diff options
| author | Michael Goulet <michael@errs.io> | 2022-08-09 18:19:58 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2022-08-09 18:19:58 +0000 |
| commit | d2667e4b718e3ded742a095e79eec92beb9bbbd6 (patch) | |
| tree | 0d18e723af9eb9f6bd2080cd3cfa39685de84553 | |
| parent | ca7e3c4a83e2adddf74d9a45301a84024ce1f730 (diff) | |
| download | rust-d2667e4b718e3ded742a095e79eec92beb9bbbd6.tar.gz rust-d2667e4b718e3ded742a095e79eec92beb9bbbd6.zip | |
Move folding into just projection cases
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/query/normalize.rs | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index b5e5f14064f..fa039f673dc 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -194,7 +194,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { // wait to fold the substs. // 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 // severe performance implications for large opaque types with // 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: obligations = {:#?}", 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) => { @@ -305,25 +313,27 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { debug!("QueryNormalizer: result = {:#?}", result); debug!("QueryNormalizer: obligations = {:#?}", obligations); self.obligations.extend(obligations); - Ok(crate::traits::project::PlaceholderReplacer::replace_placeholders( + + let res = crate::traits::project::PlaceholderReplacer::replace_placeholders( infcx, mapped_regions, mapped_types, mapped_consts, &self.universes, 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), })()?; - // `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); Ok(res) } |
