about summary refs log tree commit diff
diff options
context:
space:
mode:
authorlcnr <rust@lcnr.de>2024-11-25 19:41:13 +0100
committerlcnr <rust@lcnr.de>2024-11-25 19:58:12 +0100
commit58936c1d2ae3ccb65761e3bf779e79a85028029c (patch)
tree545292a58824a1b3437a115874fce303b4b30dee
parent7db7489f9bc274cb60c4956bfa56de0185eb1b9b (diff)
downloadrust-58936c1d2ae3ccb65761e3bf779e79a85028029c.tar.gz
rust-58936c1d2ae3ccb65761e3bf779e79a85028029c.zip
fix gce typing_mode mismatch
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs43
-rw-r--r--tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs18
-rw-r--r--tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr46
3 files changed, 89 insertions, 18 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 7d6c38c11f3..069fab6a6e6 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -551,8 +551,18 @@ pub fn try_evaluate_const<'tcx>(
         | ty::ConstKind::Placeholder(_)
         | ty::ConstKind::Expr(_) => Err(EvaluateConstErr::HasGenericsOrInfers),
         ty::ConstKind::Unevaluated(uv) => {
-            // Postpone evaluation of constants that depend on generic parameters or inference variables.
-            let (args, param_env) = if tcx.features().generic_const_exprs()
+            // Postpone evaluation of constants that depend on generic parameters or
+            // inference variables.
+            //
+            // We use `TypingMode::PostAnalysis`  here which is not *technically* correct
+            // to be revealing opaque types here as borrowcheck has not run yet. However,
+            // CTFE itself uses `TypingMode::PostAnalysis` unconditionally even during
+            // typeck and not doing so has a lot of (undesirable) fallout (#101478, #119821).
+            // As a result we always use a revealed env when resolving the instance to evaluate.
+            //
+            // FIXME: `const_eval_resolve_for_typeck` should probably just modify the env itself
+            // instead of having this logic here
+            let (args, typing_env) = if tcx.features().generic_const_exprs()
                 && uv.has_non_region_infer()
             {
                 // `feature(generic_const_exprs)` causes anon consts to inherit all parent generics. This can cause
@@ -568,13 +578,17 @@ pub fn try_evaluate_const<'tcx>(
                             // the generic arguments provided for it, then we should *not* attempt to evaluate it.
                             return Err(EvaluateConstErr::HasGenericsOrInfers);
                         } else {
-                            (replace_param_and_infer_args_with_placeholder(tcx, uv.args), param_env)
+                            let args = replace_param_and_infer_args_with_placeholder(tcx, uv.args);
+                            let typing_env = infcx
+                                .typing_env(tcx.erase_regions(param_env))
+                                .with_post_analysis_normalized(tcx);
+                            (args, typing_env)
                         }
                     }
                     Err(_) | Ok(None) => {
                         let args = GenericArgs::identity_for_item(tcx, uv.def);
-                        let param_env = tcx.param_env(uv.def);
-                        (args, param_env)
+                        let typing_env = ty::TypingEnv::post_analysis(tcx, uv.def);
+                        (args, typing_env)
                     }
                 }
             } else if tcx.def_kind(uv.def) == DefKind::AnonConst && uv.has_non_region_infer() {
@@ -593,27 +607,20 @@ pub fn try_evaluate_const<'tcx>(
                 );
 
                 let args = GenericArgs::identity_for_item(tcx, uv.def);
-                let param_env = tcx.param_env(uv.def);
-                (args, param_env)
+                let typing_env = ty::TypingEnv::post_analysis(tcx, uv.def);
+                (args, typing_env)
             } else {
                 // FIXME: This codepath is reachable under `associated_const_equality` and in the
                 // future will be reachable by `min_generic_const_args`. We should handle inference
                 // variables and generic parameters properly instead of doing nothing.
-                (uv.args, param_env)
+                let typing_env = infcx
+                    .typing_env(tcx.erase_regions(param_env))
+                    .with_post_analysis_normalized(tcx);
+                (uv.args, typing_env)
             };
             let uv = ty::UnevaluatedConst::new(uv.def, args);
 
-            // It's not *technically* correct to be revealing opaque types here as borrowcheck has
-            // not run yet. However, CTFE itself uses `TypingMode::PostAnalysis` unconditionally even
-            // during typeck and not doing so has a lot of (undesirable) fallout (#101478, #119821).
-            // As a result we always use a revealed env when resolving the instance to evaluate.
-            //
-            // FIXME: `const_eval_resolve_for_typeck` should probably just modify the env itself
-            // instead of having this logic here
-            let typing_env =
-                tcx.erase_regions(infcx.typing_env(param_env)).with_post_analysis_normalized(tcx);
             let erased_uv = tcx.erase_regions(uv);
-
             use rustc_middle::mir::interpret::ErrorHandled;
             match tcx.const_eval_resolve_for_typeck(typing_env, erased_uv, DUMMY_SP) {
                 Ok(Ok(val)) => Ok(ty::Const::new_value(
diff --git a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs
new file mode 100644
index 00000000000..e5af632da75
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs
@@ -0,0 +1,18 @@
+// Regression test for #133271.
+#![feature(generic_const_exprs)]
+//~^ WARN the feature `generic_const_exprs` is incomplete
+
+struct Foo;
+impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo
+//~^ ERROR the const parameter `NUM` is not constrained by the impl trait, self type, or predicates
+where
+    [(); 1 + 0]: Sized,
+{
+    fn unimplemented(self, _: &Foo) -> Self::Output {
+        //~^ ERROR method `unimplemented` is not a member of trait `std::ops::Add`
+        //~| ERROR type annotations needed
+        loop {}
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr
new file mode 100644
index 00000000000..ade18eb88b9
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr
@@ -0,0 +1,46 @@
+error[E0407]: method `unimplemented` is not a member of trait `std::ops::Add`
+  --> $DIR/post-analysis-user-facing-param-env.rs:11:5
+   |
+LL | /     fn unimplemented(self, _: &Foo) -> Self::Output {
+LL | |
+LL | |
+LL | |         loop {}
+LL | |     }
+   | |_____^ not a member of trait `std::ops::Add`
+
+warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/post-analysis-user-facing-param-env.rs:2:12
+   |
+LL | #![feature(generic_const_exprs)]
+   |            ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0207]: the const parameter `NUM` is not constrained by the impl trait, self type, or predicates
+  --> $DIR/post-analysis-user-facing-param-env.rs:6:10
+   |
+LL | impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo
+   |          ^^^^^^^^^^^^^^^^ unconstrained const parameter
+   |
+   = note: expressions using a const parameter must map each value to a distinct output value
+   = note: proving the result of expressions other than the parameter are unique is not supported
+
+error[E0284]: type annotations needed
+  --> $DIR/post-analysis-user-facing-param-env.rs:11:40
+   |
+LL |     fn unimplemented(self, _: &Foo) -> Self::Output {
+   |                                        ^^^^^^^^^^^^ cannot infer the value of const parameter `NUM`
+   |
+note: required for `Foo` to implement `Add<&'a Foo>`
+  --> $DIR/post-analysis-user-facing-param-env.rs:6:28
+   |
+LL | impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo
+   |          ----------------  ^^^^^^^^^^^^^^^^^^^^^^     ^^^
+   |          |
+   |          unsatisfied trait bound introduced here
+
+error: aborting due to 3 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0207, E0284, E0407.
+For more information about an error, try `rustc --explain E0207`.