Skip to content

Commit cfdf14c

Browse files
jackh726lcnr
authored andcommitted
Split Bound into Canonical and Bound
1 parent 035b866 commit cfdf14c

File tree

45 files changed

+345
-211
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+345
-211
lines changed

compiler/rustc_borrowck/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
278278
mut map: impl FnMut(ty::RegionVid) -> ty::Region<'tcx>,
279279
) -> Ty<'tcx> {
280280
fold_regions(tcx, self.inner, |r, depth| match r.kind() {
281-
ty::ReBound(debruijn, br) => {
281+
ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), br) => {
282282
debug_assert_eq!(debruijn, depth);
283283
map(ty::RegionVid::from_usize(br.var.index()))
284284
}

compiler/rustc_hir_analysis/src/collect/item_bounds.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -181,21 +181,25 @@ fn remap_gat_vars_and_recurse_into_nested_projections<'tcx>(
181181
for (param, var) in std::iter::zip(&generics.own_params, gat_vars) {
182182
let existing = match var.kind() {
183183
ty::GenericArgKind::Lifetime(re) => {
184-
if let ty::RegionKind::ReBound(ty::INNERMOST, bv) = re.kind() {
184+
if let ty::RegionKind::ReBound(ty::BoundVarIndexKind::Bound(ty::INNERMOST), bv) =
185+
re.kind()
186+
{
185187
mapping.insert(bv.var, tcx.mk_param_from_def(param))
186188
} else {
187189
return None;
188190
}
189191
}
190192
ty::GenericArgKind::Type(ty) => {
191-
if let ty::Bound(ty::INNERMOST, bv) = *ty.kind() {
193+
if let ty::Bound(ty::BoundVarIndexKind::Bound(ty::INNERMOST), bv) = *ty.kind() {
192194
mapping.insert(bv.var, tcx.mk_param_from_def(param))
193195
} else {
194196
return None;
195197
}
196198
}
197199
ty::GenericArgKind::Const(ct) => {
198-
if let ty::ConstKind::Bound(ty::INNERMOST, bv) = ct.kind() {
200+
if let ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(ty::INNERMOST), bv) =
201+
ct.kind()
202+
{
199203
mapping.insert(bv.var, tcx.mk_param_from_def(param))
200204
} else {
201205
return None;
@@ -260,7 +264,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for MapAndCompressBoundVars<'tcx> {
260264
return ty;
261265
}
262266

263-
if let ty::Bound(binder, old_bound) = *ty.kind()
267+
if let ty::Bound(ty::BoundVarIndexKind::Bound(binder), old_bound) = *ty.kind()
264268
&& self.binder == binder
265269
{
266270
let mapped = if let Some(mapped) = self.mapping.get(&old_bound.var) {
@@ -286,7 +290,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for MapAndCompressBoundVars<'tcx> {
286290
}
287291

288292
fn fold_region(&mut self, re: ty::Region<'tcx>) -> ty::Region<'tcx> {
289-
if let ty::ReBound(binder, old_bound) = re.kind()
293+
if let ty::ReBound(ty::BoundVarIndexKind::Bound(binder), old_bound) = re.kind()
290294
&& self.binder == binder
291295
{
292296
let mapped = if let Some(mapped) = self.mapping.get(&old_bound.var) {
@@ -314,7 +318,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for MapAndCompressBoundVars<'tcx> {
314318
return ct;
315319
}
316320

317-
if let ty::ConstKind::Bound(binder, old_bound) = ct.kind()
321+
if let ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(binder), old_bound) = ct.kind()
318322
&& self.binder == binder
319323
{
320324
let mapped = if let Some(mapped) = self.mapping.get(&old_bound.var) {

compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -921,7 +921,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GenericParamAndBoundVarCollector<'_, 't
921921
ty::Param(param) => {
922922
self.params.insert(param.index);
923923
}
924-
ty::Bound(db, bt) if *db >= self.depth => {
924+
ty::Bound(ty::BoundVarIndexKind::Bound(db), bt) if *db >= self.depth => {
925925
self.vars.insert(match bt.kind {
926926
ty::BoundTyKind::Param(def_id) => def_id,
927927
ty::BoundTyKind::Anon => {
@@ -944,7 +944,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GenericParamAndBoundVarCollector<'_, 't
944944
ty::ReEarlyParam(param) => {
945945
self.params.insert(param.index);
946946
}
947-
ty::ReBound(db, br) if db >= self.depth => {
947+
ty::ReBound(ty::BoundVarIndexKind::Bound(db), br) if db >= self.depth => {
948948
self.vars.insert(match br.kind {
949949
ty::BoundRegionKind::Named(def_id) => def_id,
950950
ty::BoundRegionKind::Anon | ty::BoundRegionKind::ClosureEnv => {
@@ -967,7 +967,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GenericParamAndBoundVarCollector<'_, 't
967967
ty::ConstKind::Param(param) => {
968968
self.params.insert(param.index);
969969
}
970-
ty::ConstKind::Bound(db, _) if db >= self.depth => {
970+
ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(db), _) if db >= self.depth => {
971971
let guar = self.cx.dcx().delayed_bug("unexpected escaping late-bound const var");
972972
return ControlFlow::Break(guar);
973973
}

compiler/rustc_infer/src/infer/canonical/canonicalizer.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -324,14 +324,18 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
324324

325325
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
326326
match r.kind() {
327-
ty::ReBound(index, ..) => {
327+
ty::ReBound(ty::BoundVarIndexKind::Bound(index), ..) => {
328328
if index >= self.binder_index {
329329
bug!("escaping late-bound region during canonicalization");
330330
} else {
331331
r
332332
}
333333
}
334334

335+
ty::ReBound(ty::BoundVarIndexKind::Canonical, _) => {
336+
bug!("canonicalized bound var found during canonicalization");
337+
}
338+
335339
ty::ReStatic
336340
| ty::ReEarlyParam(..)
337341
| ty::ReError(_)
@@ -403,14 +407,18 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
403407
self.canonicalize_ty_var(CanonicalVarKind::PlaceholderTy(placeholder), t)
404408
}
405409

406-
ty::Bound(debruijn, _) => {
410+
ty::Bound(ty::BoundVarIndexKind::Bound(debruijn), _) => {
407411
if debruijn >= self.binder_index {
408412
bug!("escaping bound type during canonicalization")
409413
} else {
410414
t
411415
}
412416
}
413417

418+
ty::Bound(ty::BoundVarIndexKind::Canonical, _) => {
419+
bug!("canonicalized bound var found during canonicalization");
420+
}
421+
414422
ty::Closure(..)
415423
| ty::CoroutineClosure(..)
416424
| ty::Coroutine(..)
@@ -479,13 +487,16 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
479487
ty::ConstKind::Infer(InferConst::Fresh(_)) => {
480488
bug!("encountered a fresh const during canonicalization")
481489
}
482-
ty::ConstKind::Bound(debruijn, _) => {
490+
ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(debruijn), _) => {
483491
if debruijn >= self.binder_index {
484492
bug!("escaping bound const during canonicalization")
485493
} else {
486494
return ct;
487495
}
488496
}
497+
ty::ConstKind::Bound(ty::BoundVarIndexKind::Canonical, _) => {
498+
bug!("canonicalized bound var found during canonicalization");
499+
}
489500
ty::ConstKind::Placeholder(placeholder) => {
490501
return self
491502
.canonicalize_const_var(CanonicalVarKind::PlaceholderConst(placeholder), ct);
@@ -752,7 +763,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
752763
) -> ty::Region<'tcx> {
753764
let var = self.canonical_var(var_kind, r.into());
754765
let br = ty::BoundRegion { var, kind: ty::BoundRegionKind::Anon };
755-
ty::Region::new_bound(self.cx(), self.binder_index, br)
766+
ty::Region::new_canonical_bound(self.cx(), br)
756767
}
757768

758769
/// Given a type variable `ty_var` of the given kind, first check
@@ -767,7 +778,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
767778
debug_assert!(!self.infcx.is_some_and(|infcx| ty_var != infcx.shallow_resolve(ty_var)));
768779
let var = self.canonical_var(var_kind, ty_var.into());
769780
let bt = ty::BoundTy { var, kind: ty::BoundTyKind::Anon };
770-
Ty::new_bound(self.tcx, self.binder_index, bt)
781+
Ty::new_canonical_bound(self.tcx, bt)
771782
}
772783

773784
/// Given a type variable `const_var` of the given kind, first check
@@ -784,6 +795,6 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
784795
);
785796
let var = self.canonical_var(var_kind, ct_var.into());
786797
let bc = ty::BoundConst { var };
787-
ty::Const::new_bound(self.tcx, self.binder_index, bc)
798+
ty::Const::new_canonical_bound(self.tcx, bc)
788799
}
789800
}

compiler/rustc_infer/src/infer/canonical/instantiate.rs

Lines changed: 16 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_middle::ty::{
1111
self, DelayedMap, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable,
1212
TypeVisitableExt, TypeVisitor,
1313
};
14-
use rustc_type_ir::TypeVisitable;
14+
use rustc_type_ir::{TypeFlags, TypeVisitable};
1515

1616
use crate::infer::canonical::{Canonical, CanonicalVarValues};
1717

@@ -66,7 +66,6 @@ where
6666

6767
value.fold_with(&mut CanonicalInstantiator {
6868
tcx,
69-
current_index: ty::INNERMOST,
7069
var_values: var_values.var_values,
7170
cache: Default::default(),
7271
})
@@ -79,42 +78,28 @@ struct CanonicalInstantiator<'tcx> {
7978
// The values that the bound vars are are being instantiated with.
8079
var_values: ty::GenericArgsRef<'tcx>,
8180

82-
/// As with `BoundVarReplacer`, represents the index of a binder *just outside*
83-
/// the ones we have visited.
84-
current_index: ty::DebruijnIndex,
85-
8681
// Instantiation is a pure function of `DebruijnIndex` and `Ty`.
87-
cache: DelayedMap<(ty::DebruijnIndex, Ty<'tcx>), Ty<'tcx>>,
82+
cache: DelayedMap<Ty<'tcx>, Ty<'tcx>>,
8883
}
8984

9085
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for CanonicalInstantiator<'tcx> {
9186
fn cx(&self) -> TyCtxt<'tcx> {
9287
self.tcx
9388
}
9489

95-
fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
96-
&mut self,
97-
t: ty::Binder<'tcx, T>,
98-
) -> ty::Binder<'tcx, T> {
99-
self.current_index.shift_in(1);
100-
let t = t.super_fold_with(self);
101-
self.current_index.shift_out(1);
102-
t
103-
}
104-
10590
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
10691
match *t.kind() {
107-
ty::Bound(debruijn, bound_ty) if debruijn == self.current_index => {
92+
ty::Bound(ty::BoundVarIndexKind::Canonical, bound_ty) => {
10893
self.var_values[bound_ty.var.as_usize()].expect_ty()
10994
}
11095
_ => {
111-
if !t.has_vars_bound_at_or_above(self.current_index) {
96+
if !t.has_type_flags(TypeFlags::HAS_CANONICAL_BOUND) {
11297
t
113-
} else if let Some(&t) = self.cache.get(&(self.current_index, t)) {
98+
} else if let Some(&t) = self.cache.get(&t) {
11499
t
115100
} else {
116101
let res = t.super_fold_with(self);
117-
assert!(self.cache.insert((self.current_index, t), res));
102+
assert!(self.cache.insert(t, res));
118103
res
119104
}
120105
}
@@ -123,7 +108,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for CanonicalInstantiator<'tcx> {
123108

124109
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
125110
match r.kind() {
126-
ty::ReBound(debruijn, br) if debruijn == self.current_index => {
111+
ty::ReBound(ty::BoundVarIndexKind::Canonical, br) => {
127112
self.var_values[br.var.as_usize()].expect_region()
128113
}
129114
_ => r,
@@ -132,30 +117,22 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for CanonicalInstantiator<'tcx> {
132117

133118
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
134119
match ct.kind() {
135-
ty::ConstKind::Bound(debruijn, bound_const) if debruijn == self.current_index => {
120+
ty::ConstKind::Bound(ty::BoundVarIndexKind::Canonical, bound_const) => {
136121
self.var_values[bound_const.var.as_usize()].expect_const()
137122
}
138123
_ => ct.super_fold_with(self),
139124
}
140125
}
141126

142127
fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
143-
if p.has_vars_bound_at_or_above(self.current_index) { p.super_fold_with(self) } else { p }
128+
if p.has_type_flags(TypeFlags::HAS_CANONICAL_BOUND) { p.super_fold_with(self) } else { p }
144129
}
145130

146131
fn fold_clauses(&mut self, c: ty::Clauses<'tcx>) -> ty::Clauses<'tcx> {
147-
if !c.has_vars_bound_at_or_above(self.current_index) {
132+
if !c.has_type_flags(TypeFlags::HAS_CANONICAL_BOUND) {
148133
return c;
149134
}
150135

151-
// Since instantiation is a function of `DebruijnIndex`, we don't want
152-
// to have to cache more copies of clauses when we're inside of binders.
153-
// Since we currently expect to only have clauses in the outermost
154-
// debruijn index, we just fold if we're inside of a binder.
155-
if self.current_index > ty::INNERMOST {
156-
return c.super_fold_with(self);
157-
}
158-
159136
// Our cache key is `(clauses, var_values)`, but we also don't care about
160137
// var values that aren't named in the clauses, since they can change without
161138
// affecting the output. Since `ParamEnv`s are cached first, we compute the
@@ -185,45 +162,29 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for CanonicalInstantiator<'tcx> {
185162
fn highest_var_in_clauses<'tcx>(c: ty::Clauses<'tcx>) -> usize {
186163
struct HighestVarInClauses {
187164
max_var: usize,
188-
current_index: ty::DebruijnIndex,
189165
}
190166
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HighestVarInClauses {
191-
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
192-
&mut self,
193-
t: &ty::Binder<'tcx, T>,
194-
) -> Self::Result {
195-
self.current_index.shift_in(1);
196-
let t = t.super_visit_with(self);
197-
self.current_index.shift_out(1);
198-
t
199-
}
200167
fn visit_ty(&mut self, t: Ty<'tcx>) {
201-
if let ty::Bound(debruijn, bound_ty) = *t.kind()
202-
&& debruijn == self.current_index
203-
{
168+
if let ty::Bound(ty::BoundVarIndexKind::Canonical, bound_ty) = *t.kind() {
204169
self.max_var = self.max_var.max(bound_ty.var.as_usize());
205-
} else if t.has_vars_bound_at_or_above(self.current_index) {
170+
} else if t.has_type_flags(TypeFlags::HAS_CANONICAL_BOUND) {
206171
t.super_visit_with(self);
207172
}
208173
}
209174
fn visit_region(&mut self, r: ty::Region<'tcx>) {
210-
if let ty::ReBound(debruijn, bound_region) = r.kind()
211-
&& debruijn == self.current_index
212-
{
175+
if let ty::ReBound(ty::BoundVarIndexKind::Canonical, bound_region) = r.kind() {
213176
self.max_var = self.max_var.max(bound_region.var.as_usize());
214177
}
215178
}
216179
fn visit_const(&mut self, ct: ty::Const<'tcx>) {
217-
if let ty::ConstKind::Bound(debruijn, bound_const) = ct.kind()
218-
&& debruijn == self.current_index
219-
{
180+
if let ty::ConstKind::Bound(ty::BoundVarIndexKind::Canonical, bound_const) = ct.kind() {
220181
self.max_var = self.max_var.max(bound_const.var.as_usize());
221-
} else if ct.has_vars_bound_at_or_above(self.current_index) {
182+
} else if ct.has_type_flags(TypeFlags::HAS_CANONICAL_BOUND) {
222183
ct.super_visit_with(self);
223184
}
224185
}
225186
}
226-
let mut visitor = HighestVarInClauses { max_var: 0, current_index: ty::INNERMOST };
187+
let mut visitor = HighestVarInClauses { max_var: 0 };
227188
c.visit_with(&mut visitor);
228189
visitor.max_var
229190
}

compiler/rustc_infer/src/infer/canonical/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use rustc_index::IndexVec;
2626
pub use rustc_middle::infer::canonical::*;
2727
use rustc_middle::ty::{self, GenericArg, Ty, TyCtxt, TypeFoldable};
2828
use rustc_span::Span;
29+
use rustc_type_ir::TypeFlags;
2930

3031
use crate::infer::{InferCtxt, RegionVariableOrigin};
3132

@@ -72,6 +73,8 @@ impl<'tcx> InferCtxt<'tcx> {
7273
self.instantiate_canonical_var(span, info, &var_values, |ui| universes[ui])
7374
});
7475
let result = canonical.instantiate(self.tcx, &var_values);
76+
use rustc_type_ir::TypeVisitableExt;
77+
assert!(!result.has_type_flags(TypeFlags::HAS_CANONICAL_BOUND));
7578
(result, var_values)
7679
}
7780

compiler/rustc_infer/src/infer/canonical/query_response.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -440,28 +440,28 @@ impl<'tcx> InferCtxt<'tcx> {
440440
// and only use it for placeholders. We need to handle the
441441
// `sub_root` of type inference variables which would make this
442442
// more involved. They are also a lot rarer than region variables.
443-
if let ty::Bound(debruijn, b) = *result_value.kind()
443+
if let ty::Bound(index_kind, b) = *result_value.kind()
444444
&& !matches!(
445445
query_response.variables[b.var.as_usize()],
446446
CanonicalVarKind::Ty { .. }
447447
)
448448
{
449-
// We only allow a `ty::INNERMOST` index in generic parameters.
450-
assert_eq!(debruijn, ty::INNERMOST);
449+
// We only allow a `Canonical` index in generic parameters.
450+
assert!(matches!(index_kind, ty::BoundVarIndexKind::Canonical));
451451
opt_values[b.var] = Some(*original_value);
452452
}
453453
}
454454
GenericArgKind::Lifetime(result_value) => {
455-
if let ty::ReBound(debruijn, b) = result_value.kind() {
456-
// We only allow a `ty::INNERMOST` index in generic parameters.
457-
assert_eq!(debruijn, ty::INNERMOST);
455+
if let ty::ReBound(index_kind, b) = result_value.kind() {
456+
// We only allow a `Canonical` index in generic parameters.
457+
assert!(matches!(index_kind, ty::BoundVarIndexKind::Canonical));
458458
opt_values[b.var] = Some(*original_value);
459459
}
460460
}
461461
GenericArgKind::Const(result_value) => {
462-
if let ty::ConstKind::Bound(debruijn, b) = result_value.kind() {
463-
// We only allow a `ty::INNERMOST` index in generic parameters.
464-
assert_eq!(debruijn, ty::INNERMOST);
462+
if let ty::ConstKind::Bound(index_kind, b) = result_value.kind() {
463+
// We only allow a `Canonical` index in generic parameters.
464+
assert!(matches!(index_kind, ty::BoundVarIndexKind::Canonical));
465465
opt_values[b.var] = Some(*original_value);
466466
}
467467
}

0 commit comments

Comments
 (0)