about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2024-07-13 18:32:10 +0200
committerRalf Jung <post@ralfj.de>2024-07-18 11:58:16 +0200
commit67c99d6338922d270108fc6390d3ad5224b3a7e1 (patch)
treeea8ed203cc783a23f8e49e2d403b20728b511e0d
parent86ce911f90d9498b33738655c8cfed2f637c335a (diff)
avoid creating an Instance only to immediately disassemble it again
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0158.md17
-rw-r--r--compiler/rustc_mir_build/messages.ftl2
-rw-r--r--compiler/rustc_mir_build/src/errors.rs9
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs33
-rw-r--r--src/tools/tidy/src/issues.txt1
-rw-r--r--tests/ui/associated-consts/associated-const-type-parameter-arms.stderr15
-rw-r--r--tests/ui/associated-consts/associated-const-type-parameter-pattern.rs (renamed from tests/ui/associated-consts/associated-const-type-parameter-arms.rs)10
-rw-r--r--tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr27
-rw-r--r--tests/ui/consts/issue-73976-polymorphic.stderr5
-rw-r--r--tests/ui/consts/issue-79137-toogeneric.stderr3
-rw-r--r--tests/ui/inline-const/const-match-pat-generic.stderr5
-rw-r--r--tests/ui/pattern/issue-68393-let-pat-assoc-constant.rs26
-rw-r--r--tests/ui/pattern/issue-68393-let-pat-assoc-constant.stderr15
13 files changed, 54 insertions, 114 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes/E0158.md b/compiler/rustc_error_codes/src/error_codes/E0158.md
index 03b93d925c1..c31f1e13bee 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0158.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0158.md
@@ -1,5 +1,4 @@
-An associated `const`, `const` parameter or `static` has been referenced
-in a pattern.
+A generic parameter or `static` has been referenced in a pattern.
 
 Erroneous code example:
 
