about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2015-01-07 14:05:32 -0500
committerNiko Matsakis <niko@alum.mit.edu>2015-01-07 14:07:58 -0500
commitaec62af7427083ac7f6dcb2fd484876199147fdc (patch)
treef8662116d1ccac393c02aa29201341e6f86e091a /src
parentcf136cd3507a5e929cff8d03179c0f6d96bdb687 (diff)
Solve rather subtle bug in `replace_late_bound_regions` -- we were passing the debruijn index in so that callees could construct late-bound regions at the right depth, but then the result was cached. When the cached result was used, it might be at the wrong depth. So now we don't pass the result in and instead simply adjust the depth to match the current nesting level as we go.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/infer/higher_ranked/mod.rs2
-rw-r--r--src/librustc/middle/infer/mod.rs2
-rw-r--r--src/librustc/middle/ty.rs27
-rw-r--r--src/librustc/util/ppaux.rs4
4 files changed, 23 insertions, 12 deletions
diff --git a/src/librustc/middle/infer/higher_ranked/mod.rs b/src/librustc/middle/infer/higher_ranked/mod.rs
index 073052dd368..40f32a51e22 100644
--- a/src/librustc/middle/infer/higher_ranked/mod.rs
+++ b/src/librustc/middle/infer/higher_ranked/mod.rs
@@ -468,7 +468,7 @@ pub fn skolemize_late_bound_regions<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
      * when higher-ranked things are involved. See `doc.rs` for more details.
      */
 
-    let (result, map) = ty::replace_late_bound_regions(infcx.tcx, binder, |br, _| {
+    let (result, map) = ty::replace_late_bound_regions(infcx.tcx, binder, |br| {
         infcx.region_vars.new_skolemized(br, &snapshot.region_vars_snapshot)
     });
 
diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs
index 3f18af3d768..c1f0c10e11f 100644
--- a/src/librustc/middle/infer/mod.rs
+++ b/src/librustc/middle/infer/mod.rs
@@ -1056,7 +1056,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         ty::replace_late_bound_regions(
             self.tcx,
             value,
-            |br, _| self.next_region_var(LateBoundRegion(span, br, lbrct)))
+            |br| self.next_region_var(LateBoundRegion(span, br, lbrct)))
     }
 
     /// See `verify_generic_bound` method in `region_inference`
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 9b9a58178cc..2c9ff35364b 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -6672,7 +6672,7 @@ pub fn liberate_late_bound_regions<'tcx, T>(
 {
     replace_late_bound_regions(
         tcx, value,
-        |br, _| ty::ReFree(ty::FreeRegion{scope: scope, bound_region: br})).0
+        |br| ty::ReFree(ty::FreeRegion{scope: scope, bound_region: br})).0
 }
 
 pub fn count_late_bound_regions<'tcx, T>(
@@ -6681,7 +6681,7 @@ pub fn count_late_bound_regions<'tcx, T>(
     -> uint
     where T : TypeFoldable<'tcx> + Repr<'tcx>
 {
-    let (_, skol_map) = replace_late_bound_regions(tcx, value, |_, _| ty::ReStatic);
+    let (_, skol_map) = replace_late_bound_regions(tcx, value, |_| ty::ReStatic);
     skol_map.len()
 }
 
@@ -6712,7 +6712,7 @@ pub fn erase_late_bound_regions<'tcx, T>(
     -> T
     where T : TypeFoldable<'tcx> + Repr<'tcx>
 {
-    replace_late_bound_regions(tcx, value, |_, _| ty::ReStatic).0
+    replace_late_bound_regions(tcx, value, |_| ty::ReStatic).0
 }
 
 /// Rewrite any late-bound regions so that they are anonymous.  Region numbers are
@@ -6730,9 +6730,9 @@ pub fn anonymize_late_bound_regions<'tcx, T>(
     where T : TypeFoldable<'tcx> + Repr<'tcx>,
 {
     let mut counter = 0;
-    ty::Binder(replace_late_bound_regions(tcx, sig, |_, db| {
+    ty::Binder(replace_late_bound_regions(tcx, sig, |_| {
         counter += 1;
-        ReLateBound(db, BrAnon(counter))
+        ReLateBound(ty::DebruijnIndex::new(1), BrAnon(counter))
     }).0)
 }
 
@@ -6743,7 +6743,7 @@ pub fn replace_late_bound_regions<'tcx, T, F>(
     mut mapf: F)
     -> (T, FnvHashMap<ty::BoundRegion,ty::Region>)
     where T : TypeFoldable<'tcx> + Repr<'tcx>,
-          F : FnMut(BoundRegion, DebruijnIndex) -> ty::Region,
+          F : FnMut(BoundRegion) -> ty::Region,
 {
     debug!("replace_late_bound_regions({})", binder.repr(tcx));
 
@@ -6755,8 +6755,19 @@ pub fn replace_late_bound_regions<'tcx, T, F>(
         debug!("region={}", region.repr(tcx));
         match region {
             ty::ReLateBound(debruijn, br) if debruijn.depth == current_depth => {
-                * map.entry(br).get().unwrap_or_else(
-                      |vacant_entry| vacant_entry.insert(mapf(br, debruijn)))
+                let region =
+                    * map.entry(br).get().unwrap_or_else(
+                        |vacant_entry| vacant_entry.insert(mapf(br)));
+
+                if let ty::ReLateBound(debruijn1, br) = region {
+                    // If the callback returns a late-bound region,
+                    // that region should always use depth 1. Then we
+                    // adjust it to the correct depth.
+                    assert_eq!(debruijn1.depth, 1);
+                    ty::ReLateBound(debruijn, br)
+                } else {
+                    region
+                }
             }
             _ => {
                 region
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 2d433369366..0cf676b7035 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -1182,8 +1182,8 @@ impl<'tcx, T> UserString<'tcx> for ty::Binder<T>
         // the output. We'll probably want to tweak this over time to
         // decide just how much information to give.
         let mut names = Vec::new();
-        let (unbound_value, _) = ty::replace_late_bound_regions(tcx, self, |br, debruijn| {
-            ty::ReLateBound(debruijn, match br {
+        let (unbound_value, _) = ty::replace_late_bound_regions(tcx, self, |br| {
+            ty::ReLateBound(ty::DebruijnIndex::new(1), match br {
                 ty::BrNamed(_, name) => {
                     names.push(token::get_name(name));
                     br