about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-04-05 03:26:58 -0700
committerbors <bors@rust-lang.org>2016-04-05 03:26:58 -0700
commit7ded11a58cf2f8037a511a8d340161c59fba9913 (patch)
treeeebf20400fbe4382b01a5e9e7095f65e3ebaed69
parent7fd331e16642363c333804fe3322ae6bc0be8fbc (diff)
parent588e0f9873aeda5eb8094030ac58389b15cdc83c (diff)
downloadrust-7ded11a58cf2f8037a511a8d340161c59fba9913.tar.gz
rust-7ded11a58cf2f8037a511a8d340161c59fba9913.zip
Auto merge of #29463 - jseyfried:master, r=nikomatsakis
Remove implicit binder from `FnSpace` in `VecPerParamSpace` (fixes #20526)

This removes the implicit binder from `FnSpace` in `VecPerParamSpace` so that `Binder<T>` is the only region binder (as described in issue #20526), and refactors away `enter_region_binder` and `exit_region_binder` from `TypeFolder`.
-rw-r--r--src/librustc/ty/fold.rs38
-rw-r--r--src/librustc/ty/structural_impls.rs46
-rw-r--r--src/librustc/ty/subst.rs7
3 files changed, 23 insertions, 68 deletions
diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs
index d04f272688c..54223e16e17 100644
--- a/src/librustc/ty/fold.rs
+++ b/src/librustc/ty/fold.rs
@@ -116,21 +116,9 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
 pub trait TypeFolder<'tcx> : Sized {
     fn tcx<'a>(&'a self) -> &'a TyCtxt<'tcx>;
 
-    /// Invoked by the `super_*` routines when we enter a region
-    /// binding level (for example, when entering a function
-    /// signature). This is used by clients that want to track the
-    /// Debruijn index nesting level.
-    fn enter_region_binder(&mut self) { }
-
-    /// Invoked by the `super_*` routines when we exit a region
-    /// binding level. This is used by clients that want to
-    /// track the Debruijn index nesting level.
-    fn exit_region_binder(&mut self) { }
-
     fn fold_binder<T>(&mut self, t: &Binder<T>) -> Binder<T>
         where T : TypeFoldable<'tcx>
     {
-        // FIXME(#20526) this should replace `enter_region_binder`/`exit_region_binder`.
         t.super_fold_with(self)
     }
 
@@ -197,8 +185,9 @@ pub trait TypeFolder<'tcx> : Sized {
 }
 
 pub trait TypeVisitor<'tcx> : Sized {
-    fn enter_region_binder(&mut self) { }
-    fn exit_region_binder(&mut self) { }
+    fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> bool {
+        t.super_visit_with(self)
+    }
 
     fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
         t.super_visit_with(self)
@@ -296,12 +285,11 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx>
 {
     fn tcx(&self) -> &TyCtxt<'tcx> { self.tcx }
 
-    fn enter_region_binder(&mut self) {
+    fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T> {
         self.current_depth += 1;
-    }
-
-    fn exit_region_binder(&mut self) {
+        let t = t.super_fold_with(self);
         self.current_depth -= 1;
+        t
     }
 
     fn fold_region(&mut self, r: ty::Region) -> ty::Region {
@@ -438,12 +426,11 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionReplacer<'a, 'tcx>
 {
     fn tcx(&self) -> &TyCtxt<'tcx> { self.tcx }
 
-    fn enter_region_binder(&mut self) {
+    fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T> {
         self.current_depth += 1;
-    }
-
-    fn exit_region_binder(&mut self) {
+        let t = t.super_fold_with(self);
         self.current_depth -= 1;
+        t
     }
 
     fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
@@ -596,12 +583,11 @@ struct HasEscapingRegionsVisitor {
 }
 
 impl<'tcx> TypeVisitor<'tcx> for HasEscapingRegionsVisitor {
-    fn enter_region_binder(&mut self) {
+    fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> bool {
         self.depth += 1;
-    }
-
-    fn exit_region_binder(&mut self) {
+        let result = t.super_visit_with(self);
         self.depth -= 1;
+        result
     }
 
     fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index 6fca1eef701..82cc9e7f2e3 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -190,10 +190,7 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> {
 
 impl<'tcx, T:TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<T> {
     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        folder.enter_region_binder();
-        let result = ty::Binder(self.0.fold_with(folder));
-        folder.exit_region_binder();
-        result
+        ty::Binder(self.0.fold_with(folder))
     }
 
     fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
@@ -201,10 +198,11 @@ impl<'tcx, T:TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<T> {
     }
 
     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        visitor.enter_region_binder();
-        if self.0.visit_with(visitor) { return true }
-        visitor.exit_region_binder();
-        false
+        self.0.visit_with(visitor)
+    }
+
+    fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
+        visitor.visit_binder(self)
     }
 }
 
@@ -220,39 +218,11 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for P<[T]> {
 
 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for VecPerParamSpace<T> {
     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-
-        // Things in the Fn space take place under an additional level
-        // of region binding relative to the other spaces. This is
-        // because those entries are attached to a method, and methods
-        // always introduce a level of region binding.
-
-        let result = self.map_enumerated(|(space, index, elem)| {
-            if space == subst::FnSpace && index == 0 {
-                // enter new level when/if we reach the first thing in fn space
-                folder.enter_region_binder();
-            }
-            elem.fold_with(folder)
-        });
-        if result.len(subst::FnSpace) > 0 {
-            // if there was anything in fn space, exit the region binding level
-            folder.exit_region_binder();
-        }
-        result
+        self.map(|elem| elem.fold_with(folder))
     }
 
     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        let mut entered_region_binder = false;
-        let result = self.iter_enumerated().any(|(space, index, t)| {
-            if space == subst::FnSpace && index == 0 {
-                visitor.enter_region_binder();
-                entered_region_binder = true;
-            }
-            t.visit_with(visitor)
-        });
-        if entered_region_binder {
-            visitor.exit_region_binder();
-        }
-        result
+        self.iter().any(|elem| elem.visit_with(visitor))
     }
 }
 
diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs
index 5b05c632a97..93157f28482 100644
--- a/src/librustc/ty/subst.rs
+++ b/src/librustc/ty/subst.rs
@@ -582,12 +582,11 @@ struct SubstFolder<'a, 'tcx: 'a> {
 impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
     fn tcx(&self) -> &TyCtxt<'tcx> { self.tcx }
 
-    fn enter_region_binder(&mut self) {
+    fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T> {
         self.region_binders_passed += 1;
-    }
-
-    fn exit_region_binder(&mut self) {
+        let t = t.super_fold_with(self);
         self.region_binders_passed -= 1;
+        t
     }
 
     fn fold_region(&mut self, r: ty::Region) -> ty::Region {