about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-01-09 09:20:33 +0000
committerbors <bors@rust-lang.org>2024-01-09 09:20:33 +0000
commitbe00c5a9b89161b7f45ba80340f709e8e41122f9 (patch)
tree0f0d5c14cd352eb9a9b6d6a39434a2f50186827f
parentdc641039d2b3f5c0894694e4b45f7c3951030685 (diff)
parent707c4f967e4d6c68252eb784844a10a3613bde61 (diff)
downloadrust-be00c5a9b89161b7f45ba80340f709e8e41122f9.tar.gz
rust-be00c5a9b89161b7f45ba80340f709e8e41122f9.zip
Auto merge of #118968 - aliemjay:canon-static, r=lcnr
unify query canonicalization mode

Exclude from canonicalization only the static lifetimes that appear in the param env because of #118965 . Any other occurrence can be canonicalized safely AFAICT.

r? `@lcnr`
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs83
-rw-r--r--compiler/rustc_trait_selection/src/traits/outlives_bounds.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/normalize.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs7
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-cache-issue-54302.stderr2
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-59311.stderr2
-rw-r--r--tests/ui/nll/issue-54302.stderr2
8 files changed, 35 insertions, 75 deletions
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index 69a96448467..c156c13c962 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -41,7 +41,33 @@ impl<'tcx> InferCtxt<'tcx> {
     where
         V: TypeFoldable<TyCtxt<'tcx>>,
     {
-        self.canonicalize_query_with_mode(value, query_state, &CanonicalizeAllFreeRegions)
+        let (param_env, value) = value.into_parts();
+        let param_env = self.tcx.canonical_param_env_cache.get_or_insert(
+            self.tcx,
+            param_env,
+            query_state,
+            |tcx, param_env, query_state| {
+                // FIXME(#118965): We don't canonicalize the static lifetimes that appear in the
+                // `param_env` beacause they are treated differently by trait selection.
+                Canonicalizer::canonicalize(
+                    param_env,
+                    None,
+                    tcx,
+                    &CanonicalizeFreeRegionsOtherThanStatic,
+                    query_state,
+                )
+            },
+        );
+
+        Canonicalizer::canonicalize_with_base(
+            param_env,
+            value,
+            Some(self),
+            self.tcx,
+            &CanonicalizeAllFreeRegions,
+            query_state,
+        )
+        .unchecked_map(|(param_env, value)| param_env.and(value))
     }
 
     /// Canonicalizes a query *response* `V`. When we canonicalize a
@@ -96,61 +122,6 @@ impl<'tcx> InferCtxt<'tcx> {
             &mut query_state,
         )
     }
-
-    /// A variant of `canonicalize_query` that does not
-    /// canonicalize `'static`. This is useful when
-    /// the query implementation can perform more efficient
-    /// handling of `'static` regions (e.g. trait evaluation).
-    pub fn canonicalize_query_keep_static<V>(
-        &self,
-        value: ty::ParamEnvAnd<'tcx, V>,
-        query_state: &mut OriginalQueryValues<'tcx>,
-    ) -> Canonical<'tcx, ty::ParamEnvAnd<'tcx, V>>
-    where
-        V: TypeFoldable<TyCtxt<'tcx>>,
-    {
-        self.canonicalize_query_with_mode(
-            value,
-            query_state,
-            &CanonicalizeFreeRegionsOtherThanStatic,
-        )
-    }
-
-    fn canonicalize_query_with_mode<V>(
-        &self,
-        value: ty::ParamEnvAnd<'tcx, V>,
-        query_state: &mut OriginalQueryValues<'tcx>,
-        canonicalize_region_mode: &dyn CanonicalizeMode,
-    ) -> Canonical<'tcx, ty::ParamEnvAnd<'tcx, V>>
-    where
-        V: TypeFoldable<TyCtxt<'tcx>>,
-    {
-        let (param_env, value) = value.into_parts();
-        let base = self.tcx.canonical_param_env_cache.get_or_insert(
-            self.tcx,
-            param_env,
-            query_state,
-            |tcx, param_env, query_state| {
-                Canonicalizer::canonicalize(
-                    param_env,
-                    None,
-                    tcx,
-                    &CanonicalizeFreeRegionsOtherThanStatic,
-                    query_state,
-                )
-            },
-        );
-
-        Canonicalizer::canonicalize_with_base(
-            base,
-            value,
-            Some(self),
-            self.tcx,
-            canonicalize_region_mode,
-            query_state,
-        )
-        .unchecked_map(|(param_env, value)| param_env.and(value))
-    }
 }
 
 /// Controls how we canonicalize "free regions" that are not inference
diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
index 9749ff9cbc1..5b349d576b6 100644
--- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
+++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
@@ -65,8 +65,7 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> {
         assert!(!ty.has_non_region_infer());
 
         let mut canonical_var_values = OriginalQueryValues::default();
-        let canonical_ty =
-            self.canonicalize_query_keep_static(param_env.and(ty), &mut canonical_var_values);
+        let canonical_ty = self.canonicalize_query(param_env.and(ty), &mut canonical_var_values);
         let Ok(canonical_result) = self.tcx.implied_outlives_bounds(canonical_ty) else {
             return vec![];
         };
diff --git a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
index d812d537d8c..31e34096fb0 100644
--- a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
@@ -87,10 +87,8 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
             })
         } else {
             assert!(!self.intercrate);
-            let c_pred = self.canonicalize_query_keep_static(
-                param_env.and(obligation.predicate),
-                &mut _orig_values,
-            );
+            let c_pred =
+                self.canonicalize_query(param_env.and(obligation.predicate), &mut _orig_values);
             self.tcx.at(obligation.cause.span()).evaluate_obligation(c_pred)
         }
     }
diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
index 425c4fbe9c5..d5f98db2c93 100644
--- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
@@ -272,10 +272,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx>
                 let data = data.try_fold_with(self)?;
 
                 let mut orig_values = OriginalQueryValues::default();
-                // HACK(matthewjasper) `'static` is special-cased in selection,
-                // so we cannot canonicalize it.
-                let c_data = infcx
-                    .canonicalize_query_keep_static(self.param_env.and(data), &mut orig_values);
+                let c_data = infcx.canonicalize_query(self.param_env.and(data), &mut orig_values);
                 debug!("QueryNormalizer: c_data = {:#?}", c_data);
                 debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
                 let result = match kind {
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
index cab2a62ed7e..957de925dd3 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
@@ -111,14 +111,9 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable<TyCtxt<'tcx>> + 't
             return Ok((result, None, vec![], Certainty::Proven));
         }
 
-        // FIXME(#33684) -- We need to use
-        // `canonicalize_query_keep_static` here because of things
-        // like the subtype query, which go awry around
-        // `'static` otherwise.
         let mut canonical_var_values = OriginalQueryValues::default();
         let old_param_env = query_key.param_env;
-        let canonical_self =
-            infcx.canonicalize_query_keep_static(query_key, &mut canonical_var_values);
+        let canonical_self = infcx.canonicalize_query(query_key, &mut canonical_var_values);
         let canonical_result = Self::perform_query(infcx.tcx, canonical_self)?;
 
         let InferOk { value, obligations } = infcx
diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-cache-issue-54302.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-cache-issue-54302.stderr
index 7f81ee331bf..186af160d90 100644
--- a/tests/ui/higher-ranked/trait-bounds/hrtb-cache-issue-54302.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-cache-issue-54302.stderr
@@ -4,7 +4,7 @@ error: implementation of `Deserialize` is not general enough
 LL |     assert_deserialize_owned::<&'static str>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough
    |
-   = note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0`...
+   = note: `&str` must implement `Deserialize<'0>`, for any lifetime `'0`...
    = note: ...but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1`
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr b/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr
index 28c259be35f..e50aad876d8 100644
--- a/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr
@@ -12,7 +12,7 @@ error: higher-ranked lifetime error
 LL |     v.t(|| {});
    |         ^^^^^
    |
-   = note: could not prove `for<'a> &'a V: 'static`
+   = note: could not prove `for<'a> &'a V: 'b`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/nll/issue-54302.stderr b/tests/ui/nll/issue-54302.stderr
index 269739af602..a1e2d401429 100644
--- a/tests/ui/nll/issue-54302.stderr
+++ b/tests/ui/nll/issue-54302.stderr
@@ -4,7 +4,7 @@ error: implementation of `Deserialize` is not general enough
 LL |     assert_deserialize_owned::<&'static str>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough
    |
-   = note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0`...
+   = note: `&str` must implement `Deserialize<'0>`, for any lifetime `'0`...
    = note: ...but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1`
 
 error: aborting due to 1 previous error