Skip to content

Commit 913558f

Browse files
committed
Point at generic param through which a const is used in a pattern
``` 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 { | ------------- 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 ```
1 parent b867ead commit 913558f

File tree

7 files changed

+59
-21
lines changed

7 files changed

+59
-21
lines changed

compiler/rustc_mir_build/messages.ftl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ mir_build_const_defined_here = constant defined here
8888
8989
mir_build_const_param_in_pattern = const parameters cannot be referenced in patterns
9090
91-
mir_build_const_pattern_depends_on_generic_parameter =
92-
constant pattern depends on a generic parameter
91+
mir_build_const_pattern_depends_on_generic_parameter = constant pattern depends on a generic parameter, which is not allowed
92+
.label = `const` depends on a generic parameter
9393
9494
mir_build_could_not_eval_const_pattern = could not evaluate constant pattern
9595
.label = could not evaluate constant

compiler/rustc_mir_build/src/errors.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,7 @@ pub(crate) struct UnreachablePattern<'tcx> {
606606
#[diag(mir_build_const_pattern_depends_on_generic_parameter, code = E0158)]
607607
pub(crate) struct ConstPatternDependsOnGenericParameter {
608608
#[primary_span]
609+
#[label]
609610
pub(crate) span: Span,
610611
}
611612

compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ struct ConstToPat<'tcx> {
5353
tcx: TyCtxt<'tcx>,
5454
typing_env: ty::TypingEnv<'tcx>,
5555
span: Span,
56+
id: hir::HirId,
5657

5758
treat_byte_string_as_slice: bool,
5859

@@ -66,6 +67,7 @@ impl<'tcx> ConstToPat<'tcx> {
6667
tcx: pat_ctxt.tcx,
6768
typing_env: pat_ctxt.typing_env,
6869
span,
70+
id,
6971
treat_byte_string_as_slice: pat_ctxt
7072
.typeck_results
7173
.treat_byte_string_as_slice
@@ -135,10 +137,28 @@ impl<'tcx> ConstToPat<'tcx> {
135137
return self.mk_err(err, ty);
136138
}
137139
Err(ErrorHandled::TooGeneric(_)) => {
138-
let e = self
140+
let mut e = self
139141
.tcx
140142
.dcx()
141143
.create_err(ConstPatternDependsOnGenericParameter { span: self.span });
144+
for arg in uv.args {
145+
if let ty::GenericArgKind::Type(ty) = arg.unpack()
146+
&& let ty::Param(param_ty) = ty.kind()
147+
{
148+
let def_id = self.tcx.hir().enclosing_body_owner(self.id);
149+
let generics = self.tcx.generics_of(def_id);
150+
let param = generics.type_param(*param_ty, self.tcx);
151+
let span = self.tcx.def_span(param.def_id);
152+
e.span_label(span, "constant depends on this generic param");
153+
if let Some(ident) = self.tcx.def_ident_span(def_id)
154+
&& self.tcx.sess.source_map().is_multiline(ident.between(span))
155+
{
156+
// Display the `fn` name as well in the diagnostic, as the generic isn't
157+
// in the same line and it could be confusing otherwise.
158+
e.span_label(ident, "");
159+
}
160+
}
161+
}
142162
return self.mk_err(e, ty);
143163
}
144164
Ok(Err(bad_ty)) => {

tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,46 @@
1-
error[E0158]: constant pattern depends on a generic parameter
1+
error[E0158]: constant pattern depends on a generic parameter, which is not allowed
22
--> $DIR/associated-const-type-parameter-pattern.rs:20:9
33
|
44
LL | pub trait Foo {
55
| -------------
66
LL | const X: EFoo;
77
| ------------- constant defined here
88
...
9+
LL | pub fn test<A: Foo, B: Foo>(arg: EFoo) {
10+
| - constant depends on this generic param
11+
LL | match arg {
912
LL | A::X => println!("A::X"),
10-
| ^^^^
13+
| ^^^^ `const` depends on a generic parameter
1114

12-
error[E0158]: constant pattern depends on a generic parameter
15+
error[E0158]: constant pattern depends on a generic parameter, which is not allowed
1316
--> $DIR/associated-const-type-parameter-pattern.rs:22:9
1417
|
1518
LL | pub trait Foo {
1619
| -------------
1720
LL | const X: EFoo;
1821
| ------------- constant defined here
1922
...
23+
LL | pub fn test<A: Foo, B: Foo>(arg: EFoo) {
24+
| - constant depends on this generic param
25+
...
2026
LL | B::X => println!("B::X"),
21-
| ^^^^
27+
| ^^^^ `const` depends on a generic parameter
2228

23-
error[E0158]: constant pattern depends on a generic parameter
29+
error[E0158]: constant pattern depends on a generic parameter, which is not allowed
2430
--> $DIR/associated-const-type-parameter-pattern.rs:30:9
2531
|
2632
LL | pub trait Foo {
2733
| -------------
2834
LL | const X: EFoo;
2935
| ------------- constant defined here
3036
...
37+
LL | pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
38+
| - constant depends on this generic param
39+
LL |
3140
LL | let A::X = arg;
32-
| ^^^^
41+
| ^^^^ `const` depends on a generic parameter
3342

34-
error[E0158]: constant pattern depends on a generic parameter
43+
error[E0158]: constant pattern depends on a generic parameter, which is not allowed
3544
--> $DIR/associated-const-type-parameter-pattern.rs:28:48
3645
|
3746
LL | pub trait Foo {
@@ -40,7 +49,9 @@ LL | const X: EFoo;
4049
| ------------- constant defined here
4150
...
4251
LL | pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
43-
| ^^^^
52+
| - ^^^^ `const` depends on a generic parameter
53+
| |
54+
| constant depends on this generic param
4455

4556
error: aborting due to 4 previous errors
4657

tests/ui/consts/issue-73976-polymorphic.stderr

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,28 @@
1-
error[E0158]: constant pattern depends on a generic parameter
1+
error[E0158]: constant pattern depends on a generic parameter, which is not allowed
22
--> $DIR/issue-73976-polymorphic.rs:20:37
33
|
44
LL | impl<T: 'static> GetTypeId<T> {
55
| -----------------------------
66
LL | pub const VALUE: TypeId = TypeId::of::<T>();
77
| ----------------------- constant defined here
88
...
9+
LL | const fn check_type_id<T: 'static>() -> bool {
10+
| - constant depends on this generic param
911
LL | matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE)
10-
| ^^^^^^^^^^^^^^^^^^^^^
12+
| ^^^^^^^^^^^^^^^^^^^^^ `const` depends on a generic parameter
1113

12-
error[E0158]: constant pattern depends on a generic parameter
14+
error[E0158]: constant pattern depends on a generic parameter, which is not allowed
1315
--> $DIR/issue-73976-polymorphic.rs:31:42
1416
|
1517
LL | impl<T: 'static> GetTypeNameLen<T> {
1618
| ----------------------------------
1719
LL | pub const VALUE: usize = any::type_name::<T>().len();
1820
| ---------------------- constant defined here
1921
...
22+
LL | const fn check_type_name_len<T: 'static>() -> bool {
23+
| - constant depends on this generic param
2024
LL | matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
21-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
25+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `const` depends on a generic parameter
2226

2327
error: aborting due to 2 previous errors
2428

tests/ui/consts/issue-79137-toogeneric.stderr

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
error[E0158]: constant pattern depends on a generic parameter
1+
error[E0158]: constant pattern depends on a generic parameter, which is not allowed
22
--> $DIR/issue-79137-toogeneric.rs:12:43
33
|
44
LL | impl<T> GetVariantCount<T> {
55
| --------------------------
66
LL | pub const VALUE: usize = std::mem::variant_count::<T>();
77
| ---------------------- constant defined here
88
...
9+
LL | const fn check_variant_count<T>() -> bool {
10+
| - constant depends on this generic param
911
LL | matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE)
10-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `const` depends on a generic parameter
1113

1214
error: aborting due to 1 previous error
1315

tests/ui/inline-const/const-match-pat-generic.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
error[E0158]: constant pattern depends on a generic parameter
1+
error[E0158]: constant pattern depends on a generic parameter, which is not allowed
22
--> $DIR/const-match-pat-generic.rs:7:9
33
|
44
LL | const { V } => {},
5-
| ^^^^^^^^^^^
5+
| ^^^^^^^^^^^ `const` depends on a generic parameter
66

7-
error[E0158]: constant pattern depends on a generic parameter
7+
error[E0158]: constant pattern depends on a generic parameter, which is not allowed
88
--> $DIR/const-match-pat-generic.rs:19:9
99
|
1010
LL | const { f(V) } => {},
11-
| ^^^^^^^^^^^^^^
11+
| ^^^^^^^^^^^^^^ `const` depends on a generic parameter
1212

1313
error: aborting due to 2 previous errors
1414

0 commit comments

Comments
 (0)