diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 919d5749bbff0..642eb11006649 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -915,7 +915,7 @@ impl_stable_hash_for!(enum ty::InferTy { FreshTy(a), FreshIntTy(a), FreshFloatTy(a), - CanonicalTy(a), + BoundTy(a), }); impl<'a, 'gcx> HashStable> diff --git a/src/librustc/infer/canonical/canonicalizer.rs b/src/librustc/infer/canonical/canonicalizer.rs index 46e32f2374cc5..2b085a3407ccc 100644 --- a/src/librustc/infer/canonical/canonicalizer.rs +++ b/src/librustc/infer/canonical/canonicalizer.rs @@ -23,7 +23,7 @@ use infer::InferCtxt; use std::sync::atomic::Ordering; use ty::fold::{TypeFoldable, TypeFolder}; use ty::subst::Kind; -use ty::{self, BoundTyIndex, Lift, List, Ty, TyCtxt, TypeFlags}; +use ty::{self, BoundTy, BoundTyIndex, Lift, List, Ty, TyCtxt, TypeFlags}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_vec::Idx; @@ -283,7 +283,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx> bug!("encountered a fresh type during canonicalization") } - ty::Infer(ty::CanonicalTy(_)) => { + ty::Infer(ty::BoundTy(_)) => { bug!("encountered a canonical type during canonicalization") } @@ -393,7 +393,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> { /// or returns an existing variable if `kind` has already been /// seen. `kind` is expected to be an unbound variable (or /// potentially a free region). - fn canonical_var(&mut self, info: CanonicalVarInfo, kind: Kind<'tcx>) -> BoundTyIndex { + fn canonical_var(&mut self, info: CanonicalVarInfo, kind: Kind<'tcx>) -> BoundTy { let Canonicalizer { variables, query_state, @@ -408,7 +408,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> { // avoid allocations in those cases. We also don't use `indices` to // determine if a kind has been seen before until the limit of 8 has // been exceeded, to also avoid allocations for `indices`. - if !var_values.spilled() { + let var = if !var_values.spilled() { // `var_values` is stack-allocated. `indices` isn't used yet. Do a // direct linear search of `var_values`. if let Some(idx) = var_values.iter().position(|&k| k == kind) { @@ -442,6 +442,11 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> { assert_eq!(variables.len(), var_values.len()); BoundTyIndex::new(variables.len() - 1) }) + }; + + BoundTy { + level: ty::INNERMOST, + var, } } @@ -449,8 +454,9 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> { let info = CanonicalVarInfo { kind: CanonicalVarKind::Region, }; - let cvar = self.canonical_var(info, r.into()); - self.tcx().mk_region(ty::ReCanonical(cvar)) + let b = self.canonical_var(info, r.into()); + debug_assert_eq!(ty::INNERMOST, b.level); + self.tcx().mk_region(ty::ReCanonical(b.var)) } /// Given a type variable `ty_var` of the given kind, first check @@ -466,8 +472,9 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> { let info = CanonicalVarInfo { kind: CanonicalVarKind::Ty(ty_kind), }; - let cvar = self.canonical_var(info, ty_var.into()); - self.tcx().mk_infer(ty::InferTy::CanonicalTy(cvar)) + let b = self.canonical_var(info, ty_var.into()); + debug_assert_eq!(ty::INNERMOST, b.level); + self.tcx().mk_infer(ty::InferTy::BoundTy(b)) } } } diff --git a/src/librustc/infer/canonical/query_response.rs b/src/librustc/infer/canonical/query_response.rs index 3d4dc36a9be53..38788186eb071 100644 --- a/src/librustc/infer/canonical/query_response.rs +++ b/src/librustc/infer/canonical/query_response.rs @@ -417,9 +417,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { match result_value.unpack() { UnpackedKind::Type(result_value) => { // e.g., here `result_value` might be `?0` in the example above... - if let ty::Infer(ty::InferTy::CanonicalTy(index)) = result_value.sty { + if let ty::Infer(ty::InferTy::BoundTy(b)) = result_value.sty { // in which case we would set `canonical_vars[0]` to `Some(?U)`. - opt_values[index] = Some(*original_value); + opt_values[b.var] = Some(*original_value); } } UnpackedKind::Lifetime(result_value) => { diff --git a/src/librustc/infer/canonical/substitute.rs b/src/librustc/infer/canonical/substitute.rs index f3fe01d5fd121..03441c3dee35e 100644 --- a/src/librustc/infer/canonical/substitute.rs +++ b/src/librustc/infer/canonical/substitute.rs @@ -85,10 +85,11 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for CanonicalVarValuesSubst<'cx, 'g fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { match t.sty { - ty::Infer(ty::InferTy::CanonicalTy(c)) => { - match self.var_values.var_values[c].unpack() { + ty::Infer(ty::InferTy::BoundTy(b)) => { + debug_assert_eq!(ty::INNERMOST, b.level); + match self.var_values.var_values[b.var].unpack() { UnpackedKind::Type(ty) => ty, - r => bug!("{:?} is a type but value is {:?}", c, r), + r => bug!("{:?} is a type but value is {:?}", b, r), } } _ => { diff --git a/src/librustc/infer/freshen.rs b/src/librustc/infer/freshen.rs index c7785d8317173..1647f259db9fb 100644 --- a/src/librustc/infer/freshen.rs +++ b/src/librustc/infer/freshen.rs @@ -171,7 +171,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> { t } - ty::Infer(ty::CanonicalTy(..)) => + ty::Infer(ty::BoundTy(..)) => bug!("encountered canonical ty during freshening"), ty::Generator(..) | diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 39c623de677d3..49f3717935493 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -2421,7 +2421,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { ty::Infer(ty::TyVar(_)) => Ambiguous, ty::UnnormalizedProjection(..) - | ty::Infer(ty::CanonicalTy(_)) + | ty::Infer(ty::BoundTy(_)) | ty::Infer(ty::FreshTy(_)) | ty::Infer(ty::FreshIntTy(_)) | ty::Infer(ty::FreshFloatTy(_)) => { @@ -2506,7 +2506,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { } ty::UnnormalizedProjection(..) - | ty::Infer(ty::CanonicalTy(_)) + | ty::Infer(ty::BoundTy(_)) | ty::Infer(ty::FreshTy(_)) | ty::Infer(ty::FreshIntTy(_)) | ty::Infer(ty::FreshFloatTy(_)) => { @@ -2549,7 +2549,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { | ty::Param(..) | ty::Foreign(..) | ty::Projection(..) - | ty::Infer(ty::CanonicalTy(_)) + | ty::Infer(ty::BoundTy(_)) | ty::Infer(ty::TyVar(_)) | ty::Infer(ty::FreshTy(_)) | ty::Infer(ty::FreshIntTy(_)) diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index d886d5ed20413..ed6e372fe7637 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -217,7 +217,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { ty::Infer(ty::TyVar(_)) => "inferred type".into(), ty::Infer(ty::IntVar(_)) => "integral variable".into(), ty::Infer(ty::FloatVar(_)) => "floating-point variable".into(), - ty::Infer(ty::CanonicalTy(_)) | + ty::Infer(ty::BoundTy(_)) | ty::Infer(ty::FreshTy(_)) => "fresh type".into(), ty::Infer(ty::FreshIntTy(_)) => "fresh integral type".into(), ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(), diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index 10a90dfc8a8cf..a7b21688fbeb3 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -122,7 +122,7 @@ impl FlagComputation { ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) | - ty::CanonicalTy(_) => { + ty::BoundTy(_) => { self.add_flags(TypeFlags::HAS_CANONICAL_VARS); } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 122067517cafc..5602ce479c8dc 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -63,7 +63,7 @@ use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult, use hir; -pub use self::sty::{Binder, BoundTyIndex, DebruijnIndex, INNERMOST}; +pub use self::sty::{Binder, BoundTy, BoundTyIndex, DebruijnIndex, INNERMOST}; pub use self::sty::{FnSig, GenSig, PolyFnSig, PolyGenSig}; pub use self::sty::{InferTy, ParamTy, ProjectionTy, ExistentialPredicate}; pub use self::sty::{ClosureSubsts, GeneratorSubsts, UpvarSubsts, TypeAndMut}; diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index f22c2ad296574..8289158387015 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1217,14 +1217,22 @@ pub enum InferTy { FreshIntTy(u32), FreshFloatTy(u32), - /// Canonicalized type variable, used only when preparing a trait query. - CanonicalTy(BoundTyIndex), + /// Bound type variable, used only when preparing a trait query. + BoundTy(BoundTy), } newtype_index! { pub struct BoundTyIndex { .. } } +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)] +pub struct BoundTy { + pub level: DebruijnIndex, + pub var: BoundTyIndex, +} + +impl_stable_hash_for!(struct BoundTy { level, var }); + /// A `ProjectionPredicate` for an `ExistentialTraitRef`. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)] pub struct ExistentialProjection<'tcx> { @@ -1919,7 +1927,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { ty::Infer(ty::TyVar(_)) => false, - ty::Infer(ty::CanonicalTy(_)) | + ty::Infer(ty::BoundTy(_)) | ty::Infer(ty::FreshTy(_)) | ty::Infer(ty::FreshIntTy(_)) | ty::Infer(ty::FreshFloatTy(_)) => diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index f578518145cc6..02b5d36ecce6e 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -556,7 +556,7 @@ impl CanonicalUserSubsts<'tcx> { self.value.substs.iter().zip(BoundTyIndex::new(0)..).all(|(kind, cvar)| { match kind.unpack() { UnpackedKind::Type(ty) => match ty.sty { - ty::Infer(ty::CanonicalTy(cvar1)) => cvar == cvar1, + ty::Infer(ty::BoundTy(ref b)) => cvar == b.var, _ => false, }, diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index bfa2203cc04b2..709b844526529 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -984,7 +984,7 @@ define_print! { ty::TyVar(_) => write!(f, "_"), ty::IntVar(_) => write!(f, "{}", "{integer}"), ty::FloatVar(_) => write!(f, "{}", "{float}"), - ty::CanonicalTy(_) => write!(f, "_"), + ty::BoundTy(_) => write!(f, "_"), ty::FreshTy(v) => write!(f, "FreshTy({})", v), ty::FreshIntTy(v) => write!(f, "FreshIntTy({})", v), ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v) @@ -996,7 +996,7 @@ define_print! { ty::TyVar(ref v) => write!(f, "{:?}", v), ty::IntVar(ref v) => write!(f, "{:?}", v), ty::FloatVar(ref v) => write!(f, "{:?}", v), - ty::CanonicalTy(v) => write!(f, "?{:?}", v.index()), + ty::BoundTy(v) => write!(f, "?{:?}", v.var.index()), ty::FreshTy(v) => write!(f, "FreshTy({:?})", v), ty::FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v), ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v)