Skip to content

Commit 7e15e0b

Browse files
nikomatsakiscsmoe
andcommitted
remove use of depth from TyS and replace with a debruijn index
Co-authored-by: csmoe <[email protected]>
1 parent 8f15d1e commit 7e15e0b

File tree

6 files changed

+74
-34
lines changed

6 files changed

+74
-34
lines changed

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

src/librustc/ty/fold.rs

+24-13
Original file line numberDiff line numberDiff line change
@@ -63,20 +63,22 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
6363
self.super_visit_with(visitor)
6464
}
6565

66-
fn has_regions_escaping_depth(&self, depth: u32) -> bool {
67-
self.visit_with(&mut HasEscapingRegionsVisitor { depth: depth })
68-
}
69-
7066
/// True if `self` has any late-bound regions that are either
7167
/// bound by `binder` or bound by some binder outside of `binder`.
7268
/// If `binder` is `ty::DebruijnIndex::INNERMOST`, this indicates whether
7369
/// there are any late-bound regions that appear free.
74-
fn has_regions_bound_by_or_escaping(&self, binder: ty::DebruijnIndex) -> bool {
75-
self.has_regions_escaping_depth(binder.depth - 1)
70+
fn has_regions_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool {
71+
self.visit_with(&mut HasEscapingRegionsVisitor { outer_index: binder })
72+
}
73+
74+
/// True if this `self` has any regions that escape `binder` (and
75+
/// hence are not bound by it).
76+
fn has_regions_bound_above(&self, binder: ty::DebruijnIndex) -> bool {
77+
self.has_regions_bound_at_or_above(binder.shifted_in(1))
7678
}
7779

7880
fn has_escaping_regions(&self) -> bool {
79-
self.has_regions_escaping_depth(0)
81+
self.has_regions_bound_at_or_above(ty::DebruijnIndex::INNERMOST)
8082
}
8183

8284
fn has_type_flags(&self, flags: TypeFlags) -> bool {
@@ -523,7 +525,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionReplacer<'a, 'gcx, 'tcx> {
523525
}
524526

525527
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
526-
if !t.has_regions_bound_by_or_escaping(self.current_index) {
528+
if !t.has_regions_bound_at_or_above(self.current_index) {
527529
return t;
528530
}
529531

@@ -623,23 +625,32 @@ pub fn shift_regions<'a, 'gcx, 'tcx, T>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
623625
/// represent the scope to which it is attached, etc. An escaping region represents a bound region
624626
/// for which this processing has not yet been done.
625627
struct HasEscapingRegionsVisitor {
626-
depth: u32,
628+
/// Anything bound by `outer_index` or "above" is escaping
629+
outer_index: ty::DebruijnIndex,
627630
}
628631

629632
impl<'tcx> TypeVisitor<'tcx> for HasEscapingRegionsVisitor {
630633
fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> bool {
631-
self.depth += 1;
634+
self.outer_index.shift_in(1);
632635
let result = t.super_visit_with(self);
633-
self.depth -= 1;
636+
self.outer_index.shift_out(1);
634637
result
635638
}
636639

637640
fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
638-
t.region_depth > self.depth
641+
// If the outer-exclusive-binder is *strictly greater* than
642+
// `outer_index`, that means that `t` contains some content
643+
// bound at `outer_index` or above (because
644+
// `outer_exclusive_binder` is always 1 higher than the
645+
// content in `t`). Therefore, `t` has some escaping regions.
646+
t.outer_exclusive_binder > self.outer_index
639647
}
640648

641649
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
642-
r.escapes_depth(self.depth)
650+
// If the region is bound by `outer_index` or anything outside
651+
// of outer index, then it escapes the binders we have
652+
// visited.
653+
r.bound_at_or_above_binder(self.outer_index)
643654
}
644655
}
645656

src/librustc/ty/mod.rs

+20-3
Original file line numberDiff line numberDiff line change
@@ -488,8 +488,24 @@ pub struct TyS<'tcx> {
488488
pub sty: TypeVariants<'tcx>,
489489
pub flags: TypeFlags,
490490

491-
// the maximal depth of any bound regions appearing in this type.
492-
region_depth: u32,
491+
/// This is a kind of confusing thing: it stores the smallest
492+
/// binder such that
493+
///
494+
/// (a) the binder itself captures nothing but
495+
/// (b) all the late-bound things within the type are captured
496+
/// by some sub-binder.
497+
///
498+
/// So, for a type without any late-bound things, like `u32`, this
499+
/// will be INNERMOST, because that is the innermost binder that
500+
/// captures nothing. But for a type `&'D u32`, where `'D` is a
501+
/// late-bound region with debruijn index D, this would be D+1 --
502+
/// the binder itself does not capture D, but D is captured by an
503+
/// inner binder.
504+
///
505+
/// We call this concept an "exclusive" binder D (because all
506+
/// debruijn indices within the type are contained within `0..D`
507+
/// (exclusive)).
508+
outer_exclusive_binder: ty::DebruijnIndex,
493509
}
494510

495511
impl<'tcx> Ord for TyS<'tcx> {
@@ -560,7 +576,8 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::TyS<'gcx> {
560576
// The other fields just provide fast access to information that is
561577
// also contained in `sty`, so no need to hash them.
562578
flags: _,
563-
region_depth: _,
579+
580+
outer_exclusive_binder: _,
564581
} = *self;
565582

566583
sty.hash_stable(hcx, hasher);

src/librustc/ty/sty.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1332,9 +1332,9 @@ impl RegionKind {
13321332
}
13331333
}
13341334

1335-
pub fn escapes_depth(&self, depth: u32) -> bool {
1335+
pub fn bound_at_or_above_binder(&self, index: DebruijnIndex) -> bool {
13361336
match *self {
1337-
ty::ReLateBound(debruijn, _) => debruijn.depth > depth,
1337+
ty::ReLateBound(debruijn, _) => debruijn >= index,
13381338
_ => false,
13391339
}
13401340
}

src/librustc_typeck/check/closure.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ use rustc::infer::LateBoundRegionConversionTime;
1919
use rustc::infer::type_variable::TypeVariableOrigin;
2020
use rustc::traits::error_reporting::ArgKind;
2121
use rustc::ty::{self, ToPolyTraitRef, Ty, GenericParamDefKind};
22+
use rustc::ty::fold::TypeFoldable;
2223
use rustc::ty::subst::Substs;
23-
use rustc::ty::TypeFoldable;
2424
use std::cmp;
2525
use std::iter;
2626
use rustc_target::spec::abi::Abi;
@@ -465,7 +465,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
465465
// Create a `PolyFnSig`. Note the oddity that late bound
466466
// regions appearing free in `expected_sig` are now bound up
467467
// in this binder we are creating.
468-
assert!(!expected_sig.sig.has_regions_escaping_depth(1));
468+
assert!(!expected_sig.sig.has_regions_bound_above(ty::DebruijnIndex::INNERMOST));
469469
let bound_sig = ty::Binder::bind(self.tcx.mk_fn_sig(
470470
expected_sig.sig.inputs().iter().cloned(),
471471
expected_sig.sig.output(),

0 commit comments

Comments
 (0)