mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 00:03:43 +00:00
Adjust bound tys indices in canonicalization
This commit is contained in:
parent
ee569c796d
commit
1f8de94f3b
@ -280,6 +280,8 @@ struct Canonicalizer<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
|
|||||||
indices: FxHashMap<Kind<'tcx>, BoundVar>,
|
indices: FxHashMap<Kind<'tcx>, BoundVar>,
|
||||||
canonicalize_region_mode: &'cx dyn CanonicalizeRegionMode,
|
canonicalize_region_mode: &'cx dyn CanonicalizeRegionMode,
|
||||||
needs_canonical_flags: TypeFlags,
|
needs_canonical_flags: TypeFlags,
|
||||||
|
|
||||||
|
binder_index: ty::DebruijnIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx> {
|
impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx> {
|
||||||
@ -287,11 +289,23 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
|
|||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fold_binder<T>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T>
|
||||||
|
where T: TypeFoldable<'tcx>
|
||||||
|
{
|
||||||
|
self.binder_index.shift_in(1);
|
||||||
|
let t = t.super_fold_with(self);
|
||||||
|
self.binder_index.shift_out(1);
|
||||||
|
t
|
||||||
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
match *r {
|
match *r {
|
||||||
ty::ReLateBound(..) => {
|
ty::ReLateBound(index, ..) => {
|
||||||
// leave bound regions alone
|
if index >= self.binder_index {
|
||||||
r
|
bug!("escaping late bound region during canonicalization")
|
||||||
|
} else {
|
||||||
|
r
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ReVar(vid) => {
|
ty::ReVar(vid) => {
|
||||||
@ -337,8 +351,12 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
|
|||||||
bug!("encountered a fresh type during canonicalization")
|
bug!("encountered a fresh type during canonicalization")
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Bound(_) => {
|
ty::Bound(bound_ty) => {
|
||||||
bug!("encountered a bound type during canonicalization")
|
if bound_ty.index >= self.binder_index {
|
||||||
|
bug!("escaping bound type during canonicalization")
|
||||||
|
} else {
|
||||||
|
t
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Closure(..)
|
ty::Closure(..)
|
||||||
@ -422,6 +440,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
|
|||||||
variables: SmallVec::new(),
|
variables: SmallVec::new(),
|
||||||
query_state,
|
query_state,
|
||||||
indices: FxHashMap::default(),
|
indices: FxHashMap::default(),
|
||||||
|
binder_index: ty::INNERMOST,
|
||||||
};
|
};
|
||||||
let out_value = value.fold_with(&mut canonicalizer);
|
let out_value = value.fold_with(&mut canonicalizer);
|
||||||
|
|
||||||
@ -567,7 +586,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
|
|||||||
kind: CanonicalVarKind::Ty(ty_kind),
|
kind: CanonicalVarKind::Ty(ty_kind),
|
||||||
};
|
};
|
||||||
let var = self.canonical_var(info, ty_var.into());
|
let var = self.canonical_var(info, ty_var.into());
|
||||||
self.tcx().mk_ty(ty::Bound(BoundTy::new(ty::INNERMOST, var)))
|
self.tcx().mk_ty(ty::Bound(BoundTy::new(self.binder_index, var)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -433,6 +433,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||||||
UnpackedKind::Type(result_value) => {
|
UnpackedKind::Type(result_value) => {
|
||||||
// e.g., here `result_value` might be `?0` in the example above...
|
// e.g., here `result_value` might be `?0` in the example above...
|
||||||
if let ty::Bound(b) = result_value.sty {
|
if let ty::Bound(b) = result_value.sty {
|
||||||
|
assert_eq!(b.index, ty::INNERMOST);
|
||||||
// in which case we would set `canonical_vars[0]` to `Some(?U)`.
|
// in which case we would set `canonical_vars[0]` to `Some(?U)`.
|
||||||
opt_values[b.var] = Some(*original_value);
|
opt_values[b.var] = Some(*original_value);
|
||||||
}
|
}
|
||||||
|
@ -69,13 +69,18 @@ where
|
|||||||
} else if !value.has_type_flags(TypeFlags::HAS_CANONICAL_VARS) {
|
} else if !value.has_type_flags(TypeFlags::HAS_CANONICAL_VARS) {
|
||||||
value.clone()
|
value.clone()
|
||||||
} else {
|
} else {
|
||||||
value.fold_with(&mut CanonicalVarValuesSubst { tcx, var_values })
|
value.fold_with(&mut CanonicalVarValuesSubst {
|
||||||
|
tcx,
|
||||||
|
var_values,
|
||||||
|
binder_index: ty::INNERMOST,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CanonicalVarValuesSubst<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
|
struct CanonicalVarValuesSubst<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
|
||||||
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
|
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
|
||||||
var_values: &'cx CanonicalVarValues<'tcx>,
|
var_values: &'cx CanonicalVarValues<'tcx>,
|
||||||
|
binder_index: ty::DebruijnIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for CanonicalVarValuesSubst<'cx, 'gcx, 'tcx> {
|
impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for CanonicalVarValuesSubst<'cx, 'gcx, 'tcx> {
|
||||||
@ -83,12 +88,29 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for CanonicalVarValuesSubst<'cx, 'g
|
|||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fold_binder<T>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T>
|
||||||
|
where T: TypeFoldable<'tcx>
|
||||||
|
{
|
||||||
|
self.binder_index.shift_in(1);
|
||||||
|
let t = t.super_fold_with(self);
|
||||||
|
self.binder_index.shift_out(1);
|
||||||
|
t
|
||||||
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
match t.sty {
|
match t.sty {
|
||||||
ty::Bound(b) => {
|
ty::Bound(b) => {
|
||||||
match self.var_values.var_values[b.var].unpack() {
|
if b.index == self.binder_index {
|
||||||
UnpackedKind::Type(ty) => ty,
|
match self.var_values.var_values[b.var].unpack() {
|
||||||
r => bug!("{:?} is a type but value is {:?}", b, r),
|
UnpackedKind::Type(ty) => ty::fold::shift_vars(
|
||||||
|
self.tcx,
|
||||||
|
self.binder_index.index() as u32,
|
||||||
|
&ty
|
||||||
|
),
|
||||||
|
r => bug!("{:?} is a type but value is {:?}", b, r),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -556,7 +556,10 @@ impl CanonicalUserSubsts<'tcx> {
|
|||||||
self.value.substs.iter().zip(BoundVar::new(0)..).all(|(kind, cvar)| {
|
self.value.substs.iter().zip(BoundVar::new(0)..).all(|(kind, cvar)| {
|
||||||
match kind.unpack() {
|
match kind.unpack() {
|
||||||
UnpackedKind::Type(ty) => match ty.sty {
|
UnpackedKind::Type(ty) => match ty.sty {
|
||||||
ty::Bound(ref b) => cvar == b.var,
|
ty::Bound(ref b) => {
|
||||||
|
assert_eq!(b.index, ty::INNERMOST);
|
||||||
|
cvar == b.var
|
||||||
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user