From f03c0366ad3b0afa267dd617c671c852b3e2bb73 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 3 Jul 2018 06:24:45 -0400 Subject: [PATCH] add "free region helpers" --- src/librustc/ty/fold.rs | 46 ++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index f55a51290849..076a19fb4ed7 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -253,13 +253,34 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { value.fold_with(&mut RegionFolder::new(self, skipped_regions, &mut f)) } - pub fn for_each_free_region(self, - value: &T, - callback: F) - where F: FnMut(ty::Region<'tcx>), - T: TypeFoldable<'tcx>, - { - value.visit_with(&mut RegionVisitor { + /// Invoke `callback` on every region appearing free in `value`. + pub fn for_each_free_region( + self, + value: &impl TypeFoldable<'tcx>, + mut callback: impl FnMut(ty::Region<'tcx>), + ) { + self.any_free_region_meets(value, |r| { + callback(r); + false + }); + } + + /// True if `callback` returns true for every region appearing free in `value`. + pub fn all_free_regions_meet( + self, + value: &impl TypeFoldable<'tcx>, + mut callback: impl FnMut(ty::Region<'tcx>) -> bool, + ) -> bool { + !self.any_free_region_meets(value, |r| !callback(r)) + } + + /// True if `callback` returns true for some region appearing free in `value`. + pub fn any_free_region_meets( + self, + value: &impl TypeFoldable<'tcx>, + callback: impl FnMut(ty::Region<'tcx>) -> bool, + ) -> bool { + return value.visit_with(&mut RegionVisitor { outer_index: ty::INNERMOST, callback }); @@ -287,25 +308,22 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } impl<'tcx, F> TypeVisitor<'tcx> for RegionVisitor - where F : FnMut(ty::Region<'tcx>) + where F: FnMut(ty::Region<'tcx>) -> bool { fn visit_binder>(&mut self, t: &Binder) -> bool { self.outer_index.shift_in(1); - t.skip_binder().visit_with(self); + let result = t.skip_binder().visit_with(self); self.outer_index.shift_out(1); - - false // keep visiting + result } fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { match *r { ty::ReLateBound(debruijn, _) if debruijn < self.outer_index => { - /* ignore bound regions */ + false // ignore bound regions, keep visiting } _ => (self.callback)(r), } - - false // keep visiting } } }