Skip to content

Commit 1f8de94

Browse files
committed
Adjust bound tys indices in canonicalization
1 parent ee569c7 commit 1f8de94

File tree

4 files changed

+56
-11
lines changed

4 files changed

+56
-11
lines changed

src/librustc/infer/canonical/canonicalizer.rs

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -280,18 +280,32 @@ struct Canonicalizer<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
280280
indices: FxHashMap<Kind<'tcx>, BoundVar>,
281281
canonicalize_region_mode: &'cx dyn CanonicalizeRegionMode,
282282
needs_canonical_flags: TypeFlags,
283+
284+
binder_index: ty::DebruijnIndex,
283285
}
284286

285287
impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx> {
286288
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> {
287289
self.tcx
288290
}
289291

292+
fn fold_binder<T>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T>
293+
where T: TypeFoldable<'tcx>
294+
{
295+
self.binder_index.shift_in(1);
296+
let t = t.super_fold_with(self);
297+
self.binder_index.shift_out(1);
298+
t
299+
}
300+
290301
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
291302
match *r {
292-
ty::ReLateBound(..) => {
293-
// leave bound regions alone
294-
r
303+
ty::ReLateBound(index, ..) => {
304+
if index >= self.binder_index {
305+
bug!("escaping late bound region during canonicalization")
306+
} else {
307+
r
308+
}
295309
}
296310

297311
ty::ReVar(vid) => {
@@ -337,8 +351,12 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
337351
bug!("encountered a fresh type during canonicalization")
338352
}
339353

340-
ty::Bound(_) => {
341-
bug!("encountered a bound type during canonicalization")
354+
ty::Bound(bound_ty) => {
355+
if bound_ty.index >= self.binder_index {
356+
bug!("escaping bound type during canonicalization")
357+
} else {
358+
t
359+
}
342360
}
343361

344362
ty::Closure(..)
@@ -422,6 +440,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
422440
variables: SmallVec::new(),
423441
query_state,
424442
indices: FxHashMap::default(),
443+
binder_index: ty::INNERMOST,
425444
};
426445
let out_value = value.fold_with(&mut canonicalizer);
427446

@@ -567,7 +586,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
567586
kind: CanonicalVarKind::Ty(ty_kind),
568587
};
569588
let var = self.canonical_var(info, ty_var.into());
570-
self.tcx().mk_ty(ty::Bound(BoundTy::new(ty::INNERMOST, var)))
589+
self.tcx().mk_ty(ty::Bound(BoundTy::new(self.binder_index, var)))
571590
}
572591
}
573592
}

src/librustc/infer/canonical/query_response.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
433433
UnpackedKind::Type(result_value) => {
434434
// e.g., here `result_value` might be `?0` in the example above...
435435
if let ty::Bound(b) = result_value.sty {
436+
assert_eq!(b.index, ty::INNERMOST);
436437
// in which case we would set `canonical_vars[0]` to `Some(?U)`.
437438
opt_values[b.var] = Some(*original_value);
438439
}

src/librustc/infer/canonical/substitute.rs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,26 +69,48 @@ where
6969
} else if !value.has_type_flags(TypeFlags::HAS_CANONICAL_VARS) {
7070
value.clone()
7171
} else {
72-
value.fold_with(&mut CanonicalVarValuesSubst { tcx, var_values })
72+
value.fold_with(&mut CanonicalVarValuesSubst {
73+
tcx,
74+
var_values,
75+
binder_index: ty::INNERMOST,
76+
})
7377
}
7478
}
7579

7680
struct CanonicalVarValuesSubst<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
7781
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
7882
var_values: &'cx CanonicalVarValues<'tcx>,
83+
binder_index: ty::DebruijnIndex,
7984
}
8085

8186
impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for CanonicalVarValuesSubst<'cx, 'gcx, 'tcx> {
8287
fn tcx(&self) -> TyCtxt<'_, 'gcx, 'tcx> {
8388
self.tcx
8489
}
8590

91+
fn fold_binder<T>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T>
92+
where T: TypeFoldable<'tcx>
93+
{
94+
self.binder_index.shift_in(1);
95+
let t = t.super_fold_with(self);
96+
self.binder_index.shift_out(1);
97+
t
98+
}
99+
86100
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
87101
match t.sty {
88102
ty::Bound(b) => {
89-
match self.var_values.var_values[b.var].unpack() {
90-
UnpackedKind::Type(ty) => ty,
91-
r => bug!("{:?} is a type but value is {:?}", b, r),
103+
if b.index == self.binder_index {
104+
match self.var_values.var_values[b.var].unpack() {
105+
UnpackedKind::Type(ty) => ty::fold::shift_vars(
106+
self.tcx,
107+
self.binder_index.index() as u32,
108+
&ty
109+
),
110+
r => bug!("{:?} is a type but value is {:?}", b, r),
111+
}
112+
} else {
113+
t
92114
}
93115
}
94116
_ => {

src/librustc/ty/subst.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,10 @@ impl CanonicalUserSubsts<'tcx> {
556556
self.value.substs.iter().zip(BoundVar::new(0)..).all(|(kind, cvar)| {
557557
match kind.unpack() {
558558
UnpackedKind::Type(ty) => match ty.sty {
559-
ty::Bound(ref b) => cvar == b.var,
559+
ty::Bound(ref b) => {
560+
assert_eq!(b.index, ty::INNERMOST);
561+
cvar == b.var
562+
}
560563
_ => false,
561564
},
562565

0 commit comments

Comments
 (0)