Skip to content

Commit

Permalink
Auto merge of #50475 - csmoe:debr, r=nikomatsakis
Browse files Browse the repository at this point in the history
Refactor DebruijnIndex to be 0-based

Fixes #49813
  • Loading branch information
bors committed May 29, 2018
2 parents e9a489b + 783fe4f commit 5ae5361
Show file tree
Hide file tree
Showing 31 changed files with 360 additions and 184 deletions.
10 changes: 3 additions & 7 deletions src/librustc/ich/impls_ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,16 +104,16 @@ for ty::RegionKind {
c.hash_stable(hcx, hasher);
}
ty::ReLateBound(db, ty::BrAnon(i)) => {
db.depth.hash_stable(hcx, hasher);
db.hash_stable(hcx, hasher);
i.hash_stable(hcx, hasher);
}
ty::ReLateBound(db, ty::BrNamed(def_id, name)) => {
db.depth.hash_stable(hcx, hasher);
db.hash_stable(hcx, hasher);
def_id.hash_stable(hcx, hasher);
name.hash_stable(hcx, hasher);
}
ty::ReLateBound(db, ty::BrEnv) => {
db.depth.hash_stable(hcx, hasher);
db.hash_stable(hcx, hasher);
}
ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, index, name }) => {
def_id.hash_stable(hcx, hasher);
Expand Down Expand Up @@ -821,10 +821,6 @@ impl_stable_hash_for!(enum ::middle::resolve_lifetime::Region {
Free(call_site_scope_data, decl)
});

impl_stable_hash_for!(struct ty::DebruijnIndex {
depth
});

impl_stable_hash_for!(enum ty::cast::CastKind {
CoercionCast,
PtrPtrCast,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
tcx: self.tcx,
bound_region: *br,
found_type: None,
depth: 1,
current_index: ty::DebruijnIndex::INNERMOST,
};
nested_visitor.visit_ty(arg);
nested_visitor.found_type
Expand All @@ -99,7 +99,7 @@ struct FindNestedTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
// The type where the anonymous lifetime appears
// for e.g. Vec<`&u8`> and <`&u8`>
found_type: Option<&'gcx hir::Ty>,
depth: u32,
current_index: ty::DebruijnIndex,
}

impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> {
Expand All @@ -110,16 +110,16 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> {
fn visit_ty(&mut self, arg: &'gcx hir::Ty) {
match arg.node {
hir::TyBareFn(_) => {
self.depth += 1;
self.current_index.shift_in(1);
intravisit::walk_ty(self, arg);
self.depth -= 1;
self.current_index.shift_out(1);
return;
}

hir::TyTraitObject(ref bounds, _) => for bound in bounds {
self.depth += 1;
self.current_index.shift_in(1);
self.visit_poly_trait_ref(bound, hir::TraitBoundModifier::None);
self.depth -= 1;
self.current_index.shift_out(1);
},

hir::TyRptr(ref lifetime, _) => {
Expand All @@ -135,11 +135,11 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> {
) => {
debug!(
"LateBoundAnon depth = {:?} anon_index = {:?} br_index={:?}",
debruijn_index.depth,
debruijn_index,
anon_index,
br_index
);
if debruijn_index.depth == self.depth && anon_index == br_index {
if debruijn_index == self.current_index && anon_index == br_index {
self.found_type = Some(arg);
return; // we can stop visiting now
}
Expand Down Expand Up @@ -170,11 +170,11 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> {
) => {
debug!(
"FindNestedTypeVisitor::visit_ty: LateBound depth = {:?}",
debruijn_index.depth
debruijn_index
);
debug!("self.infcx.tcx.hir.local_def_id(id)={:?}", id);
debug!("def_id={:?}", def_id);
if debruijn_index.depth == self.depth && id == def_id {
if debruijn_index == self.current_index && id == def_id {
self.found_type = Some(arg);
return; // we can stop visiting now
}
Expand All @@ -196,7 +196,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> {
tcx: self.tcx,
found_it: false,
bound_region: self.bound_region,
depth: self.depth,
current_index: self.current_index,
};
intravisit::walk_ty(subvisitor, arg); // call walk_ty; as visit_ty is empty,
// this will visit only outermost type
Expand All @@ -222,7 +222,7 @@ struct TyPathVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
tcx: TyCtxt<'a, 'gcx, 'tcx>,
found_it: bool,
bound_region: ty::BoundRegion,
depth: u32,
current_index: ty::DebruijnIndex,
}

impl<'a, 'gcx, 'tcx> Visitor<'gcx> for TyPathVisitor<'a, 'gcx, 'tcx> {
Expand All @@ -235,7 +235,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for TyPathVisitor<'a, 'gcx, 'tcx> {
match (self.tcx.named_region(hir_id), self.bound_region) {
// the lifetime of the TyPath!
(Some(rl::Region::LateBoundAnon(debruijn_index, anon_index)), ty::BrAnon(br_index)) => {
if debruijn_index.depth == self.depth && anon_index == br_index {
if debruijn_index == self.current_index && anon_index == br_index {
self.found_it = true;
return;
}
Expand All @@ -257,11 +257,11 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for TyPathVisitor<'a, 'gcx, 'tcx> {
(Some(rl::Region::LateBound(debruijn_index, id, _)), ty::BrNamed(def_id, _)) => {
debug!(
"FindNestedTypeVisitor::visit_ty: LateBound depth = {:?}",
debruijn_index.depth
debruijn_index,
);
debug!("id={:?}", id);
debug!("def_id={:?}", def_id);
if debruijn_index.depth == self.depth && id == def_id {
if debruijn_index == self.current_index && id == def_id {
self.found_it = true;
return; // we can stop visiting now
}
Expand Down
11 changes: 7 additions & 4 deletions src/librustc/infer/higher_ranked/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,8 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
{
for (a_br, a_r) in a_map {
if *a_r == r {
return infcx.tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1), *a_br));
return infcx.tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::INNERMOST,
*a_br));
}
}
span_bug!(
Expand Down Expand Up @@ -473,7 +474,7 @@ fn fold_regions_in<'a, 'gcx, 'tcx, T, F>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
_ => true
});

fldr(region, ty::DebruijnIndex::new(current_depth))
fldr(region, current_depth)
})
}

Expand Down Expand Up @@ -734,7 +735,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
// trait checking, and all of the skolemized regions
// appear inside predicates, which always have
// binders, so this assert is satisfied.
assert!(current_depth > 1);
assert!(current_depth > ty::DebruijnIndex::INNERMOST);

// since leak-check passed, this skolemized region
// should only have incoming edges from variables
Expand All @@ -750,7 +751,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
r, br);

self.tcx.mk_region(ty::ReLateBound(
ty::DebruijnIndex::new(current_depth - 1), br.clone()))
current_depth.shifted_out(1),
br.clone(),
))
}
}
});
Expand Down
1 change: 1 addition & 0 deletions src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
#![feature(test)]
#![feature(in_band_lifetimes)]
#![feature(macro_at_most_once_rep)]
#![feature(inclusive_range_methods)]

