about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2022-08-09 18:19:58 +0000
committerMichael Goulet <michael@errs.io>2022-08-09 18:19:58 +0000
commitd2667e4b718e3ded742a095e79eec92beb9bbbd6 (patch)
tree0d18e723af9eb9f6bd2080cd3cfa39685de84553
parentca7e3c4a83e2adddf74d9a45301a84024ce1f730 (diff)
downloadrust-d2667e4b718e3ded742a095e79eec92beb9bbbd6.tar.gz
rust-d2667e4b718e3ded742a095e79eec92beb9bbbd6.zip
Move folding into just projection cases
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/normalize.rs30
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)
     }