Auto merge of #91318 - eggyal:reduce-boilerplate-around-infallible-folders, r=jackh726
Reduce boilerplate around infallible folders Further to https://github.com/rust-lang/rust/pull/91230#issuecomment-981059666 r? `@jackh726`
This commit is contained in:
commit
acbe4443cc
43 changed files with 900 additions and 736 deletions
|
@ -22,7 +22,6 @@
|
|||
#![feature(never_type)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(unwrap_infallible)]
|
||||
#![recursion_limit = "512"] // For rustdoc
|
||||
|
||||
#[macro_use]
|
||||
|
|
|
@ -65,16 +65,14 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
// Convert the type from the function into a type valid outside
|
||||
// the function, by replacing invalid regions with 'static,
|
||||
// after producing an error for each of them.
|
||||
let definition_ty = instantiated_ty
|
||||
.fold_with(&mut ReverseMapper::new(
|
||||
self.tcx,
|
||||
self.is_tainted_by_errors(),
|
||||
def_id,
|
||||
map,
|
||||
instantiated_ty,
|
||||
span,
|
||||
))
|
||||
.into_ok();
|
||||
let definition_ty = instantiated_ty.fold_with(&mut ReverseMapper::new(
|
||||
self.tcx,
|
||||
self.is_tainted_by_errors(),
|
||||
def_id,
|
||||
map,
|
||||
instantiated_ty,
|
||||
span,
|
||||
));
|
||||
debug!(?definition_ty);
|
||||
|
||||
definition_ty
|
||||
|
@ -125,14 +123,14 @@ impl ReverseMapper<'tcx> {
|
|||
) -> GenericArg<'tcx> {
|
||||
assert!(!self.map_missing_regions_to_empty);
|
||||
self.map_missing_regions_to_empty = true;
|
||||
let kind = kind.fold_with(self).into_ok();
|
||||
let kind = kind.fold_with(self);
|
||||
self.map_missing_regions_to_empty = false;
|
||||
kind
|
||||
}
|
||||
|
||||
fn fold_kind_normally(&mut self, kind: GenericArg<'tcx>) -> GenericArg<'tcx> {
|
||||
assert!(!self.map_missing_regions_to_empty);
|
||||
kind.fold_with(self).into_ok()
|
||||
kind.fold_with(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,17 +140,17 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
|||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
match r {
|
||||
// Ignore bound regions and `'static` regions that appear in the
|
||||
// type, we only need to remap regions that reference lifetimes
|
||||
// from the function declaraion.
|
||||
// This would ignore `'r` in a type like `for<'r> fn(&'r u32)`.
|
||||
ty::ReLateBound(..) | ty::ReStatic => return Ok(r),
|
||||
ty::ReLateBound(..) | ty::ReStatic => return r,
|
||||
|
||||
// If regions have been erased (by writeback), don't try to unerase
|
||||
// them.
|
||||
ty::ReErased => return Ok(r),
|
||||
ty::ReErased => return r,
|
||||
|
||||
// The regions that we expect from borrow checking.
|
||||
ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReEmpty(ty::UniverseIndex::ROOT) => {}
|
||||
|
@ -167,10 +165,10 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
|||
|
||||
let generics = self.tcx().generics_of(self.opaque_type_def_id);
|
||||
match self.map.get(&r.into()).map(|k| k.unpack()) {
|
||||
Some(GenericArgKind::Lifetime(r1)) => Ok(r1),
|
||||
Some(GenericArgKind::Lifetime(r1)) => r1,
|
||||
Some(u) => panic!("region mapped to unexpected kind: {:?}", u),
|
||||
None if self.map_missing_regions_to_empty || self.tainted_by_errors => {
|
||||
Ok(self.tcx.lifetimes.re_root_empty)
|
||||
self.tcx.lifetimes.re_root_empty
|
||||
}
|
||||
None if generics.parent.is_some() => {
|
||||
if let Some(hidden_ty) = self.hidden_ty.take() {
|
||||
|
@ -182,7 +180,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
|||
)
|
||||
.emit();
|
||||
}
|
||||
Ok(self.tcx.lifetimes.re_root_empty)
|
||||
self.tcx.lifetimes.re_root_empty
|
||||
}
|
||||
None => {
|
||||
self.tcx
|
||||
|
@ -198,12 +196,12 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
|||
)
|
||||
.emit();
|
||||
|
||||
Ok(self.tcx().lifetimes.re_static)
|
||||
self.tcx().lifetimes.re_static
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
match *ty.kind() {
|
||||
ty::Closure(def_id, substs) => {
|
||||
// I am a horrible monster and I pray for death. When
|
||||
|
@ -241,7 +239,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
|||
}
|
||||
}));
|
||||
|
||||
Ok(self.tcx.mk_closure(def_id, substs))
|
||||
self.tcx.mk_closure(def_id, substs)
|
||||
}
|
||||
|
||||
ty::Generator(def_id, substs, movability) => {
|
||||
|
@ -256,7 +254,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
|||
}
|
||||
}));
|
||||
|
||||
Ok(self.tcx.mk_generator(def_id, substs, movability))
|
||||
self.tcx.mk_generator(def_id, substs, movability)
|
||||
}
|
||||
|
||||
ty::Param(param) => {
|
||||
|
@ -264,7 +262,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
|||
match self.map.get(&ty.into()).map(|k| k.unpack()) {
|
||||
// Found it in the substitution list; replace with the parameter from the
|
||||
// opaque type.
|
||||
Some(GenericArgKind::Type(t1)) => Ok(t1),
|
||||
Some(GenericArgKind::Type(t1)) => t1,
|
||||
Some(u) => panic!("type mapped to unexpected kind: {:?}", u),
|
||||
None => {
|
||||
debug!(?param, ?self.map);
|
||||
|
@ -280,7 +278,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
|||
)
|
||||
.emit();
|
||||
|
||||
Ok(self.tcx().ty_error())
|
||||
self.tcx().ty_error()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -289,13 +287,10 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn fold_const(
|
||||
&mut self,
|
||||
ct: &'tcx ty::Const<'tcx>,
|
||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
trace!("checking const {:?}", ct);
|
||||
// Find a const parameter
|
||||
Ok(match ct.val {
|
||||
match ct.val {
|
||||
ty::ConstKind::Param(..) => {
|
||||
// Look it up in the substitution list.
|
||||
match self.map.get(&ct.into()).map(|k| k.unpack()) {
|
||||
|
@ -322,7 +317,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
|||
}
|
||||
|
||||
_ => ct,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -865,11 +865,11 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionReplacer<'a, 'tcx> {
|
|||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
Ok((match r {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
(match r {
|
||||
ty::ReVar(vid) => self.vid_to_region.get(vid).cloned(),
|
||||
_ => None,
|
||||
})
|
||||
.unwrap_or_else(|| r.super_fold_with(self).into_ok()))
|
||||
.unwrap_or_else(|| r.super_fold_with(self))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1898,15 +1898,15 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
self.infcx.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
if let ty::Param(ty::ParamTy { name, .. }) = *ty.kind() {
|
||||
let infcx = self.infcx;
|
||||
Ok(self.var_map.entry(ty).or_insert_with(|| {
|
||||
self.var_map.entry(ty).or_insert_with(|| {
|
||||
infcx.next_ty_var(TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::TypeParameterDefinition(name, None),
|
||||
span: DUMMY_SP,
|
||||
})
|
||||
}))
|
||||
})
|
||||
} else {
|
||||
ty.super_fold_with(self)
|
||||
}
|
||||
|
@ -1916,9 +1916,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
self.probe(|_| {
|
||||
let mut selcx = SelectionContext::new(self);
|
||||
|
||||
let cleaned_pred = pred
|
||||
.fold_with(&mut ParamToVarFolder { infcx: self, var_map: Default::default() })
|
||||
.into_ok();
|
||||
let cleaned_pred =
|
||||
pred.fold_with(&mut ParamToVarFolder { infcx: self, var_map: Default::default() });
|
||||
|
||||
let cleaned_pred = super::project::normalize(
|
||||
&mut selcx,
|
||||
|
|
|
@ -339,7 +339,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
|
|||
if !needs_normalization(&value, self.param_env.reveal()) {
|
||||
value
|
||||
} else {
|
||||
value.fold_with(self).into_ok()
|
||||
value.fold_with(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -352,16 +352,16 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
|||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: ty::Binder<'tcx, T>,
|
||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
||||
) -> ty::Binder<'tcx, T> {
|
||||
self.universes.push(None);
|
||||
let t = t.super_fold_with(self);
|
||||
self.universes.pop();
|
||||
t
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
if !needs_normalization(&ty, self.param_env.reveal()) {
|
||||
return Ok(ty);
|
||||
return ty;
|
||||
}
|
||||
|
||||
// We try to be a little clever here as a performance optimization in
|
||||
|
@ -387,14 +387,14 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
|||
// replace bound vars if the current type is a `Projection` and we need
|
||||
// to make sure we don't forget to fold the substs regardless.
|
||||
|
||||
Ok(match *ty.kind() {
|
||||
match *ty.kind() {
|
||||
// This is really important. While we *can* handle this, this has
|
||||
// severe performance implications for large opaque types with
|
||||
// late-bound regions. See `issue-88862` benchmark.
|
||||
ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
|
||||
// Only normalize `impl Trait` after type-checking, usually in codegen.
|
||||
match self.param_env.reveal() {
|
||||
Reveal::UserFacing => ty.super_fold_with(self)?,
|
||||
Reveal::UserFacing => ty.super_fold_with(self),
|
||||
|
||||
Reveal::All => {
|
||||
let recursion_limit = self.tcx().recursion_limit();
|
||||
|
@ -408,11 +408,11 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
|||
self.selcx.infcx().report_overflow_error(&obligation, true);
|
||||
}
|
||||
|
||||
let substs = substs.super_fold_with(self)?;
|
||||
let substs = substs.super_fold_with(self);
|
||||
let generic_ty = self.tcx().type_of(def_id);
|
||||
let concrete_ty = generic_ty.subst(self.tcx(), substs);
|
||||
self.depth += 1;
|
||||
let folded_ty = self.fold_ty(concrete_ty)?;
|
||||
let folded_ty = self.fold_ty(concrete_ty);
|
||||
self.depth -= 1;
|
||||
folded_ty
|
||||
}
|
||||
|
@ -426,7 +426,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
|||
// register an obligation to *later* project, since we know
|
||||
// there won't be bound vars there.
|
||||
|
||||
let data = data.super_fold_with(self)?;
|
||||
let data = data.super_fold_with(self);
|
||||
let normalized_ty = normalize_projection_type(
|
||||
self.selcx,
|
||||
self.param_env,
|
||||
|
@ -461,7 +461,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
|||
let infcx = self.selcx.infcx();
|
||||
let (data, mapped_regions, mapped_types, mapped_consts) =
|
||||
BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data);
|
||||
let data = data.super_fold_with(self)?;
|
||||
let data = data.super_fold_with(self);
|
||||
let normalized_ty = opt_normalize_projection_type(
|
||||
self.selcx,
|
||||
self.param_env,
|
||||
|
@ -473,18 +473,16 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
|||
.ok()
|
||||
.flatten()
|
||||
.map(|normalized_ty| {
|
||||
Ok({
|
||||
PlaceholderReplacer::replace_placeholders(
|
||||
infcx,
|
||||
mapped_regions,
|
||||
mapped_types,
|
||||
mapped_consts,
|
||||
&self.universes,
|
||||
normalized_ty,
|
||||
)
|
||||
})
|
||||
PlaceholderReplacer::replace_placeholders(
|
||||
infcx,
|
||||
mapped_regions,
|
||||
mapped_types,
|
||||
mapped_consts,
|
||||
&self.universes,
|
||||
normalized_ty,
|
||||
)
|
||||
})
|
||||
.unwrap_or_else(|| ty.super_fold_with(self))?;
|
||||
.unwrap_or_else(|| ty.super_fold_with(self));
|
||||
|
||||
debug!(
|
||||
?self.depth,
|
||||
|
@ -496,19 +494,16 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
|||
normalized_ty
|
||||
}
|
||||
|
||||
_ => ty.super_fold_with(self)?,
|
||||
})
|
||||
_ => ty.super_fold_with(self),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_const(
|
||||
&mut self,
|
||||
constant: &'tcx ty::Const<'tcx>,
|
||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||
fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
if self.selcx.tcx().lazy_normalization() {
|
||||
Ok(constant)
|
||||
constant
|
||||
} else {
|
||||
let constant = constant.super_fold_with(self)?;
|
||||
Ok(constant.eval(self.selcx.tcx(), self.param_env))
|
||||
let constant = constant.super_fold_with(self);
|
||||
constant.eval(self.selcx.tcx(), self.param_env)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -555,7 +550,7 @@ impl<'me, 'tcx> BoundVarReplacer<'me, 'tcx> {
|
|||
universe_indices,
|
||||
};
|
||||
|
||||
let value = value.super_fold_with(&mut replacer).into_ok();
|
||||
let value = value.super_fold_with(&mut replacer);
|
||||
|
||||
(value, replacer.mapped_regions, replacer.mapped_types, replacer.mapped_consts)
|
||||
}
|
||||
|
@ -582,14 +577,14 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> {
|
|||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: ty::Binder<'tcx, T>,
|
||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
||||
) -> ty::Binder<'tcx, T> {
|
||||
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>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
match *r {
|
||||
ty::ReLateBound(debruijn, _)
|
||||
if debruijn.as_usize() + 1
|
||||
|
@ -601,13 +596,13 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> {
|
|||
let universe = self.universe_for(debruijn);
|
||||
let p = ty::PlaceholderRegion { universe, name: br.kind };
|
||||
self.mapped_regions.insert(p, br);
|
||||
Ok(self.infcx.tcx.mk_region(ty::RePlaceholder(p)))
|
||||
self.infcx.tcx.mk_region(ty::RePlaceholder(p))
|
||||
}
|
||||
_ => Ok(r),
|
||||
_ => r,
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
match *t.kind() {
|
||||
ty::Bound(debruijn, _)
|
||||
if debruijn.as_usize() + 1
|
||||
|
@ -619,17 +614,14 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> {
|
|||
let universe = self.universe_for(debruijn);
|
||||
let p = ty::PlaceholderType { universe, name: bound_ty.var };
|
||||
self.mapped_types.insert(p, bound_ty);
|
||||
Ok(self.infcx.tcx.mk_ty(ty::Placeholder(p)))
|
||||
self.infcx.tcx.mk_ty(ty::Placeholder(p))
|
||||
}
|
||||
_ if t.has_vars_bound_at_or_above(self.current_index) => t.super_fold_with(self),
|
||||
_ => Ok(t),
|
||||
_ => t,
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_const(
|
||||
&mut self,
|
||||
ct: &'tcx ty::Const<'tcx>,
|
||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
match *ct {
|
||||
ty::Const { val: ty::ConstKind::Bound(debruijn, _), ty: _ }
|
||||
if debruijn.as_usize() + 1
|
||||
|
@ -646,10 +638,10 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> {
|
|||
name: ty::BoundConst { var: bound_const, ty },
|
||||
};
|
||||
self.mapped_consts.insert(p, bound_const);
|
||||
Ok(self.infcx.tcx.mk_const(ty::Const { val: ty::ConstKind::Placeholder(p), ty }))
|
||||
self.infcx.tcx.mk_const(ty::Const { val: ty::ConstKind::Placeholder(p), ty })
|
||||
}
|
||||
_ if ct.has_vars_bound_at_or_above(self.current_index) => ct.super_fold_with(self),
|
||||
_ => Ok(ct),
|
||||
_ => ct,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -681,7 +673,7 @@ impl<'me, 'tcx> PlaceholderReplacer<'me, 'tcx> {
|
|||
universe_indices,
|
||||
current_index: ty::INNERMOST,
|
||||
};
|
||||
value.super_fold_with(&mut replacer).into_ok()
|
||||
value.super_fold_with(&mut replacer)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -693,9 +685,9 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> {
|
|||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: ty::Binder<'tcx, T>,
|
||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
||||
) -> ty::Binder<'tcx, T> {
|
||||
if !t.has_placeholders() && !t.has_infer_regions() {
|
||||
return Ok(t);
|
||||
return t;
|
||||
}
|
||||
self.current_index.shift_in(1);
|
||||
let t = t.super_fold_with(self);
|
||||
|
@ -703,7 +695,7 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> {
|
|||
t
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r0: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
fn fold_region(&mut self, r0: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
let r1 = match r0 {
|
||||
ty::ReVar(_) => self
|
||||
.infcx
|
||||
|
@ -737,10 +729,10 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> {
|
|||
|
||||
debug!(?r0, ?r1, ?r2, "fold_region");
|
||||
|
||||
Ok(r2)
|
||||
r2
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
match *ty.kind() {
|
||||
ty::Placeholder(p) => {
|
||||
let replace_var = self.mapped_types.get(&p);
|
||||
|
@ -754,21 +746,18 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> {
|
|||
let db = ty::DebruijnIndex::from_usize(
|
||||
self.universe_indices.len() - index + self.current_index.as_usize() - 1,
|
||||
);
|
||||
Ok(self.tcx().mk_ty(ty::Bound(db, *replace_var)))
|
||||
self.tcx().mk_ty(ty::Bound(db, *replace_var))
|
||||
}
|
||||
None => Ok(ty),
|
||||
None => ty,
|
||||
}
|
||||
}
|
||||
|
||||
_ if ty.has_placeholders() || ty.has_infer_regions() => ty.super_fold_with(self),
|
||||
_ => Ok(ty),
|
||||
_ => ty,
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_const(
|
||||
&mut self,
|
||||
ct: &'tcx ty::Const<'tcx>,
|
||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
if let ty::Const { val: ty::ConstKind::Placeholder(p), ty } = *ct {
|
||||
let replace_var = self.mapped_consts.get(&p);
|
||||
match replace_var {
|
||||
|
@ -781,11 +770,10 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> {
|
|||
let db = ty::DebruijnIndex::from_usize(
|
||||
self.universe_indices.len() - index + self.current_index.as_usize() - 1,
|
||||
);
|
||||
Ok(self
|
||||
.tcx()
|
||||
.mk_const(ty::Const { val: ty::ConstKind::Bound(db, *replace_var), ty }))
|
||||
self.tcx()
|
||||
.mk_const(ty::Const { val: ty::ConstKind::Bound(db, *replace_var), ty })
|
||||
}
|
||||
None => Ok(ct),
|
||||
None => ct,
|
||||
}
|
||||
} else {
|
||||
ct.super_fold_with(self)
|
||||
|
@ -1546,8 +1534,7 @@ fn confirm_candidate<'cx, 'tcx>(
|
|||
// when possible for this to work. See `auto-trait-projection-recursion.rs`
|
||||
// for a case where this matters.
|
||||
if progress.ty.has_infer_regions() {
|
||||
progress.ty =
|
||||
OpportunisticRegionResolver::new(selcx.infcx()).fold_ty(progress.ty).into_ok();
|
||||
progress.ty = OpportunisticRegionResolver::new(selcx.infcx()).fold_ty(progress.ty);
|
||||
}
|
||||
progress
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use rustc_data_structures::sso::SsoHashMap;
|
|||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_infer::traits::Normalized;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
|
||||
use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder};
|
||||
use rustc_middle::ty::subst::Subst;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor};
|
||||
|
||||
|
@ -87,7 +87,7 @@ impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> {
|
|||
normalizer.universes.extend((0..max_visitor.escaping).map(|_| None));
|
||||
}
|
||||
}
|
||||
let result = value.fold_with(&mut normalizer);
|
||||
let result = value.try_fold_with(&mut normalizer);
|
||||
info!(
|
||||
"normalize::<{}>: result={:?} with {} obligations",
|
||||
std::any::type_name::<T>(),
|
||||
|
@ -176,19 +176,21 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
|||
fn tcx<'c>(&'c self) -> TyCtxt<'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||
impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||
fn try_fold_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: ty::Binder<'tcx, T>,
|
||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
||||
self.universes.push(None);
|
||||
let t = t.super_fold_with(self);
|
||||
let t = t.try_super_fold_with(self);
|
||||
self.universes.pop();
|
||||
t
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
if !needs_normalization(&ty, self.param_env.reveal()) {
|
||||
return Ok(ty);
|
||||
}
|
||||
|
@ -208,10 +210,10 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
|||
ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
|
||||
// Only normalize `impl Trait` after type-checking, usually in codegen.
|
||||
match self.param_env.reveal() {
|
||||
Reveal::UserFacing => ty.super_fold_with(self),
|
||||
Reveal::UserFacing => ty.try_super_fold_with(self),
|
||||
|
||||
Reveal::All => {
|
||||
let substs = substs.super_fold_with(self)?;
|
||||
let substs = substs.try_super_fold_with(self)?;
|
||||
let recursion_limit = self.tcx().recursion_limit();
|
||||
if !recursion_limit.value_within_limit(self.anon_depth) {
|
||||
let obligation = Obligation::with_depth(
|
||||
|
@ -236,7 +238,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
|||
ty
|
||||
);
|
||||
}
|
||||
let folded_ty = ensure_sufficient_stack(|| self.fold_ty(concrete_ty));
|
||||
let folded_ty = ensure_sufficient_stack(|| self.try_fold_ty(concrete_ty));
|
||||
self.anon_depth -= 1;
|
||||
folded_ty
|
||||
}
|
||||
|
@ -248,7 +250,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
|||
// we don't need to replace them with placeholders (see branch below).
|
||||
|
||||
let tcx = self.infcx.tcx;
|
||||
let data = data.super_fold_with(self)?;
|
||||
let data = data.try_super_fold_with(self)?;
|
||||
|
||||
let mut orig_values = OriginalQueryValues::default();
|
||||
// HACK(matthewjasper) `'static` is special-cased in selection,
|
||||
|
@ -287,7 +289,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
|||
&mut self.universes,
|
||||
data,
|
||||
);
|
||||
let data = data.super_fold_with(self)?;
|
||||
let data = data.try_super_fold_with(self)?;
|
||||
|
||||
let mut orig_values = OriginalQueryValues::default();
|
||||
// HACK(matthewjasper) `'static` is special-cased in selection,
|
||||
|
@ -322,24 +324,24 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
|||
))
|
||||
}
|
||||
|
||||
_ => ty.super_fold_with(self),
|
||||
_ => ty.try_super_fold_with(self),
|
||||
})()?;
|
||||
self.cache.insert(ty, res);
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
fn fold_const(
|
||||
fn try_fold_const(
|
||||
&mut self,
|
||||
constant: &'tcx ty::Const<'tcx>,
|
||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||
let constant = constant.super_fold_with(self)?;
|
||||
let constant = constant.try_super_fold_with(self)?;
|
||||
Ok(constant.eval(self.infcx.tcx, self.param_env))
|
||||
}
|
||||
|
||||
fn fold_mir_const(
|
||||
fn try_fold_mir_const(
|
||||
&mut self,
|
||||
constant: mir::ConstantKind<'tcx>,
|
||||
) -> Result<mir::ConstantKind<'tcx>, Self::Error> {
|
||||
constant.super_fold_with(self)
|
||||
constant.try_super_fold_with(self)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2154,7 +2154,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
previous_stack: TraitObligationStackList<'o, 'tcx>,
|
||||
obligation: &'o TraitObligation<'tcx>,
|
||||
) -> TraitObligationStack<'o, 'tcx> {
|
||||
let fresh_trait_pred = obligation.predicate.fold_with(&mut self.freshener).into_ok();
|
||||
let fresh_trait_pred = obligation.predicate.fold_with(&mut self.freshener);
|
||||
|
||||
let dfn = previous_stack.cache.next_dfn();
|
||||
let depth = previous_stack.depth() + 1;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue