about summary refs log tree commit diff
diff options
context:
space:
mode:
authorscalexm <alexandre@scalexm.fr>2018-10-24 10:29:42 +0200
committerscalexm <alexandre@scalexm.fr>2018-11-03 11:41:55 +0100
commit45be1ac0fcb7ac2d4d8e52c6543e8384e7c1a6ea (patch)
treec16319d9bf0c7614fc717ff81d6408bccddebde8
parent1f8de94f3bb1ab148f717507ec1baf78c6a7d207 (diff)
downloadrust-45be1ac0fcb7ac2d4d8e52c6543e8384e7c1a6ea.tar.gz
rust-45be1ac0fcb7ac2d4d8e52c6543e8384e7c1a6ea.zip
Remove `ReCanonical` in favor of `ReLateBound`
-rw-r--r--src/librustc/ich/impls_ty.rs3
-rw-r--r--src/librustc/infer/canonical/canonicalizer.rs16
-rw-r--r--src/librustc/infer/canonical/mod.rs2
-rw-r--r--src/librustc/infer/canonical/query_response.rs48
-rw-r--r--src/librustc/infer/canonical/substitute.rs31
-rw-r--r--src/librustc/infer/combine.rs1
-rw-r--r--src/librustc/infer/error_reporting/mod.rs2
-rw-r--r--src/librustc/infer/freshen.rs1
-rw-r--r--src/librustc/infer/lexical_region_resolve/mod.rs4
-rw-r--r--src/librustc/infer/region_constraints/mod.rs4
-rw-r--r--src/librustc/ty/flags.rs2
-rw-r--r--src/librustc/ty/fold.rs14
-rw-r--r--src/librustc/ty/mod.rs7
-rw-r--r--src/librustc/ty/sty.rs30
-rw-r--r--src/librustc/ty/subst.rs17
-rw-r--r--src/librustc/util/ppaux.rs7
-rw-r--r--src/librustc_borrowck/borrowck/check_loans.rs1
-rw-r--r--src/librustc_borrowck/borrowck/gather_loans/mod.rs1
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs3
-rw-r--r--src/librustc_typeck/astconv.rs2
-rw-r--r--src/librustc_typeck/outlives/utils.rs1
-rw-r--r--src/librustc_typeck/variance/constraints.rs1
-rw-r--r--src/librustdoc/clean/mod.rs1
23 files changed, 98 insertions, 101 deletions
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
index c950942ee34..a93e31480f3 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc/ich/impls_ty.rs
@@ -100,9 +100,6 @@ for ty::RegionKind {
             ty::ReEmpty => {
                 // No variant fields to hash for these ...
             }
-            ty::ReCanonical(c) => {
-                c.hash_stable(hcx, hasher);
-            }
             ty::ReLateBound(db, ty::BrAnon(i)) => {
                 db.hash_stable(hcx, hasher);
                 i.hash_stable(hcx, hasher);
diff --git a/src/librustc/infer/canonical/canonicalizer.rs b/src/librustc/infer/canonical/canonicalizer.rs
index a54d977a517..9c70606349b 100644
--- a/src/librustc/infer/canonical/canonicalizer.rs
+++ b/src/librustc/infer/canonical/canonicalizer.rs
@@ -331,8 +331,8 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
             | ty::ReErased => self.canonicalize_region_mode
                 .canonicalize_free_region(self, r),
 
-            ty::ReClosureBound(..) | ty::ReCanonical(_) => {
-                bug!("canonical region encountered during canonicalization")
+            ty::ReClosureBound(..) => {
+                bug!("closure bound region encountered during canonicalization")
             }
         }
     }
@@ -407,12 +407,6 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
     where
         V: TypeFoldable<'tcx> + Lift<'gcx>,
     {
-        debug_assert!(
-            !value.has_type_flags(TypeFlags::HAS_CANONICAL_VARS),
-            "canonicalizing a canonical value: {:?}",
-            value,
-        );
-
         let needs_canonical_flags = if canonicalize_region_mode.any() {
             TypeFlags::HAS_FREE_REGIONS | TypeFlags::KEEP_IN_LOCAL_TCX
         } else {
@@ -569,7 +563,11 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
         r: ty::Region<'tcx>,
     ) -> ty::Region<'tcx> {
         let var = self.canonical_var(info, r.into());
-        self.tcx().mk_region(ty::ReCanonical(var))
+        let region = ty::ReLateBound(
+            self.binder_index,
+            ty::BoundRegion::BrAnon(var.index() as u32)
+        );
+        self.tcx().mk_region(region)
     }
 
     /// Given a type variable `ty_var` of the given kind, first check
diff --git a/src/librustc/infer/canonical/mod.rs b/src/librustc/infer/canonical/mod.rs
index b6f79414725..f7eb7118f41 100644
--- a/src/librustc/infer/canonical/mod.rs
+++ b/src/librustc/infer/canonical/mod.rs
@@ -20,7 +20,7 @@
 //! - a map M (of type `CanonicalVarValues`) from those canonical
 //!   variables back to the original.
 //!
-//! We can then do queries using T2. These will give back constriants
+//! We can then do queries using T2. These will give back constraints
 //! on the canonical variables which can be translated, using the map
 //! M, into constraints in our source context. This process of
 //! translating the results back is done by the
diff --git a/src/librustc/infer/canonical/query_response.rs b/src/librustc/infer/canonical/query_response.rs
index 06e97a71ce5..4858d1d0919 100644
--- a/src/librustc/infer/canonical/query_response.rs
+++ b/src/librustc/infer/canonical/query_response.rs
@@ -308,11 +308,12 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
         // ...also include the other query region constraints from the query.
         output_query_region_constraints.extend(
             query_response.value.region_constraints.iter().filter_map(|r_c| {
-                let &ty::OutlivesPredicate(k1, r2) = r_c.skip_binder(); // reconstructed below
-                let k1 = substitute_value(self.tcx, &result_subst, &k1);
-                let r2 = substitute_value(self.tcx, &result_subst, &r2);
-                if k1 != r2.into() {
-                    Some(ty::Binder::bind(ty::OutlivesPredicate(k1, r2)))
+                let ty::OutlivesPredicate(k1, r2) = r_c.skip_binder(); // reconstructed below
+                let k1 = substitute_value(self.tcx, &result_subst, &ty::Binder::bind(*k1));
+                let r2 = substitute_value(self.tcx, &result_subst, &ty::Binder::bind(*r2));
+                if k1 != r2.map_bound(|bound| bound.into()) {
+                    let predicate = ty::OutlivesPredicate(*k1.skip_binder(), *r2.skip_binder());
+                    Some(ty::Binder::bind(predicate))
                 } else {
                     None
                 }
@@ -433,16 +434,21 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
                 UnpackedKind::Type(result_value) => {
                     // e.g., here `result_value` might be `?0` in the example above...
                     if let ty::Bound(b) = result_value.sty {
+                        // ...in which case we would set `canonical_vars[0]` to `Some(?U)`.
+
+                        // We only allow a `ty::INNERMOST` index in substitutions.
                         assert_eq!(b.index, ty::INNERMOST);
-                        // in which case we would set `canonical_vars[0]` to `Some(?U)`.
                         opt_values[b.var] = Some(*original_value);
                     }
                 }
                 UnpackedKind::Lifetime(result_value) => {
                     // e.g., here `result_value` might be `'?1` in the example above...
-                    if let &ty::RegionKind::ReCanonical(index) = result_value {
-                        // in which case we would set `canonical_vars[0]` to `Some('static)`.
-                        opt_values[index] = Some(*original_value);
+                    if let &ty::RegionKind::ReLateBound(index, br) = result_value {
+                        // ... in which case we would set `canonical_vars[0]` to `Some('static)`.
+
+                        // We only allow a `ty::INNERMOST` index in substitutions.
+                        assert_eq!(index, ty::INNERMOST);
+                        opt_values[br.as_bound_var()] = Some(*original_value);
                     }
                 }
             }
@@ -525,21 +531,23 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
                 .iter()
                 .map(move |constraint| {
                     let ty::OutlivesPredicate(k1, r2) = constraint.skip_binder(); // restored below
-                    let k1 = substitute_value(self.tcx, result_subst, k1);
-                    let r2 = substitute_value(self.tcx, result_subst, r2);
+                    let k1 = substitute_value(self.tcx, result_subst, &ty::Binder::bind(*k1));
+                    let r2 = substitute_value(self.tcx, result_subst, &ty::Binder::bind(*r2));
 
                     Obligation::new(
                         cause.clone(),
                         param_env,
-                        match k1.unpack() {
+                        match k1.skip_binder().unpack() {
                             UnpackedKind::Lifetime(r1) => ty::Predicate::RegionOutlives(
-                                ty::Binder::dummy(
-                                    ty::OutlivesPredicate(r1, r2)
-                            )),
+                                ty::Binder::bind(
+                                    ty::OutlivesPredicate(r1, r2.skip_binder())
+                                )
+                            ),
                             UnpackedKind::Type(t1) => ty::Predicate::TypeOutlives(
-                                ty::Binder::dummy(ty::OutlivesPredicate(
-                                    t1, r2
-                            )))
+                                ty::Binder::bind(
+                                    ty::OutlivesPredicate(t1, r2.skip_binder())
+                                )
+                            ),
                         }
                     )
                 })
@@ -621,11 +629,11 @@ pub fn make_query_outlives<'tcx>(
             }
             Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1),
         })
-        .map(ty::Binder::dummy) // no bound regions in the code above
+        .map(ty::Binder::dummy) // no bound vars in the code above
         .chain(
             outlives_obligations
                 .map(|(ty, r)| ty::OutlivesPredicate(ty.into(), r))
-                .map(ty::Binder::dummy), // no bound regions in the code above
+                .map(ty::Binder::dummy) // no bound vars in the code above
         )
         .collect();
 
diff --git a/src/librustc/infer/canonical/substitute.rs b/src/librustc/infer/canonical/substitute.rs
index 5b2e758d816..7839c892266 100644
--- a/src/librustc/infer/canonical/substitute.rs
+++ b/src/librustc/infer/canonical/substitute.rs
@@ -19,7 +19,7 @@
 use infer::canonical::{Canonical, CanonicalVarValues};
 use ty::fold::{TypeFoldable, TypeFolder};
 use ty::subst::UnpackedKind;
-use ty::{self, Ty, TyCtxt, TypeFlags};
+use ty::{self, Ty, TyCtxt};
 
 impl<'tcx, V> Canonical<'tcx, V> {
     /// Instantiate the wrapped value, replacing each canonical value
@@ -64,9 +64,9 @@ where
     T: TypeFoldable<'tcx>,
 {
     if var_values.var_values.is_empty() {
-        debug_assert!(!value.has_type_flags(TypeFlags::HAS_CANONICAL_VARS));
         value.clone()
-    } else if !value.has_type_flags(TypeFlags::HAS_CANONICAL_VARS) {
+    } else if !value.has_escaping_bound_vars() {
+        // There are no bound vars to substitute.
         value.clone()
     } else {
         value.fold_with(&mut CanonicalVarValuesSubst {
@@ -104,8 +104,8 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for CanonicalVarValuesSubst<'cx, 'g
                     match self.var_values.var_values[b.var].unpack() {
                         UnpackedKind::Type(ty) => ty::fold::shift_vars(
                             self.tcx,
-                            self.binder_index.index() as u32,
-                            &ty
+                            &ty,
+                            self.binder_index.index() as u32
                         ),
                         r => bug!("{:?} is a type but value is {:?}", b, r),
                     }
@@ -114,7 +114,8 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for CanonicalVarValuesSubst<'cx, 'g
                 }
             }
             _ => {
-                if !t.has_type_flags(TypeFlags::HAS_CANONICAL_VARS) {
+                if !t.has_vars_bound_at_or_above(self.binder_index) {
+                    // Nothing more to substitute.
                     t
                 } else {
                     t.super_fold_with(self)
@@ -125,10 +126,20 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for CanonicalVarValuesSubst<'cx, 'g
 
     fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
         match r {
-            ty::RegionKind::ReCanonical(c) => match self.var_values.var_values[*c].unpack() {
-                UnpackedKind::Lifetime(l) => l,
-                r => bug!("{:?} is a region but value is {:?}", c, r),
-            },
+            ty::RegionKind::ReLateBound(index, br) => {
+                if *index == self.binder_index {
+                    match self.var_values.var_values[br.as_bound_var()].unpack() {
+                        UnpackedKind::Lifetime(l) => ty::fold::shift_region(
+                            self.tcx,
+                            l,
+                            self.binder_index.index() as u32,
+                        ),
+                        r => bug!("{:?} is a region but value is {:?}", br, r),
+                    }
+                } else {
+                    r
+                }
+            }
             _ => r.super_fold_with(self),
         }
     }
diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs
index 0ee03bc4c6e..f13210926a7 100644
--- a/src/librustc/infer/combine.rs
+++ b/src/librustc/infer/combine.rs
@@ -485,7 +485,6 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
                 }
             }
 
-            ty::ReCanonical(..) |
             ty::ReClosureBound(..) => {
                 span_bug!(
                     self.span,
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index d19c495af3b..1963d366e7a 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -152,7 +152,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             }
 
             // We shouldn't encounter an error message with ReClosureBound.
-            ty::ReCanonical(..) | ty::ReClosureBound(..) => {
+            ty::ReClosureBound(..) => {
                 bug!("encountered unexpected ReClosureBound: {:?}", region,);
             }
         };
diff --git a/src/librustc/infer/freshen.rs b/src/librustc/infer/freshen.rs
index c12e64b4c2c..b53444992fa 100644
--- a/src/librustc/infer/freshen.rs
+++ b/src/librustc/infer/freshen.rs
@@ -114,7 +114,6 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
                 self.tcx().types.re_erased
             }
 
-            ty::ReCanonical(..) |
             ty::ReClosureBound(..) => {
                 bug!(
                     "encountered unexpected region: {:?}",
diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs
index 8f28e9a320d..75f503d3bcf 100644
--- a/src/librustc/infer/lexical_region_resolve/mod.rs
+++ b/src/librustc/infer/lexical_region_resolve/mod.rs
@@ -260,9 +260,7 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> {
     fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx> {
         let tcx = self.tcx();
         match (a, b) {
-            (&ty::ReCanonical(..), _)
-            | (_, &ty::ReCanonical(..))
-            | (&ty::ReClosureBound(..), _)
+            (&ty::ReClosureBound(..), _)
             | (_, &ty::ReClosureBound(..))
             | (&ReLateBound(..), _)
             | (_, &ReLateBound(..))
diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs
index c82603bf560..46b12d01829 100644
--- a/src/librustc/infer/region_constraints/mod.rs
+++ b/src/librustc/infer/region_constraints/mod.rs
@@ -833,10 +833,6 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
             ty::RePlaceholder(placeholder) => placeholder.universe,
             ty::ReClosureBound(vid) | ty::ReVar(vid) => self.var_universe(vid),
             ty::ReLateBound(..) => bug!("universe(): encountered bound region {:?}", region),
-            ty::ReCanonical(..) => bug!(
-                "region_universe(): encountered canonical region {:?}",
-                region
-            ),
         }
     }
 
diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs
index 6c1070f74e0..0764f363250 100644
--- a/src/librustc/ty/flags.rs
+++ b/src/librustc/ty/flags.rs
@@ -116,7 +116,6 @@ impl FlagComputation {
             }
 
             &ty::Bound(bound_ty) => {
-                self.add_flags(TypeFlags::HAS_CANONICAL_VARS);
                 self.add_binder(bound_ty.index);
             }
 
@@ -127,7 +126,6 @@ impl FlagComputation {
                     ty::FreshTy(_) |
                     ty::FreshIntTy(_) |
                     ty::FreshFloatTy(_) => {
-                        self.add_flags(TypeFlags::HAS_CANONICAL_VARS);
                     }
 
                     ty::TyVar(_) |
diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs
index 87ff5d2a36d..31542582f94 100644
--- a/src/librustc/ty/fold.rs
+++ b/src/librustc/ty/fold.rs
@@ -672,10 +672,14 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Shifter<'a, 'gcx, 'tcx> {
     }
 }
 
-pub fn shift_region(region: ty::RegionKind, amount: u32) -> ty::RegionKind {
+pub fn shift_region<'a, 'gcx, 'tcx>(
+    tcx: TyCtxt<'a, 'gcx, 'tcx>,
+    region: ty::Region<'tcx>,
+    amount: u32
+) -> ty::Region<'tcx> {
     match region {
-        ty::ReLateBound(debruijn, br) => {
-            ty::ReLateBound(debruijn.shifted_in(amount), br)
+        ty::ReLateBound(debruijn, br) if amount > 0 => {
+            tcx.mk_region(ty::ReLateBound(debruijn.shifted_in(amount), *br))
         }
         _ => {
             region
@@ -685,8 +689,8 @@ pub fn shift_region(region: ty::RegionKind, amount: u32) -> ty::RegionKind {
 
 pub fn shift_vars<'a, 'gcx, 'tcx, T>(
     tcx: TyCtxt<'a, 'gcx, 'tcx>,
-    amount: u32,
-    value: &T
+    value: &T,
+    amount: u32
 ) -> T where T: TypeFoldable<'tcx> {
     debug!("shift_vars(value={:?}, amount={})",
            value, amount);
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index d2ef5d0b66a..7d693cd5523 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -463,13 +463,9 @@ bitflags! {
         // Currently we can't normalize projections w/ bound regions.
         const HAS_NORMALIZABLE_PROJECTION = 1 << 12;
 
-        // Set if this includes a "canonical" type or region var --
-        // ought to be true only for the results of canonicalization.
-        const HAS_CANONICAL_VARS = 1 << 13;
-
         /// Does this have any `ReLateBound` regions? Used to check
         /// if a global bound is safe to evaluate.
-        const HAS_RE_LATE_BOUND = 1 << 14;
+        const HAS_RE_LATE_BOUND = 1 << 13;
 
         const NEEDS_SUBST        = TypeFlags::HAS_PARAMS.bits |
                                    TypeFlags::HAS_SELF.bits |
@@ -490,7 +486,6 @@ bitflags! {
                                   TypeFlags::HAS_TY_CLOSURE.bits |
                                   TypeFlags::HAS_FREE_LOCAL_NAMES.bits |
                                   TypeFlags::KEEP_IN_LOCAL_TCX.bits |
-                                  TypeFlags::HAS_CANONICAL_VARS.bits |
                                   TypeFlags::HAS_RE_LATE_BOUND.bits;
     }
 }
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 9c20d9a238e..f23bd01765a 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -77,6 +77,17 @@ impl BoundRegion {
             _ => false,
         }
     }
+
+    /// When canonicalizing, we replace unbound inference variables and free
+    /// regions with anonymous late bound regions. This method asserts that
+    /// we have an anonymous late bound region, which hence may refer to
+    /// a canonical variable.
+    pub fn as_bound_var(&self) -> BoundVar {
+        match *self {
+            BoundRegion::BrAnon(var) => BoundVar::from_u32(var),
+            _ => bug!("bound region is not anonymous"),
+        }
+    }
 }
 
 /// N.B., If you change this, you'll probably want to change the corresponding
@@ -758,11 +769,11 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> {
     }
 }
 
-/// Binder is a binder for higher-ranked lifetimes. It is part of the
+/// Binder is a binder for higher-ranked lifetimes or types. It is part of the
 /// compiler's representation for things like `for<'a> Fn(&'a isize)`
 /// (which would be represented by the type `PolyTraitRef ==
 /// Binder<TraitRef>`). Note that when we instantiate,
-/// erase, or otherwise "discharge" these bound regions, we change the
+/// erase, or otherwise "discharge" these bound vars, we change the
 /// type from `Binder<T>` to just `T` (see
 /// e.g. `liberate_late_bound_regions`).
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
@@ -770,7 +781,7 @@ pub struct Binder<T>(T);
 
 impl<T> Binder<T> {
     /// Wraps `value` in a binder, asserting that `value` does not
-    /// contain any bound regions that would be bound by the
+    /// contain any bound vars that would be bound by the
     /// binder. This is commonly used to 'inject' a value T into a
     /// different binding level.
     pub fn dummy<'tcx>(value: T) -> Binder<T>
@@ -780,9 +791,8 @@ impl<T> Binder<T> {
         Binder(value)
     }
 
-    /// Wraps `value` in a binder, binding late-bound regions (if any).
-    pub fn bind<'tcx>(value: T) -> Binder<T>
-    {
+    /// Wraps `value` in a binder, binding higher-ranked vars (if any).
+    pub fn bind<'tcx>(value: T) -> Binder<T> {
         Binder(value)
     }
 
@@ -1169,9 +1179,6 @@ pub enum RegionKind {
     /// `ClosureRegionRequirements` that are produced by MIR borrowck.
     /// See `ClosureRegionRequirements` for more details.
     ReClosureBound(RegionVid),
-
-    /// Canonicalized region, used only when preparing a trait query.
-    ReCanonical(BoundVar),
 }
 
 impl<'tcx> serialize::UseSpecializedDecodable for Region<'tcx> {}
@@ -1381,7 +1388,6 @@ impl RegionKind {
             RegionKind::ReEmpty => false,
             RegionKind::ReErased => false,
             RegionKind::ReClosureBound(..) => false,
-            RegionKind::ReCanonical(..) => false,
         }
     }
 
@@ -1468,10 +1474,6 @@ impl RegionKind {
             }
             ty::ReErased => {
             }
-            ty::ReCanonical(..) => {
-                flags = flags | TypeFlags::HAS_FREE_REGIONS;
-                flags = flags | TypeFlags::HAS_CANONICAL_VARS;
-            }
             ty::ReClosureBound(..) => {
                 flags = flags | TypeFlags::HAS_FREE_REGIONS;
             }
diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs
index 6bdbeb8f604..498d704eb9e 100644
--- a/src/librustc/ty/subst.rs
+++ b/src/librustc/ty/subst.rs
@@ -475,8 +475,8 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
     }
 
     /// It is sometimes necessary to adjust the debruijn indices during substitution. This occurs
-    /// when we are substituting a type with escaping regions into a context where we have passed
-    /// through region binders. That's quite a mouthful. Let's see an example:
+    /// when we are substituting a type with escaping bound vars into a context where we have
+    /// passed through binders. That's quite a mouthful. Let's see an example:
     ///
     /// ```
     /// type Func<A> = fn(A);
@@ -524,7 +524,7 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
             return ty;
         }
 
-        let result = ty::fold::shift_vars(self.tcx(), self.binders_passed, &ty);
+        let result = ty::fold::shift_vars(self.tcx(), &ty, self.binders_passed);
         debug!("shift_vars: shifted result = {:?}", result);
 
         result
@@ -534,7 +534,7 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
         if self.binders_passed == 0 || !region.has_escaping_bound_vars() {
             return region;
         }
-        self.tcx().mk_region(ty::fold::shift_region(*region, self.binders_passed))
+        ty::fold::shift_region(self.tcx, region, self.binders_passed)
     }
 }
 
@@ -556,7 +556,8 @@ impl CanonicalUserSubsts<'tcx> {
         self.value.substs.iter().zip(BoundVar::new(0)..).all(|(kind, cvar)| {
             match kind.unpack() {
                 UnpackedKind::Type(ty) => match ty.sty {
-                    ty::Bound(ref b) => {
+                    ty::Bound(b) => {
+                        // We only allow a `ty::INNERMOST` index in substitutions.
                         assert_eq!(b.index, ty::INNERMOST);
                         cvar == b.var
                     }
@@ -564,7 +565,11 @@ impl CanonicalUserSubsts<'tcx> {
                 },
 
                 UnpackedKind::Lifetime(r) => match r {
-                    ty::ReCanonical(cvar1) => cvar == *cvar1,
+                    ty::ReLateBound(index, br) => {
+                        // We only allow a `ty::INNERMOST` index in substitutions.
+                        assert_eq!(*index, ty::INNERMOST);
+                        cvar == br.as_bound_var()
+                    }
                     _ => false,
                 },
             }
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 222bbc67b0d..5ec4f55b142 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -790,9 +790,6 @@ define_print! {
                 ty::ReEarlyBound(ref data) => {
                     write!(f, "{}", data.name)
                 }
-                ty::ReCanonical(_) => {
-                    write!(f, "'_")
-                }
                 ty::ReLateBound(_, br) |
                 ty::ReFree(ty::FreeRegion { bound_region: br, .. }) |
                 ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
@@ -860,10 +857,6 @@ define_print! {
                     write!(f, "{:?}", vid)
                 }
 
-                ty::ReCanonical(c) => {
-                    write!(f, "'?{}", c.index())
-                }
-
                 ty::RePlaceholder(placeholder) => {
                     write!(f, "RePlaceholder({:?})", placeholder)
                 }
diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs
index 1fc9ee07a1a..a802729e3fb 100644
--- a/src/librustc_borrowck/borrowck/check_loans.rs
+++ b/src/librustc_borrowck/borrowck/check_loans.rs
@@ -426,7 +426,6 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
 
             // These cannot exist in borrowck
             RegionKind::ReVar(..) |
-            RegionKind::ReCanonical(..) |
             RegionKind::RePlaceholder(..) |
             RegionKind::ReClosureBound(..) |
             RegionKind::ReErased => span_bug!(borrow_span,
diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs
index 1f83c30a387..78a31ed668f 100644
--- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs
+++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs
@@ -363,7 +363,6 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
 
                     ty::ReStatic => self.item_ub,
 
-                    ty::ReCanonical(_) |
                     ty::ReEmpty |
                     ty::ReClosureBound(..) |
                     ty::ReLateBound(..) |
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
index 2b671891fca..99372a511a9 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
@@ -277,8 +277,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             | ty::RePlaceholder(..)
             | ty::ReEmpty
             | ty::ReErased
-            | ty::ReClosureBound(..)
-            | ty::ReCanonical(..) => None,
+            | ty::ReClosureBound(..) => None,
         }
     }
 
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index afd8c251b76..46f2c0c76a0 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1748,7 +1748,7 @@ impl<'a, 'gcx, 'tcx> Bounds<'tcx> {
             self.region_bounds.iter().map(|&(region_bound, span)| {
                 // account for the binder being introduced below; no need to shift `param_ty`
                 // because, at present at least, it can only refer to early-bound regions
-                let region_bound = tcx.mk_region(ty::fold::shift_region(*region_bound, 1));
+                let region_bound = ty::fold::shift_region(tcx, region_bound, 1);
                 let outlives = ty::OutlivesPredicate(param_ty, region_bound);
                 (ty::Binder::dummy(outlives).to_predicate(), span)
             }).chain(
diff --git a/src/librustc_typeck/outlives/utils.rs b/src/librustc_typeck/outlives/utils.rs
index 96b75c4792d..d748d93d898 100644
--- a/src/librustc_typeck/outlives/utils.rs
+++ b/src/librustc_typeck/outlives/utils.rs
@@ -167,7 +167,6 @@ fn is_free_region<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, region: Region<'_>) -> bool
         RegionKind::ReEmpty
         | RegionKind::ReErased
         | RegionKind::ReClosureBound(..)
-        | RegionKind::ReCanonical(..)
         | RegionKind::ReScope(..)
         | RegionKind::ReVar(..)
         | RegionKind::RePlaceholder(..)
diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs
index b11b034ee13..47d34c90996 100644
--- a/src/librustc_typeck/variance/constraints.rs
+++ b/src/librustc_typeck/variance/constraints.rs
@@ -427,7 +427,6 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                 // way early-bound regions do, so we skip them here.
             }
 
-            ty::ReCanonical(_) |
             ty::ReFree(..) |
             ty::ReClosureBound(..) |
             ty::ReScope(..) |
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 8391db9a37d..e71b3ccb01d 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1260,7 +1260,6 @@ impl Clean<Option<Lifetime>> for ty::RegionKind {
             ty::RePlaceholder(..) |
             ty::ReEmpty |
             ty::ReClosureBound(_) |
-            ty::ReCanonical(_) |
             ty::ReErased => None
         }
     }