@@ -15,25 +14,25 @@ trait Bar {
 
 fn test<A: Bar>(arg: Foo) {
     match arg {
-        A::X => println!("A::X"), // error: E0158: associated consts cannot be
-                                  //        referenced in patterns
+        A::X => println!("A::X"), // error: E0158: constant pattern depends
+                                  //        on a generic parameter
         Foo::Two => println!("Two")
     }
 }
 ```
 
-Associated `const`s cannot be referenced in patterns because it is impossible
+Generic parameters cannot be referenced in patterns because it is impossible
 for the compiler to prove exhaustiveness (that some pattern will always match).
 Take the above example, because Rust does type checking in the *generic*
 method, not the *monomorphized* specific instance. So because `Bar` could have
-theoretically infinite implementations, there's no way to always be sure that
+theoretically arbitrary implementations, there's no way to always be sure that
 `A::X` is `Foo::One`. So this code must be rejected. Even if code can be
 proven exhaustive by a programmer, the compiler cannot currently prove this.
 
-The same holds true of `const` parameters and `static`s.
+The same holds true of `static`s.
 
-If you want to match against an associated `const`, `const` parameter or
-`static` consider using a guard instead:
+If you want to match against a `const` that depends on a generic parameter or a
+`static`, consider using a guard instead:
 
 ```
 trait Trait {
diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl
index 0c277811fda..281f3ef6ef3 100644
--- a/compiler/rustc_mir_build/messages.ftl
+++ b/compiler/rustc_mir_build/messages.ftl
@@ -4,8 +4,6 @@ mir_build_already_borrowed = cannot borrow value as mutable because it is also b
 
 mir_build_already_mut_borrowed = cannot borrow value as immutable because it is also borrowed as mutable
 
-mir_build_assoc_const_in_pattern = associated consts cannot be referenced in patterns
-
 mir_build_bindings_with_variant_name =
     pattern binding `{$name}` is named the same as one of the variants of the type `{$ty_path}`
     .suggestion = to match on the variant, qualify the path
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index 7c73d8a6d47..f6f443b64a6 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -567,13 +567,6 @@ pub(crate) struct StaticInPattern {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_assoc_const_in_pattern, code = E0158)]
-pub(crate) struct AssocConstInPattern {
-    #[primary_span]
-    pub(crate) span: Span,
-}
-
-#[derive(Diagnostic)]
 #[diag(mir_build_const_param_in_pattern, code = E0158)]
 pub(crate) struct ConstParamInPattern {
     #[primary_span]
@@ -597,7 +590,7 @@ pub(crate) struct UnreachablePattern {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_const_pattern_depends_on_generic_parameter)]
+#[diag(mir_build_const_pattern_depends_on_generic_parameter, code = E0158)]
 pub(crate) struct ConstPatternDependsOnGenericParameter {
     #[primary_span]
     pub(crate) span: Span,
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 553c5e17512..622651800f4 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -548,37 +548,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
             _ => return pat_from_kind(self.lower_variant_or_leaf(res, id, span, ty, vec![])),
         };
 
-        // Use `Reveal::All` here because patterns are always monomorphic even if their function
-        // isn't.
-        let param_env_reveal_all = self.param_env.with_reveal_all_normalized(self.tcx);
-        // N.B. There is no guarantee that args collected in typeck results are fully normalized,
-        // so they need to be normalized in order to pass to `Instance::resolve`, which will ICE
-        // if given unnormalized types.
-        let args = self
-            .tcx
-            .normalize_erasing_regions(param_env_reveal_all, self.typeck_results.node_args(id));
-        let instance = match ty::Instance::try_resolve(self.tcx, param_env_reveal_all, def_id, args)
-        {
-            Ok(Some(i)) => i,
-            Ok(None) => {
-                // It should be assoc consts if there's no error but we cannot resolve it.
-                debug_assert!(is_associated_const);
-
-                let e = self.tcx.dcx().emit_err(AssocConstInPattern { span });
-                return pat_from_kind(PatKind::Error(e));
-            }
-
-            Err(_) => {
-                let e = self.tcx.dcx().emit_err(CouldNotEvalConstPattern { span });
-                return pat_from_kind(PatKind::Error(e));
-            }
-        };
-
-        let c = ty::Const::new_unevaluated(
-            self.tcx,
-            ty::UnevaluatedConst { def: instance.def_id(), args: instance.args },
-        );
-
+        let args = self.typeck_results.node_args(id);
+        let c = ty::Const::new_unevaluated(self.tcx, ty::UnevaluatedConst { def: def_id, args });
         let pattern = self.const_to_pat(c, ty, id, span);
 
         if !is_associated_const {
diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index 3c7284ce6db..57310977704 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -3449,7 +3449,6 @@ ui/pattern/issue-6449.rs
 ui/pattern/issue-66270-pat-struct-parser-recovery.rs
 ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs
 ui/pattern/issue-67776-match-same-name-enum-variant-refs.rs
-ui/pattern/issue-68393-let-pat-assoc-constant.rs
 ui/pattern/issue-72565.rs
 ui/pattern/issue-72574-1.rs
 ui/pattern/issue-72574-2.rs
diff --git a/tests/ui/associated-consts/associated-const-type-parameter-arms.stderr b/tests/ui/associated-consts/associated-const-type-parameter-arms.stderr
deleted file mode 100644
index 1ccf9febd4b..00000000000
--- a/tests/ui/associated-consts/associated-const-type-parameter-arms.stderr
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0158]: associated consts cannot be referenced in patterns
-  --> $DIR/associated-const-type-parameter-arms.rs:20:9
-   |
-LL |         A::X => println!("A::X"),
-   |         ^^^^
-
-error[E0158]: associated consts cannot be referenced in patterns
-  --> $DIR/associated-const-type-parameter-arms.rs:22:9
-   |
-LL |         B::X => println!("B::X"),
-   |         ^^^^
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0158`.
diff --git a/tests/ui/associated-consts/associated-const-type-parameter-arms.rs b/tests/ui/associated-consts/associated-const-type-parameter-pattern.rs
index 3f260d84e4c..b5798adc71c 100644
--- a/tests/ui/associated-consts/associated-const-type-parameter-arms.rs
+++ b/tests/ui/associated-consts/associated-const-type-parameter-pattern.rs
@@ -18,12 +18,18 @@ impl Foo for Def {
 pub fn test<A: Foo, B: Foo>(arg: EFoo) {
     match arg {
         A::X => println!("A::X"),
-        //~^ error: associated consts cannot be referenced in patterns [E0158]
+        //~^ error: constant pattern depends on a generic parameter
         B::X => println!("B::X"),
-        //~^ error: associated consts cannot be referenced in patterns [E0158]
+        //~^ error: constant pattern depends on a generic parameter
         _ => (),
     }
 }
 
+pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
+    //~^ ERROR constant pattern depends on a generic parameter
+    let A::X = arg;
+    //~^ ERROR constant pattern depends on a generic parameter
+}
+
 fn main() {
 }
diff --git a/tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr b/tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr
new file mode 100644
index 00000000000..adc8f399207
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr
@@ -0,0 +1,27 @@
+error[E0158]: constant pattern depends on a generic parameter
+  --> $DIR/associated-const-type-parameter-pattern.rs:20:9
+   |
+LL |         A::X => println!("A::X"),
+   |         ^^^^
+
+error[E0158]: constant pattern depends on a generic parameter
+  --> $DIR/associated-const-type-parameter-pattern.rs:22:9
+   |
+LL |         B::X => println!("B::X"),
+   |         ^^^^
+
+error[E0158]: constant pattern depends on a generic parameter
+  --> $DIR/associated-const-type-parameter-pattern.rs:30:9
+   |
+LL |     let A::X = arg;
+   |         ^^^^
+
+error[E0158]: constant pattern depends on a generic parameter
+  --> $DIR/associated-const-type-parameter-pattern.rs:28:48
+   |
+LL | pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
+   |                                                ^^^^
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0158`.
diff --git a/tests/ui/consts/issue-73976-polymorphic.stderr b/tests/ui/consts/issue-73976-polymorphic.stderr
index 97a5fbc5747..8a44eb9854f 100644
--- a/tests/ui/consts/issue-73976-polymorphic.stderr
+++ b/tests/ui/consts/issue-73976-polymorphic.stderr
@@ -1,10 +1,10 @@
-error: constant pattern depends on a generic parameter
+error[E0158]: constant pattern depends on a generic parameter
   --> $DIR/issue-73976-polymorphic.rs:20:37
    |
 LL |     matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE)
    |                                     ^^^^^^^^^^^^^^^^^^^^^
 