#![recursion_limit="512"]

Expand Down
38 changes: 17 additions & 21 deletions src/librustc/middle/resolve_lifetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ impl Region {
}

fn late(hir_map: &Map, def: &hir::LifetimeDef) -> (hir::LifetimeName, Region) {
let depth = ty::DebruijnIndex::new(1);
let depth = ty::DebruijnIndex::INNERMOST;
let def_id = hir_map.local_def_id(def.lifetime.id);
let origin = LifetimeDefOrigin::from_is_in_band(def.in_band);
(def.lifetime.name, Region::LateBound(depth, def_id, origin))
Expand All @@ -107,7 +107,7 @@ impl Region {
fn late_anon(index: &Cell<u32>) -> Region {
let i = index.get();
index.set(i + 1);
let depth = ty::DebruijnIndex::new(1);
let depth = ty::DebruijnIndex::INNERMOST;
Region::LateBoundAnon(depth, i)
}

Expand All @@ -123,29 +123,25 @@ impl Region {

fn shifted(self, amount: u32) -> Region {
match self {
Region::LateBound(depth, id, origin) => {
Region::LateBound(depth.shifted(amount), id, origin)
Region::LateBound(debruijn, id, origin) => {
Region::LateBound(debruijn.shifted_in(amount), id, origin)
}
Region::LateBoundAnon(depth, index) => {
Region::LateBoundAnon(depth.shifted(amount), index)
Region::LateBoundAnon(debruijn, index) => {
Region::LateBoundAnon(debruijn.shifted_in(amount), index)
}
_ => self,
}
}

fn from_depth(self, depth: u32) -> Region {
fn shifted_out_to_binder(self, binder: ty::DebruijnIndex) -> Region {
match self {
Region::LateBound(debruijn, id, origin) => Region::LateBound(
ty::DebruijnIndex {
depth: debruijn.depth - (depth - 1),
},
debruijn.shifted_out_to_binder(binder),
id,
origin,
),
Region::LateBoundAnon(debruijn, index) => Region::LateBoundAnon(
ty::DebruijnIndex {
depth: debruijn.depth - (depth - 1),
},
debruijn.shifted_out_to_binder(binder),
index,
),
_ => self,
Expand Down Expand Up @@ -1858,7 +1854,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
.map(|(i, input)| {
let mut gather = GatherLifetimes {
map: self.map,
binder_depth: 1,
outer_index: ty::DebruijnIndex::INNERMOST,
have_bound_regions: false,
lifetimes: FxHashSet(),
};
Expand Down Expand Up @@ -1899,7 +1895,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {

struct GatherLifetimes<'a> {
map: &'a NamedRegionMap,
binder_depth: u32,
outer_index: ty::DebruijnIndex,
have_bound_regions: bool,
lifetimes: FxHashSet<Region>,
}
Expand All @@ -1911,7 +1907,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {

fn visit_ty(&mut self, ty: &hir::Ty) {
if let hir::TyBareFn(_) = ty.node {
self.binder_depth += 1;
self.outer_index.shift_in(1);
}
if let hir::TyTraitObject(ref bounds, ref lifetime) = ty.node {
for bound in bounds {
Expand All @@ -1927,7 +1923,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
intravisit::walk_ty(self, ty);
}
if let hir::TyBareFn(_) = ty.node {
self.binder_depth -= 1;
self.outer_index.shift_out(1);
}
}

Expand All @@ -1946,22 +1942,22 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
trait_ref: &hir::PolyTraitRef,
modifier: hir::TraitBoundModifier,
) {
self.binder_depth += 1;
self.outer_index.shift_in(1);
intravisit::walk_poly_trait_ref(self, trait_ref, modifier);
self.binder_depth -= 1;
self.outer_index.shift_out(1);
}

fn visit_lifetime(&mut self, lifetime_ref: &hir::Lifetime) {
if let Some(&lifetime) = self.map.defs.get(&lifetime_ref.id) {
match lifetime {
Region::LateBound(debruijn, _, _) | Region::LateBoundAnon(debruijn, _)
if debruijn.depth < self.binder_depth =>
if debruijn < self.outer_index =>
{
self.have_bound_regions = true;
}
_ => {
self.lifetimes
.insert(lifetime.from_depth(self.binder_depth));
.insert(lifetime.shifted_out_to_binder(self.outer_index));
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
let ty_struct = TyS {
sty: st,
flags: flags.flags,
region_depth: flags.depth,
outer_exclusive_binder: flags.outer_exclusive_binder,
};

// Make sure we don't end up with inference
Expand All @@ -205,7 +205,7 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
let ty_struct = TyS {
sty: st,
flags: flags.flags,
region_depth: flags.depth,
outer_exclusive_binder: flags.outer_exclusive_binder,
};

// This is safe because all the types the ty_struct can point to
Expand Down
36 changes: 24 additions & 12 deletions src/librustc/ty/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@ use ty::{self, Ty, TypeFlags, TypeFoldable};
pub struct FlagComputation {
pub flags: TypeFlags,

// maximum depth of any bound region that we have seen thus far
pub depth: u32,
// see `TyS::outer_exclusive_binder` for details
pub outer_exclusive_binder: ty::DebruijnIndex,
}

impl FlagComputation {
fn new() -> FlagComputation {
FlagComputation { flags: TypeFlags::empty(), depth: 0 }
FlagComputation {
flags: TypeFlags::empty(),
outer_exclusive_binder: ty::DebruijnIndex::INNERMOST,
}
}

pub fn for_sty(st: &ty::TypeVariants) -> FlagComputation {
Expand All @@ -35,10 +38,17 @@ impl FlagComputation {
self.flags = self.flags | (flags & TypeFlags::NOMINAL_FLAGS);
}

fn add_depth(&mut self, depth: u32) {
if depth > self.depth {
self.depth = depth;
}
/// indicates that `self` refers to something at binding level `binder`
fn add_binder(&mut self, binder: ty::DebruijnIndex) {
let exclusive_binder = binder.shifted_in(1);
self.add_exclusive_binder(exclusive_binder);
}

/// indicates that `self` refers to something *inside* binding
/// level `binder` -- not bound by `binder`, but bound by the next
/// binder internal to it
fn add_exclusive_binder(&mut self, exclusive_binder: ty::DebruijnIndex) {
self.outer_exclusive_binder = self.outer_exclusive_binder.max(exclusive_binder);
}

/// Adds the flags/depth from a set of types that appear within the current type, but within a
Expand All @@ -49,9 +59,11 @@ impl FlagComputation {
// The types that contributed to `computation` occurred within
// a region binder, so subtract one from the region depth
// within when adding the depth to `self`.
let depth = computation.depth;
if depth > 0 {
self.add_depth(depth - 1);
let outer_exclusive_binder = computation.outer_exclusive_binder;
if outer_exclusive_binder > ty::DebruijnIndex::INNERMOST {
self.add_exclusive_binder(outer_exclusive_binder.shifted_out(1));
} else {
// otherwise, this binder captures nothing
}
}

Expand Down Expand Up @@ -194,7 +206,7 @@ impl FlagComputation {

fn add_ty(&mut self, ty: Ty) {
self.add_flags(ty.flags);
self.add_depth(ty.region_depth);
self.add_exclusive_binder(ty.outer_exclusive_binder);
}

fn add_tys(&mut self, tys: &[Ty]) {
Expand All @@ -215,7 +227,7 @@ impl FlagComputation {
fn add_region(&mut self, r: ty::Region) {
self.add_flags(r.type_flags());
if let ty::ReLateBound(debruijn, _) = *r {
self.add_depth(debruijn.depth);
self.add_binder(debruijn);
}
}

Expand Down
Loading

0 comments on commit 5ae5361

Please sign in to comment.