Skip to content

Commit 45e04fe

Browse files
authored
Rollup merge of #70845 - varkor:const-generics-derive-eq-diagnostic, r=estebank
Make the `structural_match` error diagnostic for const generics clearer The previous diagnostic caused confusion (#70790), so this changes the message to be closer to the message for using non-`structural_match` constants in patterns, explicitly mentioning `#[derive(PartialEq, Eq)]`. Fixes #70790. r? @estebank
2 parents 14b1552 + f8b796b commit 45e04fe

7 files changed

+51
-19
lines changed

src/librustc_typeck/collect/type_of.rs

+39-11
Original file line numberDiff line numberDiff line change
@@ -341,17 +341,45 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
341341
if traits::search_for_structural_match_violation(param.hir_id, param.span, tcx, ty)
342342
.is_some()
343343
{
344-
struct_span_err!(
345-
tcx.sess,
346-
hir_ty.span,
347-
E0741,
348-
"the types of const generic parameters must derive `PartialEq` and `Eq`",
349-
)
350-
.span_label(
351-
hir_ty.span,
352-
format!("`{}` doesn't derive both `PartialEq` and `Eq`", ty),
353-
)
354-
.emit();
344+
// We use the same error code in both branches, because this is really the same
345+
// issue: we just special-case the message for type parameters to make it
346+
// clearer.
347+
if let ty::Param(_) = ty.peel_refs().kind {
348+
// Const parameters may not have type parameters as their types,
349+
// because we cannot be sure that the type parameter derives `PartialEq`
350+
// and `Eq` (just implementing them is not enough for `structural_match`).
351+
struct_span_err!(
352+
tcx.sess,
353+
hir_ty.span,
354+
E0741,
355+
"`{}` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be \
356+
used as the type of a const parameter",
357+
ty,
358+
)
359+
.span_label(
360+
hir_ty.span,
361+
format!("`{}` may not derive both `PartialEq` and `Eq`", ty),
362+
)
363+
.note(
364+
"it is not currently possible to use a type parameter as the type of a \
365+
const parameter",
366+
)
367+
.emit();
368+
} else {
369+
struct_span_err!(
370+
tcx.sess,
371+
hir_ty.span,
372+
E0741,
373+
"`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as \
374+
the type of a const parameter",
375+
ty,
376+
)
377+
.span_label(
378+
hir_ty.span,
379+
format!("`{}` doesn't derive both `PartialEq` and `Eq`", ty),
380+
)
381+
.emit();
382+
}
355383
}
356384
ty
357385
}
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::marker::PhantomData;
22

33
struct B<T, const N: T>(PhantomData<[T; N]>); //~ ERROR const generics are unstable
4-
//~^ ERROR the types of const generic parameters must derive `PartialEq` and `Eq`
4+
//~^ ERROR `T` is not guaranteed to `#[derive(PartialEq, Eq)]`
55

66
fn main() {}

src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr

+4-2
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ LL | struct B<T, const N: T>(PhantomData<[T; N]>);
77
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
88
= help: add `#![feature(const_generics)]` to the crate attributes to enable
99

10-
error[E0741]: the types of const generic parameters must derive `PartialEq` and `Eq`
10+
error[E0741]: `T` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be used as the type of a const parameter
1111
--> $DIR/const-param-type-depends-on-type-param-ungated.rs:3:22
1212
|
1313
LL | struct B<T, const N: T>(PhantomData<[T; N]>);
14-
| ^ `T` doesn't derive both `PartialEq` and `Eq`
14+
| ^ `T` may not derive both `PartialEq` and `Eq`
15+
|
16+
= note: it is not currently possible to use a type parameter as the type of a const parameter
1517

1618
error: aborting due to 2 previous errors
1719

src/test/ui/const-generics/const-param-type-depends-on-type-param.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
// details.
88

99
pub struct Dependent<T, const X: T>([(); X]);
10-
//~^ ERROR the types of const generic parameters must derive `PartialEq` and `Eq`
10+
//~^ ERROR `T` is not guaranteed to `#[derive(PartialEq, Eq)]`
1111

1212
fn main() {}

src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr

+4-2
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ LL | #![feature(const_generics)]
66
|
77
= note: `#[warn(incomplete_features)]` on by default
88

9-
error[E0741]: the types of const generic parameters must derive `PartialEq` and `Eq`
9+
error[E0741]: `T` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be used as the type of a const parameter
1010
--> $DIR/const-param-type-depends-on-type-param.rs:9:34
1111
|
1212
LL | pub struct Dependent<T, const X: T>([(); X]);
13-
| ^ `T` doesn't derive both `PartialEq` and `Eq`
13+
| ^ `T` may not derive both `PartialEq` and `Eq`
14+
|
15+
= note: it is not currently possible to use a type parameter as the type of a const parameter
1416

1517
error: aborting due to previous error; 1 warning emitted
1618

src/test/ui/const-generics/forbid-non-structural_match-types.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ struct B<const X: A>; // ok
88

99
struct C;
1010

11-
struct D<const X: C>; //~ ERROR the types of const generic parameters must derive
11+
struct D<const X: C>; //~ ERROR `C` must be annotated with `#[derive(PartialEq, Eq)]`
1212

1313
fn main() {}

src/test/ui/const-generics/forbid-non-structural_match-types.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ LL | #![feature(const_generics)]
66
|
77
= note: `#[warn(incomplete_features)]` on by default
88

9-
error[E0741]: the types of const generic parameters must derive `PartialEq` and `Eq`
9+
error[E0741]: `C` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter
1010
--> $DIR/forbid-non-structural_match-types.rs:11:19
1111
|
1212
LL | struct D<const X: C>;

0 commit comments

Comments
 (0)