1
Fork 0

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`.
This commit is contained in:
bors 2016-04-05 03:26:58 -07:00
commit 7ded11a58c
3 changed files with 23 additions and 68 deletions

View file

@ -116,21 +116,9 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
pub trait TypeFolder<'tcx> : Sized { pub trait TypeFolder<'tcx> : Sized {
fn tcx<'a>(&'a self) -> &'a TyCtxt<'tcx>; 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> fn fold_binder<T>(&mut self, t: &Binder<T>) -> Binder<T>
where T : TypeFoldable<'tcx> where T : TypeFoldable<'tcx>
{ {
// FIXME(#20526) this should replace `enter_region_binder`/`exit_region_binder`.
t.super_fold_with(self) t.super_fold_with(self)
} }
@ -197,8 +185,9 @@ pub trait TypeFolder<'tcx> : Sized {
} }
pub trait TypeVisitor<'tcx> : Sized { pub trait TypeVisitor<'tcx> : Sized {
fn enter_region_binder(&mut self) { } fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> bool {
fn exit_region_binder(&mut self) { } t.super_visit_with(self)
}
fn visit_ty(&mut self, t: Ty<'tcx>) -> bool { fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
t.super_visit_with(self) 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 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; self.current_depth += 1;
} let t = t.super_fold_with(self);
fn exit_region_binder(&mut self) {
self.current_depth -= 1; self.current_depth -= 1;
t
} }
fn fold_region(&mut self, r: ty::Region) -> ty::Region { 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 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; self.current_depth += 1;
} let t = t.super_fold_with(self);
fn exit_region_binder(&mut self) {
self.current_depth -= 1; self.current_depth -= 1;
t
} }
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
@ -596,12 +583,11 @@ struct HasEscapingRegionsVisitor {
} }
impl<'tcx> TypeVisitor<'tcx> for 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; self.depth += 1;
} let result = t.super_visit_with(self);
fn exit_region_binder(&mut self) {
self.depth -= 1; self.depth -= 1;
result
} }
fn visit_ty(&mut self, t: Ty<'tcx>) -> bool { fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {

View file

@ -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> { impl<'tcx, T:TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<T> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self { fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
folder.enter_region_binder(); ty::Binder(self.0.fold_with(folder))
let result = ty::Binder(self.0.fold_with(folder));
folder.exit_region_binder();
result
} }
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self { 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 { fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
visitor.enter_region_binder(); self.0.visit_with(visitor)
if self.0.visit_with(visitor) { return true } }
visitor.exit_region_binder();
false 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> { impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for VecPerParamSpace<T> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self { fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
self.map(|elem| elem.fold_with(folder))
// 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
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool { fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
let mut entered_region_binder = false; self.iter().any(|elem| elem.visit_with(visitor))
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
} }
} }

View file

@ -582,12 +582,11 @@ struct SubstFolder<'a, 'tcx: 'a> {
impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
fn tcx(&self) -> &TyCtxt<'tcx> { self.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; self.region_binders_passed += 1;
} let t = t.super_fold_with(self);
fn exit_region_binder(&mut self) {
self.region_binders_passed -= 1; self.region_binders_passed -= 1;
t
} }
fn fold_region(&mut self, r: ty::Region) -> ty::Region { fn fold_region(&mut self, r: ty::Region) -> ty::Region {