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:
parent
c0f00086f8
commit
87ddc1ea33
7 changed files with 59 additions and 21 deletions
|
@ -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_param_in_pattern = const parameters cannot be referenced in patterns
|
||||||
|
|
||||||
mir_build_const_pattern_depends_on_generic_parameter =
|
mir_build_const_pattern_depends_on_generic_parameter = constant pattern depends on a generic parameter, which is not allowed
|
||||||
constant pattern depends on a generic parameter
|
.label = `const` depends on a generic parameter
|
||||||
|
|
||||||
mir_build_could_not_eval_const_pattern = could not evaluate constant pattern
|
mir_build_could_not_eval_const_pattern = could not evaluate constant pattern
|
||||||
.label = could not evaluate constant
|
.label = could not evaluate constant
|
||||||
|
|
|
@ -695,6 +695,7 @@ pub(crate) struct WantedConstant {
|
||||||
#[diag(mir_build_const_pattern_depends_on_generic_parameter, code = E0158)]
|
#[diag(mir_build_const_pattern_depends_on_generic_parameter, code = E0158)]
|
||||||
pub(crate) struct ConstPatternDependsOnGenericParameter {
|
pub(crate) struct ConstPatternDependsOnGenericParameter {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
|
#[label]
|
||||||
pub(crate) span: Span,
|
pub(crate) span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ struct ConstToPat<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
typing_env: ty::TypingEnv<'tcx>,
|
typing_env: ty::TypingEnv<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
id: hir::HirId,
|
||||||
|
|
||||||
treat_byte_string_as_slice: bool,
|
treat_byte_string_as_slice: bool,
|
||||||
|
|
||||||
|
@ -66,6 +67,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
tcx: pat_ctxt.tcx,
|
tcx: pat_ctxt.tcx,
|
||||||
typing_env: pat_ctxt.typing_env,
|
typing_env: pat_ctxt.typing_env,
|
||||||
span,
|
span,
|
||||||
|
id,
|
||||||
treat_byte_string_as_slice: pat_ctxt
|
treat_byte_string_as_slice: pat_ctxt
|
||||||
.typeck_results
|
.typeck_results
|
||||||
.treat_byte_string_as_slice
|
.treat_byte_string_as_slice
|
||||||
|
@ -135,10 +137,28 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
return self.mk_err(err, ty);
|
return self.mk_err(err, ty);
|
||||||
}
|
}
|
||||||
Err(ErrorHandled::TooGeneric(_)) => {
|
Err(ErrorHandled::TooGeneric(_)) => {
|
||||||
let e = self
|
let mut e = self
|
||||||
.tcx
|
.tcx
|
||||||
.dcx()
|
.dcx()
|
||||||
.create_err(ConstPatternDependsOnGenericParameter { span: self.span });
|
.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);
|
return self.mk_err(e, ty);
|
||||||
}
|
}
|
||||||
Ok(Err(bad_ty)) => {
|
Ok(Err(bad_ty)) => {
|
||||||
|
|
|
@ -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
|
--> $DIR/associated-const-type-parameter-pattern.rs:20:9
|
||||||
|
|
|
|
||||||
LL | pub trait Foo {
|
LL | pub trait Foo {
|
||||||
|
@ -6,10 +6,13 @@ LL | pub trait Foo {
|
||||||
LL | const X: EFoo;
|
LL | const X: EFoo;
|
||||||
| ------------- constant defined here
|
| ------------- 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"),
|
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
|
--> $DIR/associated-const-type-parameter-pattern.rs:22:9
|
||||||
|
|
|
|
||||||
LL | pub trait Foo {
|
LL | pub trait Foo {
|
||||||
|
@ -17,10 +20,13 @@ LL | pub trait Foo {
|
||||||
LL | const X: EFoo;
|
LL | const X: EFoo;
|
||||||
| ------------- constant defined here
|
| ------------- 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"),
|
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
|
--> $DIR/associated-const-type-parameter-pattern.rs:30:9
|
||||||
|
|
|
|
||||||
LL | pub trait Foo {
|
LL | pub trait Foo {
|
||||||
|
@ -28,10 +34,13 @@ LL | pub trait Foo {
|
||||||
LL | const X: EFoo;
|
LL | const X: EFoo;
|
||||||
| ------------- constant defined here
|
| ------------- 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;
|
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
|
--> $DIR/associated-const-type-parameter-pattern.rs:28:48
|
||||||
|
|
|
|
||||||
LL | pub trait Foo {
|
LL | pub trait Foo {
|
||||||
|
@ -40,7 +49,9 @@ LL | const X: EFoo;
|
||||||
| ------------- constant defined here
|
| ------------- constant defined here
|
||||||
...
|
...
|
||||||
LL | pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
|
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
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
|
|
@ -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
|
--> $DIR/issue-73976-polymorphic.rs:20:37
|
||||||
|
|
|
|
||||||
LL | impl<T: 'static> GetTypeId<T> {
|
LL | impl<T: 'static> GetTypeId<T> {
|
||||||
|
@ -6,10 +6,12 @@ LL | impl<T: 'static> GetTypeId<T> {
|
||||||
LL | pub const VALUE: TypeId = TypeId::of::<T>();
|
LL | pub const VALUE: TypeId = TypeId::of::<T>();
|
||||||
| ----------------------- constant defined here
|
| ----------------------- 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)
|
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
|
--> $DIR/issue-73976-polymorphic.rs:31:42
|
||||||
|
|
|
|
||||||
LL | impl<T: 'static> GetTypeNameLen<T> {
|
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();
|
LL | pub const VALUE: usize = any::type_name::<T>().len();
|
||||||
| ---------------------- constant defined here
|
| ---------------------- 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)
|
LL | matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `const` depends on a generic parameter
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -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
|
--> $DIR/issue-79137-toogeneric.rs:12:43
|
||||||
|
|
|
|
||||||
LL | impl<T> GetVariantCount<T> {
|
LL | impl<T> GetVariantCount<T> {
|
||||||
|
@ -6,8 +6,10 @@ LL | impl<T> GetVariantCount<T> {
|
||||||
LL | pub const VALUE: usize = std::mem::variant_count::<T>();
|
LL | pub const VALUE: usize = std::mem::variant_count::<T>();
|
||||||
| ---------------------- constant defined here
|
| ---------------------- 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)
|
LL | matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE)
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `const` depends on a generic parameter
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -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
|
--> $DIR/const-match-pat-generic.rs:7:9
|
||||||
|
|
|
|
||||||
LL | const { V } => {},
|
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
|
--> $DIR/const-match-pat-generic.rs:19:9
|
||||||
|
|
|
|
||||||
LL | const { f(V) } => {},
|
LL | const { f(V) } => {},
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^ `const` depends on a generic parameter
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue