use crate::ty::fold::{TypeFoldable, TypeFolder};
use crate::ty::subst::Kind;
use crate::ty::{self, BoundVar, InferConst, Lift, List, Ty, TyCtxt, TypeFlags};
+use crate::ty::flags::FlagComputation;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::indexed_vec::Idx;
}
}
- fn fold_const(&mut self, c: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
- if let ty::LazyConst::Evaluated(ct) = c {
- match ct.val {
- ConstValue::Infer(InferConst::Var(vid)) => {
- debug!("canonical: const var found with vid {:?}", vid);
- match self.infcx.unwrap().probe_const_var(vid) {
- Ok(c) => {
- debug!("(resolved to {:?})", c);
- return self.fold_const(c);
- }
+ fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
+ match ct.val {
+ ConstValue::Infer(InferConst::Var(vid)) => {
+ debug!("canonical: const var found with vid {:?}", vid);
+ match self.infcx.unwrap().probe_const_var(vid) {
+ Ok(c) => {
+ debug!("(resolved to {:?})", c);
+ return self.fold_const(c);
+ }
- // `ConstVar(vid)` is unresolved, track its universe index in the
- // canonicalized result
- Err(mut ui) => {
- if !self.infcx.unwrap().tcx.sess.opts.debugging_opts.chalk {
- // FIXME: perf problem described in #55921.
- ui = ty::UniverseIndex::ROOT;
- }
- return self.canonicalize_const_var(
- CanonicalVarInfo {
- kind: CanonicalVarKind::Const(ui),
- },
- c,
- );
+ // `ConstVar(vid)` is unresolved, track its universe index in the
+ // canonicalized result
+ Err(mut ui) => {
+ if !self.infcx.unwrap().tcx.sess.opts.debugging_opts.chalk {
+ // FIXME: perf problem described in #55921.
+ ui = ty::UniverseIndex::ROOT;
}
+ return self.canonicalize_const_var(
+ CanonicalVarInfo {
+ kind: CanonicalVarKind::Const(ui),
+ },
+ ct,
+ );
}
}
- ConstValue::Infer(InferConst::Fresh(_)) => {
- bug!("encountered a fresh const during canonicalization")
- }
- ConstValue::Infer(InferConst::Canonical(debruijn, _)) => {
- if debruijn >= self.binder_index {
- bug!("escaping bound type during canonicalization")
- } else {
- return c;
- }
- }
- ConstValue::Placeholder(placeholder) => {
- return self.canonicalize_const_var(
- CanonicalVarInfo {
- kind: CanonicalVarKind::PlaceholderConst(placeholder),
- },
- c,
- );
+ }
+ ConstValue::Infer(InferConst::Fresh(_)) => {
+ bug!("encountered a fresh const during canonicalization")
+ }
+ ConstValue::Infer(InferConst::Canonical(debruijn, _)) => {
+ if debruijn >= self.binder_index {
+ bug!("escaping bound type during canonicalization")
+ } else {
+ return ct;
}
- _ => {}
}
+ ConstValue::Placeholder(placeholder) => {
+ return self.canonicalize_const_var(
+ CanonicalVarInfo {
+ kind: CanonicalVarKind::PlaceholderConst(placeholder),
+ },
+ ct,
+ );
+ }
+ _ => {}
}
- if c.type_flags().intersects(self.needs_canonical_flags) {
- c.super_fold_with(self)
+ let flags = FlagComputation::for_const(ct);
+ if flags.intersects(self.needs_canonical_flags) {
+ ct.super_fold_with(self)
} else {
- c
+ ct
}
}
}
fn canonicalize_const_var(
&mut self,
info: CanonicalVarInfo,
- const_var: &'tcx ty::LazyConst<'tcx>
- ) -> &'tcx ty::LazyConst<'tcx> {
+ const_var: &'tcx ty::Const<'tcx>
+ ) -> &'tcx ty::Const<'tcx> {
let infcx = self.infcx.expect("encountered const-var without infcx");
let bound_to = infcx.resolve_const_var(const_var);
if bound_to != const_var {
self.fold_const(bound_to)
} else {
- let ty = match const_var {
- ty::LazyConst::Unevaluated(def_id, _) => {
- self.tcx.type_of(*def_id)
- }
- ty::LazyConst::Evaluated(ty::Const { ty, .. }) => ty,
- };
let var = self.canonical_var(info, const_var.into());
- self.tcx().mk_lazy_const(
- ty::LazyConst::Evaluated(ty::Const {
+ self.tcx().mk_const(
+ ty::Const {
val: ConstValue::Infer(InferConst::Canonical(self.binder_index, var.into())),
- ty,
- })
+ ty: const_var.ty,
+ }
)
}
}
universe: universe_mapped,
name,
};
- self.tcx.mk_lazy_const(ty::LazyConst::Evaluated(
+ self.tcx.mk_const(
ty::Const {
val: ConstValue::Placeholder(placeholder_mapped),
ty: self.tcx.types.err, // FIXME(const_generics)
}
- )).into()
+ ).into()
}
}
}
ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(i))
).into(),
UnpackedKind::Const(ct) => {
- let ty = match ct {
- ty::LazyConst::Unevaluated(def_id, _) => {
- tcx.type_of(*def_id)
- }
- ty::LazyConst::Evaluated(ty::Const { ty, .. }) => ty,
- };
- tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const {
- ty: ty,
+ tcx.mk_const(ty::Const {
+ ty: ct.ty,
val: ConstValue::Infer(
InferConst::Canonical(ty::INNERMOST, ty::BoundVar::from_u32(i))
),
- })).into()
+ }).into()
}
})
.collect()
}
}
UnpackedKind::Const(result_value) => {
- if let ty::LazyConst::Evaluated(ty::Const {
+ if let ty::Const {
val: ConstValue::Infer(InferConst::Canonical(debrujin, b)),
..
- }) = result_value {
+ } = result_value {
// ...in which case we would set `canonical_vars[0]` to `Some(const X)`.
// We only allow a `ty::INNERMOST` index in substitutions.
use crate::hir::def_id::DefId;
use crate::mir::interpret::ConstValue;
use crate::ty::{IntType, UintType};
-use crate::ty::{self, Ty, TyCtxt, InferConst, LazyConst};
+use crate::ty::{self, Ty, TyCtxt, InferConst};
use crate::ty::error::TypeError;
use crate::ty::relate::{self, Relate, RelateResult, TypeRelation};
use crate::ty::subst::SubstsRef;
pub fn super_combine_consts<R>(
&self,
relation: &mut R,
- a: &'tcx LazyConst<'tcx>,
- b: &'tcx LazyConst<'tcx>,
- ) -> RelateResult<'tcx, &'tcx LazyConst<'tcx>>
+ a: &'tcx ty::Const<'tcx>,
+ b: &'tcx ty::Const<'tcx>,
+ ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>>
where
R: TypeRelation<'infcx, 'gcx, 'tcx>,
{
let a_is_expected = relation.a_is_expected();
- if let (&ty::LazyConst::Evaluated(a_eval), &ty::LazyConst::Evaluated(b_eval)) = (a, b) {
- match (a_eval.val, b_eval.val) {
- (ConstValue::Infer(InferConst::Var(a_vid)),
- ConstValue::Infer(InferConst::Var(b_vid))) => {
- self.const_unification_table
- .borrow_mut()
- .unify_var_var(a_vid, b_vid)
- .map_err(|e| const_unification_error(a_is_expected, e))?;
- return Ok(a);
- }
-
- // All other cases of inference with other variables are errors.
- (ConstValue::Infer(InferConst::Var(_)), ConstValue::Infer(_)) |
- (ConstValue::Infer(_), ConstValue::Infer(InferConst::Var(_))) => {
- bug!("tried to combine ConstValue::Infer/ConstValue::Infer(InferConst::Var)")
- }
+ match (a.val, b.val) {
+ (ConstValue::Infer(InferConst::Var(a_vid)),
+ ConstValue::Infer(InferConst::Var(b_vid))) => {
+ self.const_unification_table
+ .borrow_mut()
+ .unify_var_var(a_vid, b_vid)
+ .map_err(|e| const_unification_error(a_is_expected, e))?;
+ return Ok(a);
+ }
- (ConstValue::Infer(InferConst::Var(vid)), _) => {
- return self.unify_const_variable(a_is_expected, vid, b);
- }
+ // All other cases of inference with other variables are errors.
+ (ConstValue::Infer(InferConst::Var(_)), ConstValue::Infer(_)) |
+ (ConstValue::Infer(_), ConstValue::Infer(InferConst::Var(_))) => {
+ bug!("tried to combine ConstValue::Infer/ConstValue::Infer(InferConst::Var)")
+ }
- (_, ConstValue::Infer(InferConst::Var(vid))) => {
- return self.unify_const_variable(!a_is_expected, vid, a);
- }
+ (ConstValue::Infer(InferConst::Var(vid)), _) => {
+ return self.unify_const_variable(a_is_expected, vid, b);
+ }
- _ => {}
+ (_, ConstValue::Infer(InferConst::Var(vid))) => {
+ return self.unify_const_variable(!a_is_expected, vid, a);
}
+
+ _ => {}
}
ty::relate::super_relate_consts(relation, a, b)
&self,
vid_is_expected: bool,
vid: ty::ConstVid<'tcx>,
- value: &'tcx LazyConst<'tcx>,
- ) -> RelateResult<'tcx, &'tcx LazyConst<'tcx>> {
+ value: &'tcx ty::Const<'tcx>,
+ ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
self.const_unification_table
.borrow_mut()
.unify_var_value(vid, ConstVarValue {
fn consts(
&mut self,
- c: &'tcx ty::LazyConst<'tcx>,
- c2: &'tcx ty::LazyConst<'tcx>
- ) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> {
+ c: &'tcx ty::Const<'tcx>,
+ c2: &'tcx ty::Const<'tcx>
+ ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
assert_eq!(c, c2); // we are abusing TypeRelation here; both LHS and RHS ought to be ==
match c {
- LazyConst::Evaluated(ty::Const {
- val: ConstValue::Infer(InferConst::Var(vid)),
- ..
- }) => {
+ ty::Const { val: ConstValue::Infer(InferConst::Var(vid)), .. } => {
let mut variable_table = self.infcx.const_unification_table.borrow_mut();
match variable_table.probe_value(*vid).val.known() {
Some(u) => {
pub fn const_unification_error<'tcx>(
a_is_expected: bool,
- (a, b): (&'tcx LazyConst<'tcx>, &'tcx LazyConst<'tcx>),
+ (a, b): (&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>),
) -> TypeError<'tcx> {
TypeError::ConstMismatch(ty::relate::expected_found_bool(a_is_expected, &a, &b))
}
fn consts(
&mut self,
- a: &'tcx ty::LazyConst<'tcx>,
- b: &'tcx ty::LazyConst<'tcx>,
- ) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> {
+ a: &'tcx ty::Const<'tcx>,
+ b: &'tcx ty::Const<'tcx>,
+ ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
if a == b { return Ok(a); }
let a = replace_if_possible(infcx.const_unification_table.borrow_mut(), a);
let b = replace_if_possible(infcx.const_unification_table.borrow_mut(), b);
let a_is_expected = self.a_is_expected();
- if let (&ty::LazyConst::Evaluated(a_eval), &ty::LazyConst::Evaluated(b_eval)) = (a, b) {
- match (a_eval.val, b_eval.val) {
- (ConstValue::Infer(InferConst::Var(a_vid)),
- ConstValue::Infer(InferConst::Var(b_vid))) => {
- infcx.const_unification_table
- .borrow_mut()
- .unify_var_var(a_vid, b_vid)
- .map_err(|e| const_unification_error(a_is_expected, e))?;
- return Ok(a);
- }
-
- (ConstValue::Infer(InferConst::Var(a_id)), _) => {
- self.fields.infcx.unify_const_variable(a_is_expected, a_id, b)?;
- return Ok(a);
- }
-
- (_, ConstValue::Infer(InferConst::Var(b_id))) => {
- self.fields.infcx.unify_const_variable(!a_is_expected, b_id, a)?;
- return Ok(a);
- }
-
- _ => {}
+
+ match (a.val, b.val) {
+ (ConstValue::Infer(InferConst::Var(a_vid)),
+ ConstValue::Infer(InferConst::Var(b_vid))) => {
+ infcx.const_unification_table
+ .borrow_mut()
+ .unify_var_var(a_vid, b_vid)
+ .map_err(|e| const_unification_error(a_is_expected, e))?;
+ return Ok(a);
+ }
+
+ (ConstValue::Infer(InferConst::Var(a_id)), _) => {
+ self.fields.infcx.unify_const_variable(a_is_expected, a_id, b)?;
+ return Ok(a);
}
+
+ (_, ConstValue::Infer(InferConst::Var(b_id))) => {
+ self.fields.infcx.unify_const_variable(!a_is_expected, b_id, a)?;
+ return Ok(a);
+ }
+
+ _ => {}
}
self.fields.infcx.super_combine_consts(self, a, b)?;
ty_freshen_count: u32,
const_freshen_count: u32,
ty_freshen_map: FxHashMap<ty::InferTy, Ty<'tcx>>,
- const_freshen_map: FxHashMap<ty::InferConst<'tcx>, &'tcx ty::LazyConst<'tcx>>,
+ const_freshen_map: FxHashMap<ty::InferConst<'tcx>, &'tcx ty::Const<'tcx>>,
}
impl<'a, 'gcx, 'tcx> TypeFreshener<'a, 'gcx, 'tcx> {
fn freshen_const<F>(
&mut self,
- opt_ct: Option<&'tcx ty::LazyConst<'tcx>>,
+ opt_ct: Option<&'tcx ty::Const<'tcx>>,
key: ty::InferConst<'tcx>,
freshener: F,
ty: Ty<'tcx>,
- ) -> &'tcx ty::LazyConst<'tcx>
+ ) -> &'tcx ty::Const<'tcx>
where
F: FnOnce(u32) -> ty::InferConst<'tcx>,
{
}
}
- fn fold_const(&mut self, ct: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
- if let ty::LazyConst::Evaluated(ty::Const{ val, ty }) = ct {
- match val {
- ConstValue::Infer(ty::InferConst::Var(v)) => {
- let opt_ct = self.infcx.const_unification_table
- .borrow_mut()
- .probe_value(*v)
- .val
- .known();
- return self.freshen_const(
- opt_ct,
- ty::InferConst::Var(*v),
- ty::InferConst::Fresh,
- ty,
+ fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
+ match ct.val {
+ ConstValue::Infer(ty::InferConst::Var(v)) => {
+ let opt_ct = self.infcx.const_unification_table
+ .borrow_mut()
+ .probe_value(v)
+ .val
+ .known();
+ return self.freshen_const(
+ opt_ct,
+ ty::InferConst::Var(v),
+ ty::InferConst::Fresh,
+ ct.ty,
+ );
+ }
+ ConstValue::Infer(ty::InferConst::Fresh(i)) => {
+ if i >= self.const_freshen_count {
+ bug!(
+ "Encountered a freshend const with id {} \
+ but our counter is only at {}",
+ i,
+ self.const_freshen_count,
);
}
- ConstValue::Infer(ty::InferConst::Fresh(i)) => {
- if *i >= self.const_freshen_count {
- bug!(
- "Encountered a freshend const with id {} \
- but our counter is only at {}",
- i,
- self.const_freshen_count,
- );
- }
- return ct;
- }
-
- ConstValue::Infer(ty::InferConst::Canonical(..)) |
- ConstValue::Placeholder(_) => {
- bug!("unexpected const {:?}", ct)
- }
+ return ct;
+ }
- ConstValue::Param(_) |
- ConstValue::Scalar(_) |
- ConstValue::Slice(..) |
- ConstValue::ByRef(..) => {}
+ ConstValue::Infer(ty::InferConst::Canonical(..)) |
+ ConstValue::Placeholder(_) => {
+ bug!("unexpected const {:?}", ct)
}
+
+ ConstValue::Param(_) |
+ ConstValue::Scalar(_) |
+ ConstValue::Slice(..) |
+ ConstValue::ByRef(..) |
+ ConstValue::Unevaluated(..) => {}
}
ct.super_fold_with(self)
r
}
- fn fold_const(&mut self, ct: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
- if let ty::LazyConst::Evaluated(ty::Const {
- val: ConstValue::Infer(ty::InferConst::Var(vid)),
- ty,
- }) = *ct {
+ fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
+ if let ty::Const { val: ConstValue::Infer(ty::InferConst::Var(vid)), ty } = *ct {
if self.const_variables.contains(&vid) {
// This variable was created during the
// fudging. Recreate it with a fresh variable
fn consts(
&mut self,
- a: &'tcx ty::LazyConst<'tcx>,
- b: &'tcx ty::LazyConst<'tcx>,
- ) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> {
+ a: &'tcx ty::Const<'tcx>,
+ b: &'tcx ty::Const<'tcx>,
+ ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
if a == b {
return Ok(a);
};
let fld_c = |bound_var: ty::BoundVar, ty| {
- self.tcx.mk_lazy_const(ty::LazyConst::Evaluated(
+ self.tcx.mk_const(
ty::Const {
val: ConstValue::Placeholder(ty::PlaceholderConst {
universe: next_universe,
}),
ty,
}
- ))
+ )
};
let (result, map) = self.tcx.replace_bound_vars(binder, fld_r, fld_t, fld_c);
fn consts(
&mut self,
- a: &'tcx ty::LazyConst<'tcx>,
- b: &'tcx ty::LazyConst<'tcx>,
- ) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> {
+ a: &'tcx ty::Const<'tcx>,
+ b: &'tcx ty::Const<'tcx>,
+ ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
if a == b {
return Ok(a);
&self,
ty: Ty<'tcx>,
origin: ConstVariableOrigin
- ) -> &'tcx ty::LazyConst<'tcx> {
+ ) -> &'tcx ty::Const<'tcx> {
self.tcx.mk_const_var(self.next_const_var_id(origin), ty)
}
ty: Ty<'tcx>,
origin: ConstVariableOrigin,
universe: ty::UniverseIndex,
- ) -> &'tcx ty::LazyConst<'tcx> {
+ ) -> &'tcx ty::Const<'tcx> {
let vid = self.const_unification_table
.borrow_mut()
.new_key(ConstVarValue {
pub fn probe_const_var(
&self,
vid: ty::ConstVid<'tcx>
- ) -> Result<&'tcx ty::LazyConst<'tcx>, ty::UniverseIndex> {
+ ) -> Result<&'tcx ty::Const<'tcx>, ty::UniverseIndex> {
use self::unify_key::ConstVariableValue;
match self.const_unification_table.borrow_mut().probe_value(vid).val {
pub fn resolve_const_var(
&self,
- ct: &'tcx ty::LazyConst<'tcx>
- ) -> &'tcx ty::LazyConst<'tcx> {
- if let ty::LazyConst::Evaluated(ty::Const {
- val: ConstValue::Infer(InferConst::Var(v)),
- ..
- }) = ct {
+ ct: &'tcx ty::Const<'tcx>
+ ) -> &'tcx ty::Const<'tcx> {
+ if let ty::Const { val: ConstValue::Infer(InferConst::Var(v)), .. } = ct {
self.const_unification_table
.borrow_mut()
.probe_value(*v)
pub fn shallow_resolve_const(
&self,
- ct: &'tcx ty::LazyConst<'tcx>
- ) -> &'tcx ty::LazyConst<'tcx> {
+ ct: &'tcx ty::Const<'tcx>
+ ) -> &'tcx ty::Const<'tcx> {
match ct {
- ty::LazyConst::Evaluated(ty::Const {
- val: ConstValue::Infer(InferConst::Var(vid)),
- ..
- }) => {
+ ty::Const { val: ConstValue::Infer(InferConst::Var(vid)), .. } => {
self.const_unification_table
.borrow_mut()
.probe_value(*vid)
fn consts(
&mut self,
- a: &'tcx ty::LazyConst<'tcx>,
- b: &'tcx ty::LazyConst<'tcx>,
- ) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> {
- if let ty::LazyConst::Evaluated(ty::Const {
- val: ConstValue::Infer(InferConst::Canonical(_, _)),
- ..
- }) = a {
+ a: &'tcx ty::Const<'tcx>,
+ b: &'tcx ty::Const<'tcx>,
+ ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
+ if let ty::Const { val: ConstValue::Infer(InferConst::Canonical(_, _)), .. } = a {
// FIXME(const_generics): I'm unsure how this branch should actually be handled,
// so this is probably not correct.
self.infcx.super_combine_consts(self, a, b)
fn consts(
&mut self,
- a: &'tcx ty::LazyConst<'tcx>,
- _: &'tcx ty::LazyConst<'tcx>,
- ) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> {
+ a: &'tcx ty::Const<'tcx>,
+ _: &'tcx ty::Const<'tcx>,
+ ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
debug!("TypeGeneralizer::consts(a={:?})", a);
- if let ty::LazyConst::Evaluated(ty::Const {
- val: ConstValue::Infer(InferConst::Canonical(_, _)),
- ..
- }) = a {
+ if let ty::Const { val: ConstValue::Infer(InferConst::Canonical(_, _)), .. } = a {
bug!(
"unexpected inference variable encountered in NLL generalization: {:?}",
a
}
}
- fn fold_const(&mut self, ct: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
+ fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
if !ct.needs_infer() {
ct // micro-optimize -- if there is nothing in this const that this fold affects...
} else {
}
}
- fn fold_const(&mut self, c: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
+ fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
if !c.needs_infer() && !ty::keep_local(&c) {
c // micro-optimize -- if there is nothing in this const that this fold affects...
// ^ we need to have the `keep_local` check to un-default
// defaulted tuples.
} else {
let c = self.infcx.shallow_resolve_const(c);
- match c {
- ty::LazyConst::Evaluated(ty::Const { val, .. }) => {
- match val {
- ConstValue::Infer(InferConst::Var(vid)) => {
- self.err = Some(FixupError::UnresolvedConst(*vid));
- return self.tcx().types.ct_err;
- }
- ConstValue::Infer(InferConst::Fresh(_)) => {
- bug!("Unexpected const in full const resolver: {:?}", c);
- }
- _ => {}
- }
+ match c.val {
+ ConstValue::Infer(InferConst::Var(vid)) => {
+ self.err = Some(FixupError::UnresolvedConst(vid));
+ return self.tcx().types.ct_err;
+ }
+ ConstValue::Infer(InferConst::Fresh(_)) => {
+ bug!("Unexpected const in full const resolver: {:?}", c);
}
_ => {}
}
fn consts(
&mut self,
- a: &'tcx ty::LazyConst<'tcx>,
- b: &'tcx ty::LazyConst<'tcx>,
- ) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> {
+ a: &'tcx ty::Const<'tcx>,
+ b: &'tcx ty::Const<'tcx>,
+ ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
if a == b { return Ok(a); }
// Consts can only be equal or unequal to each other: there's no subtyping
// relation, so we're just going to perform equating here instead.
let a_is_expected = self.a_is_expected();
- if let (&ty::LazyConst::Evaluated(a_eval), &ty::LazyConst::Evaluated(b_eval)) = (a, b) {
- match (a_eval.val, b_eval.val) {
- (ConstValue::Infer(InferConst::Var(a_vid)),
- ConstValue::Infer(InferConst::Var(b_vid))) => {
- infcx.const_unification_table
- .borrow_mut()
- .unify_var_var(a_vid, b_vid)
- .map_err(|e| const_unification_error(a_is_expected, e))?;
- return Ok(a);
- }
-
- (ConstValue::Infer(InferConst::Var(a_id)), _) => {
- self.fields.infcx.unify_const_variable(a_is_expected, a_id, b)?;
- return Ok(a);
- }
-
- (_, ConstValue::Infer(InferConst::Var(b_id))) => {
- self.fields.infcx.unify_const_variable(!a_is_expected, b_id, a)?;
- return Ok(a);
- }
-
- _ => {}
+ match (a.val, b.val) {
+ (ConstValue::Infer(InferConst::Var(a_vid)),
+ ConstValue::Infer(InferConst::Var(b_vid))) => {
+ infcx.const_unification_table
+ .borrow_mut()
+ .unify_var_var(a_vid, b_vid)
+ .map_err(|e| const_unification_error(a_is_expected, e))?;
+ return Ok(a);
}
+
+ (ConstValue::Infer(InferConst::Var(a_id)), _) => {
+ self.fields.infcx.unify_const_variable(a_is_expected, a_id, b)?;
+ return Ok(a);
+ }
+
+ (_, ConstValue::Infer(InferConst::Var(b_id))) => {
+ self.fields.infcx.unify_const_variable(!a_is_expected, b_id, a)?;
+ return Ok(a);
+ }
+
+ _ => {}
}
self.fields.infcx.super_combine_consts(self, a, b)?;
#[derive(Copy, Clone, Debug)]
pub enum ConstVariableValue<'tcx> {
- Known { value: &'tcx ty::LazyConst<'tcx> },
+ Known { value: &'tcx ty::Const<'tcx> },
Unknown { universe: ty::UniverseIndex },
}
impl<'tcx> ConstVariableValue<'tcx> {
/// If this value is known, returns the const it is known to be.
/// Otherwise, `None`.
- pub fn known(&self) -> Option<&'tcx ty::LazyConst<'tcx>> {
+ pub fn known(&self) -> Option<&'tcx ty::Const<'tcx>> {
match *self {
ConstVariableValue::Unknown { .. } => None,
ConstVariableValue::Known { value } => Some(value),
}
impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
- type Error = (&'tcx ty::LazyConst<'tcx>, &'tcx ty::LazyConst<'tcx>);
+ type Error = (&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>);
fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
let val = match (value1.val, value2.val) {
ConstVariableValue::Known { value: value1 },
ConstVariableValue::Known { value: value2 }
) => {
- match <&'tcx ty::LazyConst<'tcx>>::unify_values(&value1, &value2) {
+ match <&'tcx ty::Const<'tcx>>::unify_values(&value1, &value2) {
Ok(value) => Ok(ConstVariableValue::Known { value }),
Err(err) => Err(err),
}
}
}
-impl<'tcx> EqUnifyValue for &'tcx ty::LazyConst<'tcx> {}
+impl<'tcx> EqUnifyValue for &'tcx ty::Const<'tcx> {}
pub fn replace_if_possible(
mut table: RefMut<'_, UnificationTable<InPlace<ty::ConstVid<'tcx>>>>,
- c: &'tcx ty::LazyConst<'tcx>
-) -> &'tcx ty::LazyConst<'tcx> {
- if let ty::LazyConst::Evaluated(ty::Const {
- val: ConstValue::Infer(InferConst::Var(vid)),
- ..
- }) = c {
+ c: &'tcx ty::Const<'tcx>
+) -> &'tcx ty::Const<'tcx> {
+ if let ty::Const { val: ConstValue::Infer(InferConst::Var(vid)), .. } = c {
match table.probe_value(*vid).val.known() {
Some(c) => c,
None => c,
fn consts(
&mut self,
- a: &'tcx ty::LazyConst<'tcx>,
- b: &'tcx ty::LazyConst<'tcx>,
- ) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> {
+ a: &'tcx ty::Const<'tcx>,
+ b: &'tcx ty::Const<'tcx>,
+ ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
if a == b {
return Ok(a);
}
- if let (&ty::LazyConst::Evaluated(a_eval), &ty::LazyConst::Evaluated(b_eval)) = (a, b) {
- match (a_eval.val, b_eval.val) {
- (_, ConstValue::Infer(InferConst::Fresh(_))) => {
- return Ok(a);
- }
-
- (ConstValue::Infer(_), _) | (_, ConstValue::Infer(_)) => {
- return Err(TypeError::ConstMismatch(relate::expected_found(self, &a, &b)));
- }
+ match (a.val, b.val) {
+ (_, ConstValue::Infer(InferConst::Fresh(_))) => {
+ return Ok(a);
+ }
- _ => {}
+ (ConstValue::Infer(_), _) | (_, ConstValue::Infer(_)) => {
+ return Err(TypeError::ConstMismatch(relate::expected_found(self, &a, &b)));
}
+
+ _ => {}
}
relate::super_relate_consts(self, a, b)
pub re_static: Region<'tcx>,
pub re_erased: Region<'tcx>,
- pub ct_err: &'tcx LazyConst<'tcx>,
+ pub ct_err: &'tcx Const<'tcx>,
}
pub struct LocalTableInContext<'a, V: 'a> {
self,
ic: InferConst<'tcx>,
ty: Ty<'tcx>,
- ) -> &'tcx LazyConst<'tcx> {
- self.mk_lazy_const(LazyConst::Evaluated(ty::Const {
+ ) -> &'tcx ty::Const<'tcx> {
+ self.mk_const(ty::Const {
val: ConstValue::Infer(ic),
ty,
- }))
+ })
}
#[inline]
ProjectionBoundsLength(ExpectedFound<usize>),
ExistentialMismatch(ExpectedFound<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>),
- ConstMismatch(ExpectedFound<&'tcx ty::LazyConst<'tcx>>),
+ ConstMismatch(ExpectedFound<&'tcx ty::Const<'tcx>>),
}
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)]
pub struct BottomUpFolder<'a, 'gcx: 'a+'tcx, 'tcx: 'a, F, G, H>
where F: FnMut(Ty<'tcx>) -> Ty<'tcx>,
G: FnMut(ty::Region<'tcx>) -> ty::Region<'tcx>,
- H: FnMut(&'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx>,
+ H: FnMut(&'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx>,
{
pub tcx: TyCtxt<'a, 'gcx, 'tcx>,
pub ty_op: F,
impl<'a, 'gcx, 'tcx, F, G, H> TypeFolder<'gcx, 'tcx> for BottomUpFolder<'a, 'gcx, 'tcx, F, G, H>
where F: FnMut(Ty<'tcx>) -> Ty<'tcx>,
G: FnMut(ty::Region<'tcx>) -> ty::Region<'tcx>,
- H: FnMut(&'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx>,
+ H: FnMut(&'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx>,
{
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx }
(self.lt_op)(r)
}
- fn fold_const(&mut self, ct: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
+ fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
let ct = ct.super_fold_with(self);
(self.ct_op)(ct)
}
fld_r: &'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a),
fld_t: &'a mut (dyn FnMut(ty::BoundTy) -> Ty<'tcx> + 'a),
- fld_c: &'a mut (dyn FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::LazyConst<'tcx> + 'a),
+ fld_c: &'a mut (dyn FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx> + 'a),
}
impl<'a, 'gcx, 'tcx> BoundVarReplacer<'a, 'gcx, 'tcx> {
) -> Self
where F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
G: FnMut(ty::BoundTy) -> Ty<'tcx>,
- H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::LazyConst<'tcx>,
+ H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx>,
{
BoundVarReplacer {
tcx,
}
}
- fn fold_const(&mut self, ct: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
- if let ty::LazyConst::Evaluated(ty::Const {
+ fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
+ if let ty::Const {
val: ConstValue::Infer(ty::InferConst::Canonical(debruijn, bound_const)),
ty,
- }) = *ct {
+ } = *ct {
if debruijn == self.current_index {
let fld_c = &mut self.fld_c;
let ct = fld_c(bound_const, ty);
) -> (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)
where F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
G: FnMut(ty::BoundTy) -> Ty<'tcx>,
- H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::LazyConst<'tcx>,
+ H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx>,
T: TypeFoldable<'tcx>,
{
use rustc_data_structures::fx::FxHashMap;
) -> (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)
where F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
G: FnMut(ty::BoundTy) -> Ty<'tcx>,
- H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::LazyConst<'tcx>,
+ H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx>,
T: TypeFoldable<'tcx>
{
self.replace_escaping_bound_vars(value.skip_binder(), fld_r, fld_t, fld_c)
}
}
- fn fold_const(&mut self, ct: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
- if let ty::LazyConst::Evaluated(ty::Const {
+ fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
+ if let ty::Const {
val: ConstValue::Infer(ty::InferConst::Canonical(debruijn, bound_const)),
ty,
- }) = *ct {
+ } = *ct {
if self.amount == 0 || debruijn < self.current_index {
ct
} else {
r.bound_at_or_above_binder(self.outer_index)
}
- fn visit_const(&mut self, ct: &'tcx ty::LazyConst<'tcx>) -> bool {
- if let ty::LazyConst::Evaluated(ty::Const {
+ fn visit_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> bool {
+ if let ty::Const {
val: ConstValue::Infer(ty::InferConst::Canonical(debruijn, _)),
..
- }) = *ct {
+ } = *ct {
debruijn >= self.outer_index
} else {
false
pub mod error;
mod erase_regions;
pub mod fast_reject;
+pub mod flags;
pub mod fold;
pub mod inhabitedness;
pub mod layout;
pub mod util;
mod context;
-mod flags;
mod instance;
mod structural_impls;
mod sty;
// in order to place the projections inside the `<...>`.
if !resugared {
// Use a type that can't appear in defaults of type parameters.
- let dummy_self = self.tcx().mk_infer(ty::FreshTy(0));
+ let dummy_self = self.tcx().mk_ty_infer(ty::FreshTy(0));
let principal = principal.with_self_ty(self.tcx(), dummy_self);
let args = self.generic_args_to_print(
ty::ExistentialTraitRef<'tcx> {
// Use a type that can't appear in defaults of type parameters.
- let dummy_self = cx.tcx().mk_infer(ty::FreshTy(0));
+ let dummy_self = cx.tcx().mk_ty_infer(ty::FreshTy(0));
let trait_ref = self.with_self_ty(cx.tcx(), dummy_self);
p!(print(trait_ref))
}
use crate::hir::def_id::DefId;
use crate::ty::subst::{Kind, UnpackedKind, SubstsRef};
use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
-use crate::ty::error::{ExpectedFound, TypeError, ConstError};
+use crate::ty::error::{ExpectedFound, TypeError};
use crate::mir::interpret::{GlobalId, ConstValue, Scalar};
use crate::util::common::ErrorReported;
use syntax_pos::DUMMY_SP;
fn consts(
&mut self,
- a: &'tcx ty::LazyConst<'tcx>,
- b: &'tcx ty::LazyConst<'tcx>
- ) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>>;
+ a: &'tcx ty::Const<'tcx>,
+ b: &'tcx ty::Const<'tcx>
+ ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>>;
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
-> RelateResult<'tcx, ty::Binder<T>>
ast::Mutability::MutMutable => ty::Invariant,
};
let ty = relation.relate_with_variance(variance, &a.ty, &b.ty)?;
- Ok(ty::TypeAndMut {ty: ty, mutbl: mutbl})
+ Ok(ty::TypeAndMut { ty, mutbl })
}
}
}
/// it.
pub fn super_relate_consts<'a, 'gcx, 'tcx, R>(
relation: &mut R,
- a: &'tcx ty::LazyConst<'tcx>,
- b: &'tcx ty::LazyConst<'tcx>
-) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>>
+ a: &'tcx ty::Const<'tcx>,
+ b: &'tcx ty::Const<'tcx>
+) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>>
where
R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
{
+ // Only consts whose types are equal should be compared.
+ assert_eq!(a.ty, b.ty);
+
let tcx = relation.tcx();
- match (a, b) {
- (ty::LazyConst::Evaluated(a_eval), ty::LazyConst::Evaluated(b_eval)) => {
- // Only consts whose types are equal should be compared.
- assert_eq!(a_eval.ty, b_eval.ty);
-
- // Currently, the values that can be unified are those that
- // implement both `PartialEq` and `Eq`, corresponding to
- // `structural_match` types.
- // FIXME(const_generics): check for `structural_match` synthetic attribute.
- match (a_eval.val, b_eval.val) {
- (ConstValue::Infer(_), _) | (_, ConstValue::Infer(_)) => {
- // The caller should handle these cases!
- bug!("var types encountered in super_relate_consts: {:?} {:?}", a, b)
- }
- (ConstValue::Param(a_p), ConstValue::Param(b_p)) if a_p.index == b_p.index => {
- Ok(a)
- }
- (ConstValue::Placeholder(p1), ConstValue::Placeholder(p2)) if p1 == p2 => {
- Ok(a)
- }
- (ConstValue::Scalar(Scalar::Bits { .. }), _) if a == b => {
- Ok(a)
- }
- (ConstValue::ByRef(..), _) => {
- bug!(
- "non-Scalar ConstValue encountered in super_relate_consts {:?} {:?}",
- a,
- b,
- );
- }
- _ => {
- Err(TypeError::ConstMismatch(expected_found(relation, &a, &b)))
- }
- }
+ // Currently, the values that can be unified are those that
+ // implement both `PartialEq` and `Eq`, corresponding to
+ // `structural_match` types.
+ // FIXME(const_generics): check for `structural_match` synthetic attribute.
+ match (a.val, b.val) {
+ (ConstValue::Infer(_), _) | (_, ConstValue::Infer(_)) => {
+ // The caller should handle these cases!
+ bug!("var types encountered in super_relate_consts: {:?} {:?}", a, b)
}
- // FIXME(const_generics): this is probably wrong (regarding TyProjection)
- (
- ty::LazyConst::Unevaluated(a_def_id, a_substs),
- ty::LazyConst::Unevaluated(b_def_id, b_substs),
- ) if a_def_id == b_def_id => {
- let substs =
- relation.relate_with_variance(ty::Variance::Invariant, a_substs, b_substs)?;
- Ok(tcx.mk_lazy_const(ty::LazyConst::Unevaluated(*a_def_id, substs)))
+ (ConstValue::Param(a_p), ConstValue::Param(b_p)) if a_p.index == b_p.index => {
+ Ok(a)
+ }
+ (ConstValue::Placeholder(p1), ConstValue::Placeholder(p2)) if p1 == p2 => {
+ Ok(a)
+ }
+ (ConstValue::Scalar(Scalar::Bits { .. }), _) if a == b => {
+ Ok(a)
}
- _ => {
+ (ConstValue::ByRef(..), _) => {
+ bug!(
+ "non-Scalar ConstValue encountered in super_relate_consts {:?} {:?}",
+ a,
+ b,
+ );
+ }
+
+ // FIXME(const_generics): this is wrong, as it is a projection
+ (ConstValue::Unevaluated(a_def_id, a_substs),
+ ConstValue::Unevaluated(b_def_id, b_substs)) if a_def_id == b_def_id => {
+ let substs =
+ relation.relate_with_variance(ty::Variance::Invariant, &a_substs, &b_substs)?;
+ Ok(tcx.mk_const(ty::Const {
+ val: ConstValue::Unevaluated(a_def_id, &substs),
+ ty: a.ty,
+ })
+ }
+
+ _ => {
Err(TypeError::ConstMismatch(expected_found(relation, &a, &b)))
}
}
}
}
-impl<'tcx> Relate<'tcx> for &'tcx ty::LazyConst<'tcx> {
+impl<'tcx> Relate<'tcx> for &'tcx ty::Const<'tcx> {
fn relate<'a, 'gcx, R>(relation: &mut R,
- a: &&'tcx ty::LazyConst<'tcx>,
- b: &&'tcx ty::LazyConst<'tcx>)
- -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>>
+ a: &&'tcx ty::Const<'tcx>,
+ b: &&'tcx ty::Const<'tcx>)
+ -> RelateResult<'tcx, &'tcx ty::Const<'tcx>>
where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
{
relation.consts(*a, *b)
fn consts(
&mut self,
- a: &'tcx ty::LazyConst<'tcx>,
- b: &'tcx ty::LazyConst<'tcx>,
- ) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> {
- if let ty::LazyConst::Evaluated(ty::Const {
+ a: &'tcx ty::Const<'tcx>,
+ b: &'tcx ty::Const<'tcx>,
+ ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
+ if let ty::Const {
val: ConstValue::Infer(InferConst::Canonical(debruijn, bound_ct)),
..
- }) = a {
+ } = a {
if *debruijn == self.binder_index {
self.unify_free_answer_var(*bound_ct, b.into())?;
return Ok(b);
match (a, b) {
(
- ty::LazyConst::Evaluated(ty::Const {
+ ty::Const {
val: ConstValue::Infer(InferConst::Canonical(a_debruijn, a_bound)),
..
- }),
- ty::LazyConst::Evaluated(ty::Const {
+ },
+ ty::Const {
val: ConstValue::Infer(InferConst::Canonical(b_debruijn, b_bound)),
..
- }),
+ },
) => {
assert_eq!(a_debruijn, b_debruijn);
assert_eq!(a_bound, b_bound);
use rustc::ty::adjustment::{Adjust, Adjustment, PointerCast};
use rustc::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder};
use rustc::ty::subst::UnpackedKind;
-use rustc::ty::{self, Ty, TyCtxt, Const, LazyConst};
+use rustc::ty::{self, Ty, TyCtxt, Const};
use rustc::mir::interpret::ConstValue;
use rustc::util::nodemap::DefIdSet;
use rustc_data_structures::sync::Lrc;
},
ct_op: |ct| {
trace!("checking const {:?}", ct);
- // find a const parameter
- if let LazyConst::Evaluated(Const { ty, val }) = ct {
- if let ConstValue::Param(..) = val {
- // look it up in the substitution list
- assert_eq!(opaque_defn.substs.len(), generics.params.len());
- for (subst, param) in opaque_defn.substs.iter()
- .zip(&generics.params) {
- if let UnpackedKind::Const(subst) = subst.unpack() {
- if subst == ct {
- // found it in the substitution list, replace with the
- // parameter from the existential type
- return self.tcx()
- .global_tcx()
- .mk_const_param(param.index, param.name, ty);
- }
+ // Find a const parameter
+ if let ConstValue::Param(..) = ct.val {
+ // look it up in the substitution list
+ assert_eq!(opaque_defn.substs.len(), generics.params.len());
+ for (subst, param) in opaque_defn.substs.iter()
+ .zip(&generics.params) {
+ if let UnpackedKind::Const(subst) = subst.unpack() {
+ if subst == ct {
+ // found it in the substitution list, replace with the
+ // parameter from the existential type
+ return self.tcx()
+ .global_tcx()
+ .mk_const_param(param.index, param.name, ty);
}
}
- self.tcx()
- .sess
- .struct_span_err(
- span,
- &format!(
- "const parameter `{}` is part of concrete type but not \
- used in parameter list for existential type",
- ct,
- ),
- )
- .emit();
- return self.tcx().types.ct_err;
}
+ self.tcx()
+ .sess
+ .struct_span_err(
+ span,
+ &format!(
+ "const parameter `{}` is part of concrete type but not \
+ used in parameter list for existential type",
+ ct,
+ ),
+ )
+ .emit();
+ return self.tcx().types.ct_err;
}
ct
}