Move folding into just projection cases

This commit is contained in:
Michael Goulet 2022-08-09 18:19:58 +00:00
parent ca7e3c4a83
commit d2667e4b71

View file

@ -194,7 +194,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
// wait to fold the substs. // wait to fold the substs.
// Wrap this in a closure so we don't accidentally return from the outer function // Wrap this in a closure so we don't accidentally return from the outer function
let mut res = (|| match *ty.kind() { let res = (|| match *ty.kind() {
// This is really important. While we *can* handle this, this has // This is really important. While we *can* handle this, this has
// severe performance implications for large opaque types with // severe performance implications for large opaque types with
// late-bound regions. See `issue-88862` benchmark. // late-bound regions. See `issue-88862` benchmark.
@ -266,7 +266,15 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
debug!("QueryNormalizer: result = {:#?}", result); debug!("QueryNormalizer: result = {:#?}", result);
debug!("QueryNormalizer: obligations = {:#?}", obligations); debug!("QueryNormalizer: obligations = {:#?}", obligations);
self.obligations.extend(obligations); self.obligations.extend(obligations);
Ok(result.normalized_ty)
let res = result.normalized_ty;
// `tcx.normalize_projection_ty` may normalize to a type that still has
// unevaluated consts, so keep normalizing here if that's the case.
if res != ty && res.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) {
Ok(res.try_super_fold_with(self)?)
} else {
Ok(res)
}
} }
ty::Projection(data) => { ty::Projection(data) => {
@ -305,25 +313,27 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
debug!("QueryNormalizer: result = {:#?}", result); debug!("QueryNormalizer: result = {:#?}", result);
debug!("QueryNormalizer: obligations = {:#?}", obligations); debug!("QueryNormalizer: obligations = {:#?}", obligations);
self.obligations.extend(obligations); self.obligations.extend(obligations);
Ok(crate::traits::project::PlaceholderReplacer::replace_placeholders(
let res = crate::traits::project::PlaceholderReplacer::replace_placeholders(
infcx, infcx,
mapped_regions, mapped_regions,
mapped_types, mapped_types,
mapped_consts, mapped_consts,
&self.universes, &self.universes,
result.normalized_ty, result.normalized_ty,
)) );
// `tcx.normalize_projection_ty` may normalize to a type that still has
// unevaluated consts, so keep normalizing here if that's the case.
if res != ty && res.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) {
Ok(res.try_super_fold_with(self)?)
} else {
Ok(res)
}
} }
_ => ty.try_super_fold_with(self), _ => ty.try_super_fold_with(self),
})()?; })()?;
// `tcx.normalize_projection_ty` may normalize to a type that still has
// unevaluated consts, so keep normalizing here if that's the case.
if res != ty && res.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) {
res = res.try_super_fold_with(self)?;
}
self.cache.insert(ty, res); self.cache.insert(ty, res);
Ok(res) Ok(res)
} }