simplify some binder shifting logic

This commit is contained in:
Michael Goulet 2022-11-26 05:11:06 +00:00
parent aff003becd
commit 61e185b5d0

View file

@ -407,6 +407,7 @@ where
match *t.kind() { match *t.kind() {
ty::Bound(debruijn, bound_ty) if debruijn == self.current_index => { ty::Bound(debruijn, bound_ty) if debruijn == self.current_index => {
let ty = self.delegate.replace_ty(bound_ty); let ty = self.delegate.replace_ty(bound_ty);
debug_assert!(!ty.has_vars_bound_above(ty::INNERMOST));
ty::fold::shift_vars(self.tcx, ty, self.current_index.as_u32()) ty::fold::shift_vars(self.tcx, ty, self.current_index.as_u32())
} }
_ if t.has_vars_bound_at_or_above(self.current_index) => t.super_fold_with(self), _ if t.has_vars_bound_at_or_above(self.current_index) => t.super_fold_with(self),
@ -437,6 +438,7 @@ where
match ct.kind() { match ct.kind() {
ty::ConstKind::Bound(debruijn, bound_const) if debruijn == self.current_index => { ty::ConstKind::Bound(debruijn, bound_const) if debruijn == self.current_index => {
let ct = self.delegate.replace_const(bound_const, ct.ty()); let ct = self.delegate.replace_const(bound_const, ct.ty());
debug_assert!(!ct.has_vars_bound_above(ty::INNERMOST));
ty::fold::shift_vars(self.tcx, ct, self.current_index.as_u32()) ty::fold::shift_vars(self.tcx, ct, self.current_index.as_u32())
} }
_ => ct.super_fold_with(self), _ => ct.super_fold_with(self),
@ -697,14 +699,10 @@ impl<'tcx> TypeFolder<'tcx> for Shifter<'tcx> {
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(debruijn, br) => { ty::ReLateBound(debruijn, br) if debruijn >= self.current_index => {
if self.amount == 0 || debruijn < self.current_index { let debruijn = debruijn.shifted_in(self.amount);
r let shifted = ty::ReLateBound(debruijn, br);
} else { self.tcx.mk_region(shifted)
let debruijn = debruijn.shifted_in(self.amount);
let shifted = ty::ReLateBound(debruijn, br);
self.tcx.mk_region(shifted)
}
} }
_ => r, _ => r,
} }
@ -712,31 +710,30 @@ impl<'tcx> TypeFolder<'tcx> for Shifter<'tcx> {
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
match *ty.kind() { match *ty.kind() {
ty::Bound(debruijn, bound_ty) => { ty::Bound(debruijn, bound_ty) if debruijn >= self.current_index => {
if self.amount == 0 || debruijn < self.current_index { let debruijn = debruijn.shifted_in(self.amount);
ty self.tcx.mk_ty(ty::Bound(debruijn, bound_ty))
} else {
let debruijn = debruijn.shifted_in(self.amount);
self.tcx.mk_ty(ty::Bound(debruijn, bound_ty))
}
} }
_ => ty.super_fold_with(self), _ if ty.has_vars_bound_at_or_above(self.current_index) => ty.super_fold_with(self),
_ => ty,
} }
} }
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
if let ty::ConstKind::Bound(debruijn, bound_ct) = ct.kind() { if let ty::ConstKind::Bound(debruijn, bound_ct) = ct.kind()
if self.amount == 0 || debruijn < self.current_index { && debruijn >= self.current_index
ct {
} else { let debruijn = debruijn.shifted_in(self.amount);
let debruijn = debruijn.shifted_in(self.amount); self.tcx.mk_const(ty::ConstKind::Bound(debruijn, bound_ct), ct.ty())
self.tcx.mk_const(ty::ConstKind::Bound(debruijn, bound_ct), ct.ty())
}
} else { } else {
ct.super_fold_with(self) ct.super_fold_with(self)
} }
} }
fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
if p.has_vars_bound_at_or_above(self.current_index) { p.super_fold_with(self) } else { p }
}
} }
pub fn shift_region<'tcx>( pub fn shift_region<'tcx>(
@ -758,5 +755,9 @@ where
{ {
debug!("shift_vars(value={:?}, amount={})", value, amount); debug!("shift_vars(value={:?}, amount={})", value, amount);
if amount == 0 || !value.has_escaping_bound_vars() {
return value;
}
value.fold_with(&mut Shifter::new(tcx, amount)) value.fold_with(&mut Shifter::new(tcx, amount))
} }