-error: constant pattern depends on a generic parameter
+error[E0158]: constant pattern depends on a generic parameter
   --> $DIR/issue-73976-polymorphic.rs:31:42
    |
 LL |     matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
@@ -12,3 +12,4 @@ LL |     matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0158`.
diff --git a/tests/ui/consts/issue-79137-toogeneric.stderr b/tests/ui/consts/issue-79137-toogeneric.stderr
index 18bdde45e2c..de81512ec6d 100644
--- a/tests/ui/consts/issue-79137-toogeneric.stderr
+++ b/tests/ui/consts/issue-79137-toogeneric.stderr
@@ -1,4 +1,4 @@
-error: constant pattern depends on a generic parameter
+error[E0158]: constant pattern depends on a generic parameter
   --> $DIR/issue-79137-toogeneric.rs:12:43
    |
 LL |     matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE)
@@ -6,3 +6,4 @@ LL |     matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE)
 
 error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0158`.
diff --git a/tests/ui/inline-const/const-match-pat-generic.stderr b/tests/ui/inline-const/const-match-pat-generic.stderr
index 15c3a876afc..26f72b34eca 100644
--- a/tests/ui/inline-const/const-match-pat-generic.stderr
+++ b/tests/ui/inline-const/const-match-pat-generic.stderr
@@ -1,10 +1,10 @@
-error: constant pattern depends on a generic parameter
+error[E0158]: constant pattern depends on a generic parameter
   --> $DIR/const-match-pat-generic.rs:7:9
    |
 LL |         const { V } => {},
    |         ^^^^^^^^^^^
 
-error: constant pattern depends on a generic parameter
+error[E0158]: constant pattern depends on a generic parameter
   --> $DIR/const-match-pat-generic.rs:19:9
    |
 LL |         const { f(V) } => {},
@@ -12,3 +12,4 @@ LL |         const { f(V) } => {},
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0158`.
diff --git a/tests/ui/pattern/issue-68393-let-pat-assoc-constant.rs b/tests/ui/pattern/issue-68393-let-pat-assoc-constant.rs
deleted file mode 100644
index 95ead6b5d4a..00000000000
--- a/tests/ui/pattern/issue-68393-let-pat-assoc-constant.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-pub enum EFoo {
-    A,
-}
-
-pub trait Foo {
-    const X: EFoo;
-}
-
-struct Abc;
-
-impl Foo for Abc {
-    const X: EFoo = EFoo::A;
-}
-
-struct Def;
-impl Foo for Def {
-    const X: EFoo = EFoo::A;
-}
-
-pub fn test<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
-    //~^ ERROR associated consts cannot be referenced in patterns
-    let A::X = arg;
-    //~^ ERROR associated consts cannot be referenced in patterns
-}
-
-fn main() {}
diff --git a/tests/ui/pattern/issue-68393-let-pat-assoc-constant.stderr b/tests/ui/pattern/issue-68393-let-pat-assoc-constant.stderr
deleted file mode 100644
index 62c90b638d7..00000000000
--- a/tests/ui/pattern/issue-68393-let-pat-assoc-constant.stderr
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0158]: associated consts cannot be referenced in patterns
-  --> $DIR/issue-68393-let-pat-assoc-constant.rs:22:9
-   |
-LL |     let A::X = arg;
-   |         ^^^^
-
-error[E0158]: associated consts cannot be referenced in patterns
-  --> $DIR/issue-68393-let-pat-assoc-constant.rs:20:40
-   |
-LL | pub fn test<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
-   |                                        ^^^^
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0158`.