about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_mir_build/messages.ftl4
-rw-r--r--compiler/rustc_mir_build/src/errors.rs1
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs22
-rw-r--r--tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr27
-rw-r--r--tests/ui/consts/issue-73976-polymorphic.stderr12
-rw-r--r--tests/ui/consts/issue-79137-toogeneric.stderr6
-rw-r--r--tests/ui/inline-const/const-match-pat-generic.stderr8
7 files changed, 59 insertions, 21 deletions
diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl
index 2bf49137e8f..4bc7dcf9564 100644
--- a/compiler/rustc_mir_build/messages.ftl
+++ b/compiler/rustc_mir_build/messages.ftl
@@ -88,8 +88,8 @@ mir_build_const_defined_here = constant defined here
 
 mir_build_const_param_in_pattern = const parameters cannot be referenced in patterns
 
-mir_build_const_pattern_depends_on_generic_parameter =
-    constant pattern depends on a generic parameter
+mir_build_const_pattern_depends_on_generic_parameter = constant pattern depends on a generic parameter, which is not allowed
+    .label = `const` depends on a generic parameter
 
 mir_build_could_not_eval_const_pattern = could not evaluate constant pattern
     .label = could not evaluate constant
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index 7f4bb139fad..1068c56eeca 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -695,6 +695,7 @@ pub(crate) struct WantedConstant {
 #[diag(mir_build_const_pattern_depends_on_generic_parameter, code = E0158)]
 pub(crate) struct ConstPatternDependsOnGenericParameter {
     #[primary_span]
+    #[label]
     pub(crate) span: Span,
 }
 
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index 3690459bf51..b625c655fac 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -53,6 +53,7 @@ struct ConstToPat<'tcx> {
     tcx: TyCtxt<'tcx>,
     typing_env: ty::TypingEnv<'tcx>,
     span: Span,
+    id: hir::HirId,
 
     treat_byte_string_as_slice: bool,
 
@@ -66,6 +67,7 @@ impl<'tcx> ConstToPat<'tcx> {
             tcx: pat_ctxt.tcx,
             typing_env: pat_ctxt.typing_env,
             span,
+            id,
             treat_byte_string_as_slice: pat_ctxt
                 .typeck_results
                 .treat_byte_string_as_slice
@@ -135,10 +137,28 @@ impl<'tcx> ConstToPat<'tcx> {
                 return self.mk_err(err, ty);
             }
             Err(ErrorHandled::TooGeneric(_)) => {
-                let e = self
+                let mut e = self
                     .tcx
                     .dcx()
                     .create_err(ConstPatternDependsOnGenericParameter { span: self.span });
+                for arg in uv.args {
+                    if let ty::GenericArgKind::Type(ty) = arg.unpack()
+                        && let ty::Param(param_ty) = ty.kind()
+                    {
+                        let def_id = self.tcx.hir().enclosing_body_owner(self.id);
+                        let generics = self.tcx.generics_of(def_id);
+                        let param = generics.type_param(*param_ty, self.tcx);
+                        let span = self.tcx.def_span(param.def_id);
+                        e.span_label(span, "constant depends on this generic param");
+                        if let Some(ident) = self.tcx.def_ident_span(def_id)
+                            && self.tcx.sess.source_map().is_multiline(ident.between(span))
+                        {
+                            // Display the `fn` name as well in the diagnostic, as the generic isn't
+                            // in the same line and it could be confusing otherwise.
+                            e.span_label(ident, "");
+                        }
+                    }
+                }
                 return self.mk_err(e, ty);
             }
             Ok(Err(bad_ty)) => {
diff --git a/tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr b/tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr
index 5aef0fa414b..455831e8401 100644
--- a/tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr
+++ b/tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr
@@ -1,4 +1,4 @@
-error[E0158]: constant pattern depends on a generic parameter
+error[E0158]: constant pattern depends on a generic parameter, which is not allowed
   --> $DIR/associated-const-type-parameter-pattern.rs:20:9
    |
 LL | pub trait Foo {
@@ -6,10 +6,13 @@ LL | pub trait Foo {
 LL |     const X: EFoo;
    |     ------------- constant defined here
 ...
+LL | pub fn test<A: Foo, B: Foo>(arg: EFoo) {
+   |             - constant depends on this generic param
+LL |     match arg {
 LL |         A::X => println!("A::X"),
-   |         ^^^^
+   |         ^^^^ `const` depends on a generic parameter
 
-error[E0158]: constant pattern depends on a generic parameter
+error[E0158]: constant pattern depends on a generic parameter, which is not allowed
   --> $DIR/associated-const-type-parameter-pattern.rs:22:9
    |
 LL | pub trait Foo {
@@ -17,10 +20,13 @@ LL | pub trait Foo {
 LL |     const X: EFoo;
    |     ------------- constant defined here
 ...
+LL | pub fn test<A: Foo, B: Foo>(arg: EFoo) {
+   |                     - constant depends on this generic param
+...
 LL |         B::X => println!("B::X"),
-   |         ^^^^
+   |         ^^^^ `const` depends on a generic parameter
 
-error[E0158]: constant pattern depends on a generic parameter
+error[E0158]: constant pattern depends on a generic parameter, which is not allowed
   --> $DIR/associated-const-type-parameter-pattern.rs:30:9
    |
 LL | pub trait Foo {
@@ -28,10 +34,13 @@ LL | pub trait Foo {
 LL |     const X: EFoo;
    |     ------------- constant defined here
 ...
+LL | pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
+   |                     - constant depends on this generic param
+LL |
 LL |     let A::X = arg;
-   |         ^^^^
+   |         ^^^^ `const` depends on a generic parameter
 
-error[E0158]: constant pattern depends on a generic parameter
+error[E0158]: constant pattern depends on a generic parameter, which is not allowed
   --> $DIR/associated-const-type-parameter-pattern.rs:28:48
    |
 LL | pub trait Foo {
@@ -40,7 +49,9 @@ LL |     const X: EFoo;
    |     ------------- constant defined here
 ...
 LL | pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
-   |                                                ^^^^
+   |                     -                          ^^^^ `const` depends on a generic parameter
+   |                     |
+   |                     constant depends on this generic param
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/consts/issue-73976-polymorphic.stderr b/tests/ui/consts/issue-73976-polymorphic.stderr
index 79a03d4ec32..2f50e6ac2fd 100644
--- a/tests/ui/consts/issue-73976-polymorphic.stderr
+++ b/tests/ui/consts/issue-73976-polymorphic.stderr
@@ -1,4 +1,4 @@
-error[E0158]: constant pattern depends on a generic parameter
+error[E0158]: constant pattern depends on a generic parameter, which is not allowed
   --> $DIR/issue-73976-polymorphic.rs:20:37
    |
 LL | impl<T: 'static> GetTypeId<T> {
@@ -6,10 +6,12 @@ LL | impl<T: 'static> GetTypeId<T> {
 LL |     pub const VALUE: TypeId = TypeId::of::<T>();
    |     ----------------------- constant defined here
 ...
+LL | const fn check_type_id<T: 'static>() -> bool {
+   |                        - constant depends on this generic param
 LL |     matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE)
-   |                                     ^^^^^^^^^^^^^^^^^^^^^
+   |                                     ^^^^^^^^^^^^^^^^^^^^^ `const` depends on a generic parameter
 
-error[E0158]: constant pattern depends on a generic parameter
+error[E0158]: constant pattern depends on a generic parameter, which is not allowed
   --> $DIR/issue-73976-polymorphic.rs:31:42
    |
 LL | impl<T: 'static> GetTypeNameLen<T> {
@@ -17,8 +19,10 @@ LL | impl<T: 'static> GetTypeNameLen<T> {
 LL |     pub const VALUE: usize = any::type_name::<T>().len();
    |     ---------------------- constant defined here
 ...
+LL | const fn check_type_name_len<T: 'static>() -> bool {
+   |                              - constant depends on this generic param
 LL |     matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
-   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^ `const` depends on a generic parameter
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/issue-79137-toogeneric.stderr b/tests/ui/consts/issue-79137-toogeneric.stderr
index 9b53a259547..d36f3ecbb76 100644
--- a/tests/ui/consts/issue-79137-toogeneric.stderr
+++ b/tests/ui/consts/issue-79137-toogeneric.stderr
@@ -1,4 +1,4 @@
-error[E0158]: constant pattern depends on a generic parameter
+error[E0158]: constant pattern depends on a generic parameter, which is not allowed
   --> $DIR/issue-79137-toogeneric.rs:12:43
    |
 LL | impl<T> GetVariantCount<T> {
@@ -6,8 +6,10 @@ LL | impl<T> GetVariantCount<T> {
 LL |     pub const VALUE: usize = std::mem::variant_count::<T>();
    |     ---------------------- constant defined here
 ...
+LL | const fn check_variant_count<T>() -> bool {
+   |                              - constant depends on this generic param
 LL |     matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE)
-   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `const` depends on a generic parameter
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/inline-const/const-match-pat-generic.stderr b/tests/ui/inline-const/const-match-pat-generic.stderr
index 26f72b34eca..cf48161b5e3 100644
--- a/tests/ui/inline-const/const-match-pat-generic.stderr
+++ b/tests/ui/inline-const/const-match-pat-generic.stderr
@@ -1,14 +1,14 @@
-error[E0158]: constant pattern depends on a generic parameter
+error[E0158]: constant pattern depends on a generic parameter, which is not allowed
   --> $DIR/const-match-pat-generic.rs:7:9
    |
 LL |         const { V } => {},
-   |         ^^^^^^^^^^^
+   |         ^^^^^^^^^^^ `const` depends on a generic parameter
 
-error[E0158]: constant pattern depends on a generic parameter
+error[E0158]: constant pattern depends on a generic parameter, which is not allowed
   --> $DIR/const-match-pat-generic.rs:19:9
    |
 LL |         const { f(V) } => {},
-   |         ^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^ `const` depends on a generic parameter
 
 error: aborting due to 2 previous errors