1
Fork 0

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
```
This commit is contained in:
Esteban Küber 2024-11-20 03:08:52 +00:00
parent c0f00086f8
commit 87ddc1ea33
7 changed files with 59 additions and 21 deletions

View file

@ -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

View file

@ -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,
}

View file

@ -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)) => {

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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