diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2015-01-07 14:05:32 -0500 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2015-01-07 14:07:58 -0500 |
| commit | aec62af7427083ac7f6dcb2fd484876199147fdc (patch) | |
| tree | f8662116d1ccac393c02aa29201341e6f86e091a /src | |
| parent | cf136cd3507a5e929cff8d03179c0f6d96bdb687 (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.rs | 2 | ||||
| -rw-r--r-- | src/librustc/middle/infer/mod.rs | 2 | ||||
| -rw-r--r-- | src/librustc/middle/ty.rs | 27 | ||||
| -rw-r--r-- | src/librustc/util/ppaux.rs | 4 |
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 |
