Adapt TypeFolder
implementors to return a Result
Co-authored-by: Alan Egerton <eggyal@gmail.com>
This commit is contained in:
parent
6e3fa20b00
commit
6dc3dae46f
24 changed files with 387 additions and 305 deletions
|
@ -42,11 +42,11 @@ impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> {
|
|||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
if ty.needs_infer() { ty.super_fold_with(self) } else { self.tcx.erase_regions_ty(ty) }
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
if ty.needs_infer() { ty.super_fold_with(self) } else { Ok(self.tcx.erase_regions_ty(ty)) }
|
||||
}
|
||||
|
||||
fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T>
|
||||
fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> Result<ty::Binder<'tcx, T>, Self::Error>
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
|
@ -54,7 +54,7 @@ impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> {
|
|||
u.super_fold_with(self)
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
// because late-bound regions affect subtyping, we can't
|
||||
// erase the bound/free distinction, but we can replace
|
||||
// all free regions with 'erased.
|
||||
|
@ -64,12 +64,15 @@ impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> {
|
|||
// away. In codegen, they will always be erased to 'erased
|
||||
// whenever a substitution occurs.
|
||||
match *r {
|
||||
ty::ReLateBound(..) => r,
|
||||
_ => self.tcx.lifetimes.re_erased,
|
||||
ty::ReLateBound(..) => Ok(r),
|
||||
_ => Ok(self.tcx.lifetimes.re_erased),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> {
|
||||
fn fold_mir_const(
|
||||
&mut self,
|
||||
c: mir::ConstantKind<'tcx>,
|
||||
) -> Result<mir::ConstantKind<'tcx>, Self::Error> {
|
||||
c.super_fold_with(self)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -301,19 +301,22 @@ where
|
|||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
let t = ty.super_fold_with(self);
|
||||
(self.ty_op)(t)
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
let t = ty.super_fold_with(self)?;
|
||||
Ok((self.ty_op)(t))
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
let r = r.super_fold_with(self);
|
||||
(self.lt_op)(r)
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
let r = r.super_fold_with(self)?;
|
||||
Ok((self.lt_op)(r))
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
let ct = ct.super_fold_with(self);
|
||||
(self.ct_op)(ct)
|
||||
fn fold_const(
|
||||
&mut self,
|
||||
ct: &'tcx ty::Const<'tcx>,
|
||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||
let ct = ct.super_fold_with(self)?;
|
||||
Ok((self.ct_op)(ct))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -481,7 +484,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
|
|||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: ty::Binder<'tcx, T>,
|
||||
) -> ty::Binder<'tcx, T> {
|
||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
||||
self.current_index.shift_in(1);
|
||||
let t = t.super_fold_with(self);
|
||||
self.current_index.shift_out(1);
|
||||
|
@ -489,16 +492,16 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
|
|||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
match *r {
|
||||
ty::ReLateBound(debruijn, _) if debruijn < self.current_index => {
|
||||
debug!(?self.current_index, "skipped bound region");
|
||||
*self.skipped_regions = true;
|
||||
r
|
||||
Ok(r)
|
||||
}
|
||||
_ => {
|
||||
debug!(?self.current_index, "folding free region");
|
||||
(self.fold_region_fn)(r, self.current_index)
|
||||
Ok((self.fold_region_fn)(r, self.current_index))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -539,19 +542,19 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
|
|||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: ty::Binder<'tcx, T>,
|
||||
) -> ty::Binder<'tcx, T> {
|
||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
||||
self.current_index.shift_in(1);
|
||||
let t = t.super_fold_with(self);
|
||||
self.current_index.shift_out(1);
|
||||
t
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
match *t.kind() {
|
||||
ty::Bound(debruijn, bound_ty) if debruijn == self.current_index => {
|
||||
if let Some(fld_t) = self.fld_t.as_mut() {
|
||||
let ty = fld_t(bound_ty);
|
||||
return ty::fold::shift_vars(self.tcx, &ty, self.current_index.as_u32());
|
||||
return Ok(ty::fold::shift_vars(self.tcx, &ty, self.current_index.as_u32()));
|
||||
}
|
||||
}
|
||||
_ if t.has_vars_bound_at_or_above(self.current_index) => {
|
||||
|
@ -559,10 +562,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
|
|||
}
|
||||
_ => {}
|
||||
}
|
||||
t
|
||||
Ok(t)
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
match *r {
|
||||
ty::ReLateBound(debruijn, br) if debruijn == self.current_index => {
|
||||
if let Some(fld_r) = self.fld_r.as_mut() {
|
||||
|
@ -573,25 +576,28 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
|
|||
// debruijn index. Then we adjust it to the
|
||||
// correct depth.
|
||||
assert_eq!(debruijn1, ty::INNERMOST);
|
||||
self.tcx.mk_region(ty::ReLateBound(debruijn, br))
|
||||
Ok(self.tcx.mk_region(ty::ReLateBound(debruijn, br)))
|
||||
} else {
|
||||
region
|
||||
Ok(region)
|
||||
};
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
r
|
||||
Ok(r)
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
fn fold_const(
|
||||
&mut self,
|
||||
ct: &'tcx ty::Const<'tcx>,
|
||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||
match *ct {
|
||||
ty::Const { val: ty::ConstKind::Bound(debruijn, bound_const), ty }
|
||||
if debruijn == self.current_index =>
|
||||
{
|
||||
if let Some(fld_c) = self.fld_c.as_mut() {
|
||||
let ct = fld_c(bound_const, ty);
|
||||
return ty::fold::shift_vars(self.tcx, &ct, self.current_index.as_u32());
|
||||
return Ok(ty::fold::shift_vars(self.tcx, &ct, self.current_index.as_u32()));
|
||||
}
|
||||
}
|
||||
_ if ct.has_vars_bound_at_or_above(self.current_index) => {
|
||||
|
@ -599,7 +605,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
|
|||
}
|
||||
_ => {}
|
||||
}
|
||||
ct
|
||||
Ok(ct)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -949,36 +955,36 @@ impl TypeFolder<'tcx> for Shifter<'tcx> {
|
|||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: ty::Binder<'tcx, T>,
|
||||
) -> ty::Binder<'tcx, T> {
|
||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
||||
self.current_index.shift_in(1);
|
||||
let t = t.super_fold_with(self);
|
||||
self.current_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>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
match *r {
|
||||
ty::ReLateBound(debruijn, br) => {
|
||||
if self.amount == 0 || debruijn < self.current_index {
|
||||
r
|
||||
Ok(r)
|
||||
} else {
|
||||
let debruijn = debruijn.shifted_in(self.amount);
|
||||
let shifted = ty::ReLateBound(debruijn, br);
|
||||
self.tcx.mk_region(shifted)
|
||||
Ok(self.tcx.mk_region(shifted))
|
||||
}
|
||||
}
|
||||
_ => r,
|
||||
_ => Ok(r),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
match *ty.kind() {
|
||||
ty::Bound(debruijn, bound_ty) => {
|
||||
if self.amount == 0 || debruijn < self.current_index {
|
||||
ty
|
||||
Ok(ty)
|
||||
} else {
|
||||
let debruijn = debruijn.shifted_in(self.amount);
|
||||
self.tcx.mk_ty(ty::Bound(debruijn, bound_ty))
|
||||
Ok(self.tcx.mk_ty(ty::Bound(debruijn, bound_ty)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -986,13 +992,18 @@ impl TypeFolder<'tcx> for Shifter<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
fn fold_const(
|
||||
&mut self,
|
||||
ct: &'tcx ty::Const<'tcx>,
|
||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||
if let ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty } = *ct {
|
||||
if self.amount == 0 || debruijn < self.current_index {
|
||||
ct
|
||||
Ok(ct)
|
||||
} else {
|
||||
let debruijn = debruijn.shifted_in(self.amount);
|
||||
self.tcx.mk_const(ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty })
|
||||
Ok(self
|
||||
.tcx
|
||||
.mk_const(ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty }))
|
||||
}
|
||||
} else {
|
||||
ct.super_fold_with(self)
|
||||
|
@ -1295,19 +1306,22 @@ impl<'tcx> TypeFolder<'tcx> for ExposeDefaultConstSubstsFolder<'tcx> {
|
|||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
if ty.flags().intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) {
|
||||
ty.super_fold_with(self)
|
||||
} else {
|
||||
ty
|
||||
Ok(ty)
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_predicate(&mut self, pred: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
|
||||
fn fold_predicate(
|
||||
&mut self,
|
||||
pred: ty::Predicate<'tcx>,
|
||||
) -> Result<ty::Predicate<'tcx>, Self::Error> {
|
||||
if pred.inner.flags.intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) {
|
||||
pred.super_fold_with(self)
|
||||
} else {
|
||||
pred
|
||||
Ok(pred)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -622,7 +622,7 @@ fn polymorphize<'tcx>(
|
|||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
debug!("fold_ty: ty={:?}", ty);
|
||||
match ty.kind {
|
||||
ty::Closure(def_id, substs) => {
|
||||
|
@ -631,11 +631,11 @@ fn polymorphize<'tcx>(
|
|||
ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)),
|
||||
substs,
|
||||
);
|
||||
if substs == polymorphized_substs {
|
||||
Ok(if substs == polymorphized_substs {
|
||||
ty
|
||||
} else {
|
||||
self.tcx.mk_closure(def_id, polymorphized_substs)
|
||||
}
|
||||
})
|
||||
}
|
||||
ty::Generator(def_id, substs, movability) => {
|
||||
let polymorphized_substs = polymorphize(
|
||||
|
@ -643,11 +643,11 @@ fn polymorphize<'tcx>(
|
|||
ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)),
|
||||
substs,
|
||||
);
|
||||
if substs == polymorphized_substs {
|
||||
Ok(if substs == polymorphized_substs {
|
||||
ty
|
||||
} else {
|
||||
self.tcx.mk_generator(def_id, polymorphized_substs, movability)
|
||||
}
|
||||
})
|
||||
}
|
||||
_ => ty.super_fold_with(self),
|
||||
}
|
||||
|
|
|
@ -103,18 +103,24 @@ impl TypeFolder<'tcx> for NormalizeAfterErasingRegionsFolder<'tcx> {
|
|||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
self.normalize_generic_arg_after_erasing_regions(ty.into()).expect_ty()
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
Ok(self.normalize_generic_arg_after_erasing_regions(ty.into()).expect_ty())
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
self.normalize_generic_arg_after_erasing_regions(c.into()).expect_const()
|
||||
fn fold_const(
|
||||
&mut self,
|
||||
c: &'tcx ty::Const<'tcx>,
|
||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||
Ok(self.normalize_generic_arg_after_erasing_regions(c.into()).expect_const())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> {
|
||||
fn fold_mir_const(
|
||||
&mut self,
|
||||
c: mir::ConstantKind<'tcx>,
|
||||
) -> Result<mir::ConstantKind<'tcx>, Self::Error> {
|
||||
// FIXME: This *probably* needs canonicalization too!
|
||||
let arg = self.param_env.and(c);
|
||||
self.tcx.normalize_mir_const_after_erasing_regions(arg)
|
||||
Ok(self.tcx.normalize_mir_const_after_erasing_regions(arg))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2016,24 +2016,24 @@ impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
|
|||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: ty::Binder<'tcx, T>,
|
||||
) -> ty::Binder<'tcx, T> {
|
||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
||||
self.current_index.shift_in(1);
|
||||
let t = t.super_fold_with(self);
|
||||
self.current_index.shift_out(1);
|
||||
t
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
match *t.kind() {
|
||||
_ if t.has_vars_bound_at_or_above(self.current_index) || t.has_placeholders() => {
|
||||
return t.super_fold_with(self);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
t
|
||||
Ok(t)
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
let name = &mut self.name;
|
||||
let region = match *r {
|
||||
ty::ReLateBound(_, br) => self.region_map.entry(br).or_insert_with(|| name(br)),
|
||||
|
@ -2049,13 +2049,13 @@ impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
}
|
||||
_ => return r,
|
||||
_ => return Ok(r),
|
||||
};
|
||||
if let ty::ReLateBound(debruijn1, br) = *region {
|
||||
assert_eq!(debruijn1, ty::INNERMOST);
|
||||
self.tcx.mk_region(ty::ReLateBound(self.current_index, br))
|
||||
Ok(self.tcx.mk_region(ty::ReLateBound(self.current_index, br)))
|
||||
} else {
|
||||
region
|
||||
Ok(region)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1087,12 +1087,12 @@ impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
ty::Unevaluated {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
Ok(ty::Unevaluated {
|
||||
def: self.def,
|
||||
substs_: Some(self.substs(folder.tcx()).fold_with(folder)?),
|
||||
promoted: self.promoted,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
|
@ -1112,12 +1112,12 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx, ()> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
ty::Unevaluated {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
Ok(ty::Unevaluated {
|
||||
def: self.def,
|
||||
substs_: Some(self.substs(folder.tcx()).fold_with(folder)?),
|
||||
promoted: self.promoted,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
|
|
|
@ -465,14 +465,14 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
|
|||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: ty::Binder<'tcx, T>,
|
||||
) -> ty::Binder<'tcx, T> {
|
||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
||||
self.binders_passed += 1;
|
||||
let t = t.super_fold_with(self);
|
||||
let t = t.super_fold_with(self)?;
|
||||
self.binders_passed -= 1;
|
||||
t
|
||||
Ok(t)
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
// Note: This routine only handles regions that are bound on
|
||||
// type declarations and other outer declarations, not those
|
||||
// bound in *fn types*. Region substitution of the bound
|
||||
|
@ -482,7 +482,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
|
|||
ty::ReEarlyBound(data) => {
|
||||
let rk = self.substs.get(data.index as usize).map(|k| k.unpack());
|
||||
match rk {
|
||||
Some(GenericArgKind::Lifetime(lt)) => self.shift_region_through_binders(lt),
|
||||
Some(GenericArgKind::Lifetime(lt)) => Ok(self.shift_region_through_binders(lt)),
|
||||
_ => {
|
||||
let span = self.span.unwrap_or(DUMMY_SP);
|
||||
let msg = format!(
|
||||
|
@ -494,31 +494,41 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
}
|
||||
_ => r,
|
||||
_ => Ok(r),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
if !t.potentially_needs_subst() {
|
||||
return t;
|
||||
return Ok(t);
|
||||
}
|
||||
|
||||
match *t.kind() {
|
||||
ty::Param(p) => self.ty_for_param(p, t),
|
||||
ty::Param(p) => Ok(self.ty_for_param(p, t)),
|
||||
_ => t.super_fold_with(self),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
fn fold_const(
|
||||
&mut self,
|
||||
c: &'tcx ty::Const<'tcx>,
|
||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||
if !c.potentially_needs_subst() {
|
||||
return Ok(c);
|
||||
}
|
||||
|
||||
if let ty::ConstKind::Param(p) = c.val {
|
||||
self.const_for_param(p, c)
|
||||
Ok(self.const_for_param(p, c))
|
||||
} else {
|
||||
c.super_fold_with(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> {
|
||||
fn fold_mir_const(
|
||||
&mut self,
|
||||
c: mir::ConstantKind<'tcx>,
|
||||
) -> Result<mir::ConstantKind<'tcx>, Self::Error> {
|
||||
c.super_fold_with(self)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -605,13 +605,13 @@ impl<'tcx> TypeFolder<'tcx> for OpaqueTypeExpander<'tcx> {
|
|||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
if let ty::Opaque(def_id, substs) = t.kind {
|
||||
self.expand_opaque_ty(def_id, substs).unwrap_or(t)
|
||||
Ok(self.expand_opaque_ty(def_id, substs).unwrap_or(t))
|
||||
} else if t.has_opaque_types() {
|
||||
t.super_fold_with(self)
|
||||
} else {
|
||||
t
|
||||
Ok(t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1046,25 +1046,31 @@ pub fn fold_list<'tcx, F, T>(
|
|||
list: &'tcx ty::List<T>,
|
||||
folder: &mut F,
|
||||
intern: impl FnOnce(TyCtxt<'tcx>, &[T]) -> &'tcx ty::List<T>,
|
||||
) -> &'tcx ty::List<T>
|
||||
) -> Result<&'tcx ty::List<T>, F::Error>
|
||||
where
|
||||
F: TypeFolder<'tcx>,
|
||||
T: TypeFoldable<'tcx> + PartialEq + Copy,
|
||||
{
|
||||
let mut iter = list.iter();
|
||||
// Look for the first element that changed
|
||||
if let Some((i, new_t)) = iter.by_ref().enumerate().find_map(|(i, t)| {
|
||||
let new_t = t.fold_with(folder);
|
||||
if new_t == t { None } else { Some((i, new_t)) }
|
||||
match iter.by_ref().enumerate().find_map(|(i, t)| match t.fold_with(folder) {
|
||||
Ok(new_t) if new_t == t => None,
|
||||
new_t => Some((i, new_t)),
|
||||
}) {
|
||||
// An element changed, prepare to intern the resulting list
|
||||
let mut new_list = SmallVec::<[_; 8]>::with_capacity(list.len());
|
||||
new_list.extend_from_slice(&list[..i]);
|
||||
new_list.push(new_t);
|
||||
new_list.extend(iter.map(|t| t.fold_with(folder)));
|
||||
intern(folder.tcx(), &new_list)
|
||||
} else {
|
||||
list
|
||||
Some((i, Ok(new_t))) => {
|
||||
// An element changed, prepare to intern the resulting list
|
||||
let mut new_list = SmallVec::<[_; 8]>::with_capacity(list.len());
|
||||
new_list.extend_from_slice(&list[..i]);
|
||||
new_list.push(new_t);
|
||||
for t in iter {
|
||||
new_list.push(t.fold_with(folder)?)
|
||||
}
|
||||
Ok(intern(folder.tcx(), &new_list))
|
||||
}
|
||||
Some((_, Err(err))) => {
|
||||
return Err(err);
|
||||
}
|
||||
None => Ok(list),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue