Skip to content

Commit 5ae5361

Browse files
committed
Auto merge of #50475 - csmoe:debr, r=nikomatsakis
Refactor DebruijnIndex to be 0-based Fixes #49813
2 parents e9a489b + 783fe4f commit 5ae5361

31 files changed

+360
-184
lines changed

src/librustc/ich/impls_ty.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -104,16 +104,16 @@ for ty::RegionKind {
104104
c.hash_stable(hcx, hasher);
105105
}
106106
ty::ReLateBound(db, ty::BrAnon(i)) => {
107-
db.depth.hash_stable(hcx, hasher);
107+
db.hash_stable(hcx, hasher);
108108
i.hash_stable(hcx, hasher);
109109
}
110110
ty::ReLateBound(db, ty::BrNamed(def_id, name)) => {
111-
db.depth.hash_stable(hcx, hasher);
111+
db.hash_stable(hcx, hasher);
112112
def_id.hash_stable(hcx, hasher);
113113
name.hash_stable(hcx, hasher);
114114
}
115115
ty::ReLateBound(db, ty::BrEnv) => {
116-
db.depth.hash_stable(hcx, hasher);
116+
db.hash_stable(hcx, hasher);
117117
}
118118
ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, index, name }) => {
119119
def_id.hash_stable(hcx, hasher);
@@ -821,10 +821,6 @@ impl_stable_hash_for!(enum ::middle::resolve_lifetime::Region {
821821
Free(call_site_scope_data, decl)
822822
});
823823

824-
impl_stable_hash_for!(struct ty::DebruijnIndex {
825-
depth
826-
});
827-
828824
impl_stable_hash_for!(enum ty::cast::CastKind {
829825
CoercionCast,
830826
PtrPtrCast,

src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs

+15-15
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
7777
tcx: self.tcx,
7878
bound_region: *br,
7979
found_type: None,
80-
depth: 1,
80+
current_index: ty::DebruijnIndex::INNERMOST,
8181
};
8282
nested_visitor.visit_ty(arg);
8383
nested_visitor.found_type
@@ -99,7 +99,7 @@ struct FindNestedTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
9999
// The type where the anonymous lifetime appears
100100
// for e.g. Vec<`&u8`> and <`&u8`>
101101
found_type: Option<&'gcx hir::Ty>,
102-
depth: u32,
102+
current_index: ty::DebruijnIndex,
103103
}
104104

105105
impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> {
@@ -110,16 +110,16 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> {
110110
fn visit_ty(&mut self, arg: &'gcx hir::Ty) {
111111
match arg.node {
112112
hir::TyBareFn(_) => {
113-
self.depth += 1;
113+
self.current_index.shift_in(1);
114114
intravisit::walk_ty(self, arg);
115-
self.depth -= 1;
115+
self.current_index.shift_out(1);
116116
return;
117117
}
118118

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

125125
hir::TyRptr(ref lifetime, _) => {
@@ -135,11 +135,11 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> {
135135
) => {
136136
debug!(
137137
"LateBoundAnon depth = {:?} anon_index = {:?} br_index={:?}",
138-
debruijn_index.depth,
138+
debruijn_index,
139139
anon_index,
140140
br_index
141141
);
142-
if debruijn_index.depth == self.depth && anon_index == br_index {
142+
if debruijn_index == self.current_index && anon_index == br_index {
143143
self.found_type = Some(arg);
144144
return; // we can stop visiting now
145145
}
@@ -170,11 +170,11 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> {
170170
) => {
171171
debug!(
172172
"FindNestedTypeVisitor::visit_ty: LateBound depth = {:?}",
173-
debruijn_index.depth
173+
debruijn_index
174174
);
175175
debug!("self.infcx.tcx.hir.local_def_id(id)={:?}", id);
176176
debug!("def_id={:?}", def_id);
177-
if debruijn_index.depth == self.depth && id == def_id {
177+
if debruijn_index == self.current_index && id == def_id {
178178
self.found_type = Some(arg);
179179
return; // we can stop visiting now
180180
}
@@ -196,7 +196,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> {
196196
tcx: self.tcx,
197197
found_it: false,
198198
bound_region: self.bound_region,
199-
depth: self.depth,
199+
current_index: self.current_index,
200200
};
201201
intravisit::walk_ty(subvisitor, arg); // call walk_ty; as visit_ty is empty,
202202
// this will visit only outermost type
@@ -222,7 +222,7 @@ struct TyPathVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
222222
tcx: TyCtxt<'a, 'gcx, 'tcx>,
223223
found_it: bool,
224224
bound_region: ty::BoundRegion,
225-
depth: u32,
225+
current_index: ty::DebruijnIndex,
226226
}
227227

228228
impl<'a, 'gcx, 'tcx> Visitor<'gcx> for TyPathVisitor<'a, 'gcx, 'tcx> {
@@ -235,7 +235,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for TyPathVisitor<'a, 'gcx, 'tcx> {
235235
match (self.tcx.named_region(hir_id), self.bound_region) {
236236
// the lifetime of the TyPath!
237237
(Some(rl::Region::LateBoundAnon(debruijn_index, anon_index)), ty::BrAnon(br_index)) => {
238-
if debruijn_index.depth == self.depth && anon_index == br_index {
238+
if debruijn_index == self.current_index && anon_index == br_index {
239239
self.found_it = true;
240240
return;
241241
}
@@ -257,11 +257,11 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for TyPathVisitor<'a, 'gcx, 'tcx> {
257257
(Some(rl::Region::LateBound(debruijn_index, id, _)), ty::BrNamed(def_id, _)) => {
258258
debug!(
259259
"FindNestedTypeVisitor::visit_ty: LateBound depth = {:?}",
260-
debruijn_index.depth
260+
debruijn_index,
261261
);
262262
debug!("id={:?}", id);
263263
debug!("def_id={:?}", def_id);
264-
if debruijn_index.depth == self.depth && id == def_id {
264+
if debruijn_index == self.current_index && id == def_id {
265265
self.found_it = true;
266266
return; // we can stop visiting now
267267
}

src/librustc/infer/higher_ranked/mod.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,8 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
417417
{
418418
for (a_br, a_r) in a_map {
419419
if *a_r == r {
420-
return infcx.tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1), *a_br));
420+
return infcx.tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::INNERMOST,
421+
*a_br));
421422
}
422423
}
423424
span_bug!(
@@ -473,7 +474,7 @@ fn fold_regions_in<'a, 'gcx, 'tcx, T, F>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
473474
_ => true
474475
});
475476

476-
fldr(region, ty::DebruijnIndex::new(current_depth))
477+
fldr(region, current_depth)
477478
})
478479
}
479480

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

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

752753
self.tcx.mk_region(ty::ReLateBound(
753-
ty::DebruijnIndex::new(current_depth - 1), br.clone()))
754+
current_depth.shifted_out(1),
755+
br.clone(),
756+
))
754757
}
755758
}
756759
});

