Skip to content

Remove implicit binder from FnSpace in VecPerParamSpace (fixes #20526) #29463

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 5, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 12 additions & 26 deletions src/librustc/ty/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -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 {
Expand Down
46 changes: 8 additions & 38 deletions src/librustc/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,21 +190,19 @@ 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 {
folder.fold_binder(self)
}

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)
}
}

Expand All @@ -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))
}
}

Expand Down
7 changes: 3 additions & 4 deletions src/librustc/ty/subst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down