From 3eea7b31ee0f1afdfcbb2ece8a5445655706cd9b Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 6 Apr 2020 15:12:52 +0100 Subject: [PATCH 1/2] Make the `structural_match` error diagnostic for const generics clearer --- src/librustc_typeck/collect/type_of.rs | 4 +++- .../const-param-type-depends-on-type-param-ungated.rs | 2 +- .../const-param-type-depends-on-type-param-ungated.stderr | 2 +- .../const-generics/const-param-type-depends-on-type-param.rs | 2 +- .../const-param-type-depends-on-type-param.stderr | 2 +- .../ui/const-generics/forbid-non-structural_match-types.rs | 2 +- .../const-generics/forbid-non-structural_match-types.stderr | 2 +- 7 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs index e17b736058f02..ddf0b247ae3a3 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/src/librustc_typeck/collect/type_of.rs @@ -346,7 +346,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { tcx.sess, hir_ty.span, E0741, - "the types of const generic parameters must derive `PartialEq` and `Eq`", + "`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the \ + type of a const parameter", + ty, ) .span_label( hir_ty.span, diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs index 78bd549ba791a..59bb06690a1c9 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs +++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs @@ -1,6 +1,6 @@ use std::marker::PhantomData; struct B(PhantomData<[T; N]>); //~ ERROR const generics are unstable -//~^ ERROR the types of const generic parameters must derive `PartialEq` and `Eq` +//~^ ERROR `T` must be annotated with `#[derive(PartialEq, Eq)]` fn main() {} diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr index 14ade3f33fd9b..70f9fc4184c2c 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr +++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr @@ -7,7 +7,7 @@ LL | struct B(PhantomData<[T; N]>); = note: see issue #44580 for more information = help: add `#![feature(const_generics)]` to the crate attributes to enable -error[E0741]: the types of const generic parameters must derive `PartialEq` and `Eq` +error[E0741]: `T` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter --> $DIR/const-param-type-depends-on-type-param-ungated.rs:3:22 | LL | struct B(PhantomData<[T; N]>); diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs b/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs index 684ccf71082c2..4dcda3b87a854 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs +++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs @@ -7,6 +7,6 @@ // details. pub struct Dependent([(); X]); -//~^ ERROR the types of const generic parameters must derive `PartialEq` and `Eq` +//~^ ERROR `T` must be annotated with `#[derive(PartialEq, Eq)]` fn main() {} diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr b/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr index 724e3909e458f..290d53c4e1971 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr +++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr @@ -6,7 +6,7 @@ LL | #![feature(const_generics)] | = note: `#[warn(incomplete_features)]` on by default -error[E0741]: the types of const generic parameters must derive `PartialEq` and `Eq` +error[E0741]: `T` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter --> $DIR/const-param-type-depends-on-type-param.rs:9:34 | LL | pub struct Dependent([(); X]); diff --git a/src/test/ui/const-generics/forbid-non-structural_match-types.rs b/src/test/ui/const-generics/forbid-non-structural_match-types.rs index 7bc4f3986eb75..a30cdc3efdf43 100644 --- a/src/test/ui/const-generics/forbid-non-structural_match-types.rs +++ b/src/test/ui/const-generics/forbid-non-structural_match-types.rs @@ -8,6 +8,6 @@ struct B; // ok struct C; -struct D; //~ ERROR the types of const generic parameters must derive +struct D; //~ ERROR `C` must be annotated with `#[derive(PartialEq, Eq)]` fn main() {} diff --git a/src/test/ui/const-generics/forbid-non-structural_match-types.stderr b/src/test/ui/const-generics/forbid-non-structural_match-types.stderr index d2469ca766ec7..4f343146263ba 100644 --- a/src/test/ui/const-generics/forbid-non-structural_match-types.stderr +++ b/src/test/ui/const-generics/forbid-non-structural_match-types.stderr @@ -6,7 +6,7 @@ LL | #![feature(const_generics)] | = note: `#[warn(incomplete_features)]` on by default -error[E0741]: the types of const generic parameters must derive `PartialEq` and `Eq` +error[E0741]: `C` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter --> $DIR/forbid-non-structural_match-types.rs:11:19 | LL | struct D; From f8b796b10b3282b02a6bb6f5b5be9dc8dc0dbf94 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 20 Apr 2020 14:01:59 +0100 Subject: [PATCH 2/2] Add error message for using type parameter as the type of a const parameter --- src/librustc_typeck/collect/type_of.rs | 52 ++++++++++++++----- ...aram-type-depends-on-type-param-ungated.rs | 2 +- ...-type-depends-on-type-param-ungated.stderr | 6 ++- .../const-param-type-depends-on-type-param.rs | 2 +- ...st-param-type-depends-on-type-param.stderr | 6 ++- 5 files changed, 49 insertions(+), 19 deletions(-) diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs index ddf0b247ae3a3..5ebf86ef10126 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/src/librustc_typeck/collect/type_of.rs @@ -342,19 +342,45 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { if traits::search_for_structural_match_violation(param.hir_id, param.span, tcx, ty) .is_some() { - struct_span_err!( - tcx.sess, - hir_ty.span, - E0741, - "`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the \ - type of a const parameter", - ty, - ) - .span_label( - hir_ty.span, - format!("`{}` doesn't derive both `PartialEq` and `Eq`", ty), - ) - .emit(); + // We use the same error code in both branches, because this is really the same + // issue: we just special-case the message for type parameters to make it + // clearer. + if let ty::Param(_) = ty.peel_refs().kind { + // Const parameters may not have type parameters as their types, + // because we cannot be sure that the type parameter derives `PartialEq` + // and `Eq` (just implementing them is not enough for `structural_match`). + struct_span_err!( + tcx.sess, + hir_ty.span, + E0741, + "`{}` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be \ + used as the type of a const parameter", + ty, + ) + .span_label( + hir_ty.span, + format!("`{}` may not derive both `PartialEq` and `Eq`", ty), + ) + .note( + "it is not currently possible to use a type parameter as the type of a \ + const parameter", + ) + .emit(); + } else { + struct_span_err!( + tcx.sess, + hir_ty.span, + E0741, + "`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as \ + the type of a const parameter", + ty, + ) + .span_label( + hir_ty.span, + format!("`{}` doesn't derive both `PartialEq` and `Eq`", ty), + ) + .emit(); + } } ty } diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs index 59bb06690a1c9..86ab8075896aa 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs +++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs @@ -1,6 +1,6 @@ use std::marker::PhantomData; struct B(PhantomData<[T; N]>); //~ ERROR const generics are unstable -//~^ ERROR `T` must be annotated with `#[derive(PartialEq, Eq)]` +//~^ ERROR `T` is not guaranteed to `#[derive(PartialEq, Eq)]` fn main() {} diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr index 70f9fc4184c2c..92a7edf96bccb 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr +++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr @@ -7,11 +7,13 @@ LL | struct B(PhantomData<[T; N]>); = note: see issue #44580 for more information = help: add `#![feature(const_generics)]` to the crate attributes to enable -error[E0741]: `T` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter +error[E0741]: `T` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be used as the type of a const parameter --> $DIR/const-param-type-depends-on-type-param-ungated.rs:3:22 | LL | struct B(PhantomData<[T; N]>); - | ^ `T` doesn't derive both `PartialEq` and `Eq` + | ^ `T` may not derive both `PartialEq` and `Eq` + | + = note: it is not currently possible to use a type parameter as the type of a const parameter error: aborting due to 2 previous errors diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs b/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs index 4dcda3b87a854..7468020366cec 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs +++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs @@ -7,6 +7,6 @@ // details. pub struct Dependent([(); X]); -//~^ ERROR `T` must be annotated with `#[derive(PartialEq, Eq)]` +//~^ ERROR `T` is not guaranteed to `#[derive(PartialEq, Eq)]` fn main() {} diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr b/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr index 290d53c4e1971..9f20b06813e37 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr +++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr @@ -6,11 +6,13 @@ LL | #![feature(const_generics)] | = note: `#[warn(incomplete_features)]` on by default -error[E0741]: `T` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter +error[E0741]: `T` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be used as the type of a const parameter --> $DIR/const-param-type-depends-on-type-param.rs:9:34 | LL | pub struct Dependent([(); X]); - | ^ `T` doesn't derive both `PartialEq` and `Eq` + | ^ `T` may not derive both `PartialEq` and `Eq` + | + = note: it is not currently possible to use a type parameter as the type of a const parameter error: aborting due to previous error; 1 warning emitted