src/librustc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
#![feature(test)]
7272
#![feature(in_band_lifetimes)]
7373
#![feature(macro_at_most_once_rep)]
74+
#![feature(inclusive_range_methods)]
7475

7576
#![recursion_limit="512"]
7677

src/librustc/middle/resolve_lifetime.rs

+17-21
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ impl Region {
9898
}
9999

100100
fn late(hir_map: &Map, def: &hir::LifetimeDef) -> (hir::LifetimeName, Region) {
101-
let depth = ty::DebruijnIndex::new(1);
101+
let depth = ty::DebruijnIndex::INNERMOST;
102102
let def_id = hir_map.local_def_id(def.lifetime.id);
103103
let origin = LifetimeDefOrigin::from_is_in_band(def.in_band);
104104
(def.lifetime.name, Region::LateBound(depth, def_id, origin))
@@ -107,7 +107,7 @@ impl Region {
107107
fn late_anon(index: &Cell<u32>) -> Region {
108108
let i = index.get();
109109
index.set(i + 1);
110-
let depth = ty::DebruijnIndex::new(1);
110+
let depth = ty::DebruijnIndex::INNERMOST;
111111
Region::LateBoundAnon(depth, i)
112112
}
113113

@@ -123,29 +123,25 @@ impl Region {
123123

124124
fn shifted(self, amount: u32) -> Region {
125125
match self {
126-
Region::LateBound(depth, id, origin) => {
127-
Region::LateBound(depth.shifted(amount), id, origin)
126+
Region::LateBound(debruijn, id, origin) => {
127+
Region::LateBound(debruijn.shifted_in(amount), id, origin)
128128
}
129-
Region::LateBoundAnon(depth, index) => {
130-
Region::LateBoundAnon(depth.shifted(amount), index)
129+
Region::LateBoundAnon(debruijn, index) => {
130+
Region::LateBoundAnon(debruijn.shifted_in(amount), index)
131131
}
132132
_ => self,
133133
}
134134
}
135135

136-
fn from_depth(self, depth: u32) -> Region {
136+
fn shifted_out_to_binder(self, binder: ty::DebruijnIndex) -> Region {
137137
match self {
138138
Region::LateBound(debruijn, id, origin) => Region::LateBound(
139-
ty::DebruijnIndex {
140-
depth: debruijn.depth - (depth - 1),
141-
},
139+
debruijn.shifted_out_to_binder(binder),
142140
id,
143141
origin,
144142
),
145143
Region::LateBoundAnon(debruijn, index) => Region::LateBoundAnon(
146-
ty::DebruijnIndex {
147-
depth: debruijn.depth - (depth - 1),
148-
},
144+
debruijn.shifted_out_to_binder(binder),
149145
index,
150146
),
151147
_ => self,
@@ -1858,7 +1854,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
18581854
.map(|(i, input)| {
18591855
let mut gather = GatherLifetimes {
18601856
map: self.map,
1861-
binder_depth: 1,
1857+
outer_index: ty::DebruijnIndex::INNERMOST,
18621858
have_bound_regions: false,
18631859
lifetimes: FxHashSet(),
18641860
};
@@ -1899,7 +1895,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
18991895

19001896
struct GatherLifetimes<'a> {
19011897
map: &'a NamedRegionMap,
1902-
binder_depth: u32,
1898+
outer_index: ty::DebruijnIndex,
19031899
have_bound_regions: bool,
19041900
lifetimes: FxHashSet<Region>,
19051901
}
@@ -1911,7 +1907,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
19111907

19121908
fn visit_ty(&mut self, ty: &hir::Ty) {
19131909
if let hir::TyBareFn(_) = ty.node {
1914-
self.binder_depth += 1;
1910+
self.outer_index.shift_in(1);
19151911
}
19161912
if let hir::TyTraitObject(ref bounds, ref lifetime) = ty.node {
19171913
for bound in bounds {
@@ -1927,7 +1923,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
19271923
intravisit::walk_ty(self, ty);
19281924
}
19291925
if let hir::TyBareFn(_) = ty.node {
1930-
self.binder_depth -= 1;
1926+
self.outer_index.shift_out(1);
19311927
}
19321928
}
19331929

@@ -1946,22 +1942,22 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
19461942
trait_ref: &hir::PolyTraitRef,
19471943
modifier: hir::TraitBoundModifier,
19481944
) {
1949-
self.binder_depth += 1;
1945+
self.outer_index.shift_in(1);
19501946
intravisit::walk_poly_trait_ref(self, trait_ref, modifier);
1951-
self.binder_depth -= 1;
1947+
self.outer_index.shift_out(1);
19521948
}
19531949

19541950
fn visit_lifetime(&mut self, lifetime_ref: &hir::Lifetime) {
19551951
if let Some(&lifetime) = self.map.defs.get(&lifetime_ref.id) {
19561952
match lifetime {
19571953
Region::LateBound(debruijn, _, _) | Region::LateBoundAnon(debruijn, _)
1958-
if debruijn.depth < self.binder_depth =>
1954+
if debruijn < self.outer_index =>
19591955
{
19601956
self.have_bound_regions = true;
19611957
}
19621958
_ => {
19631959
self.lifetimes
1964-
.insert(lifetime.from_depth(self.binder_depth));
1960+
.insert(lifetime.shifted_out_to_binder(self.outer_index));
19651961
}
19661962
}
19671963
}

src/librustc/ty/context.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
181181
let ty_struct = TyS {
182182
sty: st,
183183
flags: flags.flags,
184-
region_depth: flags.depth,
184+
outer_exclusive_binder: flags.outer_exclusive_binder,
185185
};
186186

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

211211
// This is safe because all the types the ty_struct can point to

src/librustc/ty/flags.rs

+24-12
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,16 @@ use ty::{self, Ty, TypeFlags, TypeFoldable};
1616
pub struct FlagComputation {
1717
pub flags: TypeFlags,
1818

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

2323
impl FlagComputation {
2424
fn new() -> FlagComputation {
25-
FlagComputation { flags: TypeFlags::empty(), depth: 0 }
25+
FlagComputation {
26+
flags: TypeFlags::empty(),
27+
outer_exclusive_binder: ty::DebruijnIndex::INNERMOST,
28+
}
2629
}
2730

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

38-
fn add_depth(&mut self, depth: u32) {
39-
if depth > self.depth {
40-
self.depth = depth;
41-
}
41+
/// indicates that `self` refers to something at binding level `binder`
42+
fn add_binder(&mut self, binder: ty::DebruijnIndex) {
43+
let exclusive_binder = binder.shifted_in(1);
44+
self.add_exclusive_binder(exclusive_binder);
45+
}
46+
47+
/// indicates that `self` refers to something *inside* binding
48+
/// level `binder` -- not bound by `binder`, but bound by the next
49+
/// binder internal to it
50+
fn add_exclusive_binder(&mut self, exclusive_binder: ty::DebruijnIndex) {
51+
self.outer_exclusive_binder = self.outer_exclusive_binder.max(exclusive_binder);
4252
}
4353

4454
/// Adds the flags/depth from a set of types that appear within the current type, but within a
@@ -49,9 +59,11 @@ impl FlagComputation {
4959
// The types that contributed to `computation` occurred within
5060
// a region binder, so subtract one from the region depth
5161
// within when adding the depth to `self`.
52-
let depth = computation.depth;
53-
if depth > 0 {
54-
self.add_depth(depth - 1);
62+
let outer_exclusive_binder = computation.outer_exclusive_binder;
63+
if outer_exclusive_binder > ty::DebruijnIndex::INNERMOST {
64+
self.add_exclusive_binder(outer_exclusive_binder.shifted_out(1));
65+
} else {
66+
// otherwise, this binder captures nothing
5567
}
5668
}
5769

@@ -194,7 +206,7 @@ impl FlagComputation {
194206

195207
fn add_ty(&mut self, ty: Ty) {
196208
self.add_flags(ty.flags);
197-
self.add_depth(ty.region_depth);
209+
self.add_exclusive_binder(ty.outer_exclusive_binder);
198210
}
199211

200212
fn add_tys(&mut self, tys: &[Ty]) {
@@ -215,7 +227,7 @@ impl FlagComputation {
215227
fn add_region(&mut self, r: ty::Region) {
216228
self.add_flags(r.type_flags());
217229
if let ty::ReLateBound(debruijn, _) = *r {
218-
self.add_depth(debruijn.depth);
230+
self.add_binder(debruijn);
219231
}
220232
}
221233

0 commit comments

Comments
 (0)