about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2024-11-20 04:30:35 +0000
committerEsteban Küber <esteban@kuber.com.ar>2024-12-04 20:29:36 +0000
commit335d05aee555c19d375a46c34134312ac720aba0 (patch)
treefad5c6e3499061305c704824095289b48e9dcd0d
parentfb2f6a44c05c017139ef0266683fdfe3c66c4220 (diff)
downloadrust-335d05aee555c19d375a46c34134312ac720aba0.tar.gz
rust-335d05aee555c19d375a46c34134312ac720aba0.zip
Add additional context for non-sructural type constant used in pattern
- Point at type that should derive `PartialEq` to be structural.
- Point at manual `impl PartialEq`, explaining that it is not sufficient to be structural.

```
error: constant of non-structural type `MyType` in a pattern
  --> $DIR/const-partial_eq-fallback-ice.rs:14:12
   |
LL | struct MyType;
   | ------------- `MyType` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const CONSTANT: &&MyType = &&MyType;
   | ------------------------ constant defined here
...
LL |     if let CONSTANT = &&MyType {
   |            ^^^^^^^^ constant of non-structural type
   |
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
  --> $DIR/const-partial_eq-fallback-ice.rs:5:1
   |
LL | impl PartialEq<usize> for MyType {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
-rw-r--r--compiler/rustc_mir_build/messages.ftl10
-rw-r--r--compiler/rustc_mir_build/src/errors.rs9
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs23
-rw-r--r--tests/ui/consts/const_in_pattern/cross-crate-fail.rs6
-rw-r--r--tests/ui/consts/const_in_pattern/cross-crate-fail.stderr22
-rw-r--r--tests/ui/consts/const_in_pattern/no-eq-branch-fail.rs3
-rw-r--r--tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr8
-rw-r--r--tests/ui/consts/const_in_pattern/reject_non_structural.rs70
-rw-r--r--tests/ui/consts/const_in_pattern/reject_non_structural.stderr160
-rw-r--r--tests/ui/consts/issue-89088.rs2
-rw-r--r--tests/ui/consts/issue-89088.stderr8
-rw-r--r--tests/ui/consts/match_ice.rs3
-rw-r--r--tests/ui/consts/match_ice.stderr8
-rw-r--r--tests/ui/pattern/issue-115599.rs2
-rw-r--r--tests/ui/pattern/issue-115599.stderr8
-rw-r--r--tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.rs2
-rw-r--r--tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr14
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.rs2
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.stderr14
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.rs2
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr14
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs2
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr14
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs2
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr14
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs2
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr14
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs2
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr14
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs12
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr32
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs4
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.stderr16
33 files changed, 343 insertions, 175 deletions
diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl
index df51388c772..6122307e5bb 100644
--- a/compiler/rustc_mir_build/messages.ftl
+++ b/compiler/rustc_mir_build/messages.ftl
@@ -322,12 +322,12 @@ mir_build_trailing_irrefutable_let_patterns = trailing irrefutable {$count ->
         *[other] them
     } into the body
 
-mir_build_type_not_structural =
-     to use a constant of type `{$non_sm_ty}` in a pattern, `{$non_sm_ty}` must be annotated with `#[derive(PartialEq)]`
-
+mir_build_type_not_structural = constant of non-structural type `{$non_sm_ty}` in a pattern
+    .label = constant of non-structural type
+mir_build_type_not_structural_def = `{$non_sm_ty}` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
 mir_build_type_not_structural_more_info = see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
-
-mir_build_type_not_structural_tip = the traits must be derived, manual `impl`s are not sufficient
+mir_build_type_not_structural_tip =
+    the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
 
 mir_build_unconditional_recursion = function cannot return without recursing
     .label = cannot return without recursing
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index 2741830c62d..da4c78ddc4e 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -882,12 +882,17 @@ pub(crate) struct UnionPattern {
 
 #[derive(Diagnostic)]
 #[diag(mir_build_type_not_structural)]
-#[note(mir_build_type_not_structural_tip)]
-#[note(mir_build_type_not_structural_more_info)]
 pub(crate) struct TypeNotStructural<'tcx> {
     #[primary_span]
+    #[label]
     pub(crate) span: Span,
+    #[label(mir_build_type_not_structural_def)]
+    pub(crate) ty_def_span: Span,
     pub(crate) non_sm_ty: Ty<'tcx>,
+    #[note(mir_build_type_not_structural_tip)]
+    pub(crate) manual_partialeq_impl_span: Option<Span>,
+    #[note(mir_build_type_not_structural_more_info)]
+    pub(crate) manual_partialeq_impl_note: bool,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index 71cef18e316..36c84f68f73 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -254,7 +254,22 @@ impl<'tcx> ConstToPat<'tcx> {
                 // Extremely important check for all ADTs! Make sure they opted-in to be used in
                 // patterns.
                 debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, ty);
-                let err = TypeNotStructural { span, non_sm_ty: ty };
+                let ty_def_span = tcx.def_span(adt_def.did());
+                let mut manual_partialeq_impl_span = None;
+                let partial_eq_trait_id =
+                    tcx.require_lang_item(hir::LangItem::PartialEq, Some(self.span));
+                tcx.for_each_relevant_impl(partial_eq_trait_id, ty, |def_id| {
+                    if def_id.is_local() {
+                        manual_partialeq_impl_span = Some(tcx.def_span(def_id));
+                    }
+                });
+                let err = TypeNotStructural {
+                    span,
+                    non_sm_ty: ty,
+                    ty_def_span,
+                    manual_partialeq_impl_span,
+                    manual_partialeq_impl_note: manual_partialeq_impl_span.is_none(),
+                };
                 return Err(tcx.dcx().create_err(err));
             }
             ty::Adt(adt_def, args) if adt_def.is_enum() => {
@@ -269,7 +284,7 @@ impl<'tcx> ConstToPat<'tcx> {
                             adt_def.variants()[variant_index]
                                 .fields
                                 .iter()
-                                .map(|field| field.ty(self.tcx, args)),
+                                .map(|field| field.ty(tcx, args)),
                         ),
                     ),
                 }
@@ -278,7 +293,7 @@ impl<'tcx> ConstToPat<'tcx> {
                 assert!(!def.is_union()); // Valtree construction would never succeed for unions.
                 PatKind::Leaf {
                     subpatterns: self.field_pats(cv.unwrap_branch().iter().copied().zip(
-                        def.non_enum_variant().fields.iter().map(|field| field.ty(self.tcx, args)),
+                        def.non_enum_variant().fields.iter().map(|field| field.ty(tcx, args)),
                     )),
                 }
             }
@@ -377,7 +392,7 @@ impl<'tcx> ConstToPat<'tcx> {
                 let err = InvalidPattern {
                     span,
                     non_sm_ty: ty,
-                    prefix: ty.prefix_string(self.tcx).to_string(),
+                    prefix: ty.prefix_string(tcx).to_string(),
                 };
                 return Err(tcx.dcx().create_err(err));
             }
diff --git a/tests/ui/consts/const_in_pattern/cross-crate-fail.rs b/tests/ui/consts/const_in_pattern/cross-crate-fail.rs
index 163a47f4333..f02e780f30e 100644
--- a/tests/ui/consts/const_in_pattern/cross-crate-fail.rs
+++ b/tests/ui/consts/const_in_pattern/cross-crate-fail.rs
@@ -9,15 +9,13 @@ fn main() {
     let _ = Defaulted;
     match None {
         consts::SOME => panic!(),
-        //~^ must be annotated with `#[derive(PartialEq)]`
-
+        //~^ ERROR constant of non-structural type `CustomEq` in a pattern
         _ => {}
     }
 
     match None {
         <Defaulted as consts::AssocConst>::SOME  => panic!(),
-        //~^ must be annotated with `#[derive(PartialEq)]`
-
+        //~^ ERROR constant of non-structural type `CustomEq` in a pattern
         _ => {}
     }
 }
diff --git a/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr b/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr
index 81fc67e6aeb..7cada883645 100644
--- a/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr
+++ b/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr
@@ -1,29 +1,33 @@
-error: to use a constant of type `CustomEq` in a pattern, `CustomEq` must be annotated with `#[derive(PartialEq)]`
+error: constant of non-structural type `CustomEq` in a pattern
   --> $DIR/cross-crate-fail.rs:11:9
    |
 LL |         consts::SOME => panic!(),
-   |         ^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^ constant of non-structural type
    |
-  ::: $DIR/auxiliary/consts.rs:11:1
+  ::: $DIR/auxiliary/consts.rs:1:1
    |
+LL | pub struct CustomEq;
+   | ------------------- `CustomEq` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+...
 LL | pub const SOME: Option<CustomEq> = Some(CustomEq);
    | -------------------------------- constant defined here
    |
-   = note: the traits must be derived, manual `impl`s are not sufficient
    = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
 
-error: to use a constant of type `CustomEq` in a pattern, `CustomEq` must be annotated with `#[derive(PartialEq)]`
-  --> $DIR/cross-crate-fail.rs:18:9
+error: constant of non-structural type `CustomEq` in a pattern
+  --> $DIR/cross-crate-fail.rs:17:9
    |
 LL |         <Defaulted as consts::AssocConst>::SOME  => panic!(),
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant of non-structural type
    |
-  ::: $DIR/auxiliary/consts.rs:15:5
+  ::: $DIR/auxiliary/consts.rs:1:1
    |
+LL | pub struct CustomEq;
+   | ------------------- `CustomEq` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+...
 LL |     const SOME: Option<CustomEq> = Some(CustomEq);
    |     ---------------------------- constant defined here
    |
-   = note: the traits must be derived, manual `impl`s are not sufficient
    = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
 
 error: aborting due to 2 previous errors
diff --git a/tests/ui/consts/const_in_pattern/no-eq-branch-fail.rs b/tests/ui/consts/const_in_pattern/no-eq-branch-fail.rs
index cf013c1a790..91ef5ac5329 100644
--- a/tests/ui/consts/const_in_pattern/no-eq-branch-fail.rs
+++ b/tests/ui/consts/const_in_pattern/no-eq-branch-fail.rs
@@ -16,8 +16,7 @@ const BAR_BAZ: Foo = if 42 == 42 {
 
 fn main() {
     match Foo::Qux(NoEq) {
-        BAR_BAZ => panic!(),
-        //~^ ERROR must be annotated with `#[derive(PartialEq)]`
+        BAR_BAZ => panic!(), //~ ERROR constant of non-structural type `Foo` in a pattern
         _ => {}
     }
 }
diff --git a/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr b/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr
index 5e2fc6eca3c..154c94c6d38 100644
--- a/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr
+++ b/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr
@@ -1,13 +1,15 @@
-error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq)]`
+error: constant of non-structural type `Foo` in a pattern
   --> $DIR/no-eq-branch-fail.rs:19:9
    |
+LL | enum Foo {
+   | -------- `Foo` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+...
 LL | const BAR_BAZ: Foo = if 42 == 42 {
    | ------------------ constant defined here
 ...
 LL |         BAR_BAZ => panic!(),
-   |         ^^^^^^^
+   |         ^^^^^^^ constant of non-structural type
    |
-   = note: the traits must be derived, manual `impl`s are not sufficient
    = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/consts/const_in_pattern/reject_non_structural.rs b/tests/ui/consts/const_in_pattern/reject_non_structural.rs
index 52cb974c1df..39e5f732a89 100644
--- a/tests/ui/consts/const_in_pattern/reject_non_structural.rs
+++ b/tests/ui/consts/const_in_pattern/reject_non_structural.rs
@@ -17,9 +17,29 @@ struct NoPartialEq;
 
 #[derive(Copy, Clone, Debug)]
 struct NoDerive;
+//~^ NOTE must be annotated with `#[derive(PartialEq)]`
+//~| NOTE must be annotated with `#[derive(PartialEq)]`
+//~| NOTE must be annotated with `#[derive(PartialEq)]`
+//~| NOTE must be annotated with `#[derive(PartialEq)]`
+//~| NOTE must be annotated with `#[derive(PartialEq)]`
+//~| NOTE must be annotated with `#[derive(PartialEq)]`
+//~| NOTE must be annotated with `#[derive(PartialEq)]`
+//~| NOTE must be annotated with `#[derive(PartialEq)]`
+//~| NOTE must be annotated with `#[derive(PartialEq)]`
+//~| NOTE must be annotated with `#[derive(PartialEq)]`
 
 // This impl makes `NoDerive` irreflexive.
 impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
+//~^ NOTE StructuralPartialEq.html for details
+//~| NOTE StructuralPartialEq.html for details
+//~| NOTE StructuralPartialEq.html for details
+//~| NOTE StructuralPartialEq.html for details
+//~| NOTE StructuralPartialEq.html for details
+//~| NOTE StructuralPartialEq.html for details
+//~| NOTE StructuralPartialEq.html for details
+//~| NOTE StructuralPartialEq.html for details
+//~| NOTE StructuralPartialEq.html for details
+//~| NOTE StructuralPartialEq.html for details
 
 impl Eq for NoDerive { }
 
@@ -38,63 +58,53 @@ fn main() {
 
     const ENUM: Derive<NoDerive> = Derive::Some(NoDerive); //~ NOTE constant defined here
     match Derive::Some(NoDerive) { ENUM => dbg!(ENUM), _ => panic!("whoops"), };
-    //~^ ERROR must be annotated with `#[derive(PartialEq)]`
-    //~| NOTE the traits must be derived
-    //~| NOTE StructuralPartialEq.html for details
+    //~^ ERROR constant of non-structural type `NoDerive` in a pattern
+    //~| NOTE constant of non-structural type
 
     const FIELD: OND = TrivialEq(Some(NoDerive)).0; //~ NOTE constant defined here
     match Some(NoDerive) { FIELD => dbg!(FIELD), _ => panic!("whoops"), };
-    //~^ ERROR must be annotated with `#[derive(PartialEq)]`
-    //~| NOTE the traits must be derived
-    //~| NOTE StructuralPartialEq.html for details
+    //~^ ERROR constant of non-structural type `NoDerive` in a pattern
+    //~| NOTE constant of non-structural type
 
     const NO_DERIVE_SOME: OND = Some(NoDerive);
     const INDIRECT: OND = NO_DERIVE_SOME; //~ NOTE constant defined here
     match Some(NoDerive) {INDIRECT => dbg!(INDIRECT), _ => panic!("whoops"), };
-    //~^ ERROR must be annotated with `#[derive(PartialEq)]`
-    //~| NOTE the traits must be derived
-    //~| NOTE StructuralPartialEq.html for details
+    //~^ ERROR constant of non-structural type `NoDerive` in a pattern
+    //~| NOTE constant of non-structural type
 
     const TUPLE: (OND, OND) = (None, Some(NoDerive)); //~ NOTE constant defined here
     match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), };
-    //~^ ERROR must be annotated with `#[derive(PartialEq)]`
-    //~| NOTE the traits must be derived
-    //~| NOTE StructuralPartialEq.html for details
+    //~^ ERROR constant of non-structural type `NoDerive` in a pattern
+    //~| NOTE constant of non-structural type
 
     const TYPE_ASCRIPTION: OND = type_ascribe!(Some(NoDerive), OND); //~ NOTE constant defined here
     match Some(NoDerive) { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), };
-    //~^ ERROR must be annotated with `#[derive(PartialEq)]`
-    //~| NOTE the traits must be derived
-    //~| NOTE StructuralPartialEq.html for details
+    //~^ ERROR constant of non-structural type `NoDerive` in a pattern
+    //~| NOTE constant of non-structural type
 
     const ARRAY: [OND; 2] = [None, Some(NoDerive)]; //~ NOTE constant defined here
     match [None, Some(NoDerive)] { ARRAY => dbg!(ARRAY), _ => panic!("whoops"), };
-    //~^ ERROR must be annotated with `#[derive(PartialEq)]`
-    //~| NOTE the traits must be derived
-    //~| NOTE StructuralPartialEq.html for details
+    //~^ ERROR constant of non-structural type `NoDerive` in a pattern
+    //~| NOTE constant of non-structural type
 
     const REPEAT: [OND; 2] = [Some(NoDerive); 2]; //~ NOTE constant defined here
     match [Some(NoDerive); 2] { REPEAT => dbg!(REPEAT), _ => panic!("whoops"), };
-    //~^ ERROR must be annotated with `#[derive(PartialEq)]`
-    //~| NOTE the traits must be derived
-    //~| NOTE StructuralPartialEq.html for details
+    //~^ ERROR constant of non-structural type `NoDerive` in a pattern
+    //~| NOTE constant of non-structural type
 
     trait Trait: Sized { const ASSOC: Option<Self>; } //~ NOTE constant defined here
     impl Trait for NoDerive { const ASSOC: Option<NoDerive> = Some(NoDerive); }
     match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), };
-    //~^ ERROR must be annotated with `#[derive(PartialEq)]`
-    //~| NOTE the traits must be derived
-    //~| NOTE StructuralPartialEq.html for details
+    //~^ ERROR constant of non-structural type `NoDerive` in a pattern
+    //~| NOTE constant of non-structural type
 
     const BLOCK: OND = { NoDerive; Some(NoDerive) }; //~ NOTE constant defined here
     match Some(NoDerive) { BLOCK => dbg!(BLOCK), _ => panic!("whoops"), };
-    //~^ ERROR must be annotated with `#[derive(PartialEq)]`
-    //~| NOTE the traits must be derived
-    //~| NOTE StructuralPartialEq.html for details
+    //~^ ERROR constant of non-structural type `NoDerive` in a pattern
+    //~| NOTE constant of non-structural type
 
     const ADDR_OF: &OND = &Some(NoDerive); //~ NOTE constant defined here
     match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), };
-    //~^ ERROR must be annotated with `#[derive(PartialEq)]`
-    //~| NOTE the traits must be derived
-    //~| NOTE StructuralPartialEq.html for details
+    //~^ ERROR constant of non-structural type `NoDerive` in a pattern
+    //~| NOTE constant of non-structural type
 }
diff --git a/tests/ui/consts/const_in_pattern/reject_non_structural.stderr b/tests/ui/consts/const_in_pattern/reject_non_structural.stderr
index e8a69512e7e..fa16d0b06a7 100644
--- a/tests/ui/consts/const_in_pattern/reject_non_structural.stderr
+++ b/tests/ui/consts/const_in_pattern/reject_non_structural.stderr
@@ -1,113 +1,173 @@
-error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
-  --> $DIR/reject_non_structural.rs:40:36
+error: constant of non-structural type `NoDerive` in a pattern
+  --> $DIR/reject_non_structural.rs:60:36
    |
+LL | struct NoDerive;
+   | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+...
 LL |     const ENUM: Derive<NoDerive> = Derive::Some(NoDerive);
    |     ---------------------------- constant defined here
 LL |     match Derive::Some(NoDerive) { ENUM => dbg!(ENUM), _ => panic!("whoops"), };
-   |                                    ^^^^
+   |                                    ^^^^ constant of non-structural type
    |
-   = note: the traits must be derived, manual `impl`s are not sufficient
-   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+  --> $DIR/reject_non_structural.rs:32:1
+   |
+LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
-  --> $DIR/reject_non_structural.rs:46:28
+error: constant of non-structural type `NoDerive` in a pattern
+  --> $DIR/reject_non_structural.rs:65:28
    |
+LL | struct NoDerive;
+   | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+...
 LL |     const FIELD: OND = TrivialEq(Some(NoDerive)).0;
    |     ---------------- constant defined here
 LL |     match Some(NoDerive) { FIELD => dbg!(FIELD), _ => panic!("whoops"), };
-   |                            ^^^^^
+   |                            ^^^^^ constant of non-structural type
+   |
+note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+  --> $DIR/reject_non_structural.rs:32:1
    |
-   = note: the traits must be derived, manual `impl`s are not sufficient
-   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
-  --> $DIR/reject_non_structural.rs:53:27
+error: constant of non-structural type `NoDerive` in a pattern
+  --> $DIR/reject_non_structural.rs:71:27
    |
+LL | struct NoDerive;
+   | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+...
 LL |     const INDIRECT: OND = NO_DERIVE_SOME;
    |     ------------------- constant defined here
 LL |     match Some(NoDerive) {INDIRECT => dbg!(INDIRECT), _ => panic!("whoops"), };
-   |                           ^^^^^^^^
+   |                           ^^^^^^^^ constant of non-structural type
    |
-   = note: the traits must be derived, manual `impl`s are not sufficient
-   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+  --> $DIR/reject_non_structural.rs:32:1
+   |
+LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
-  --> $DIR/reject_non_structural.rs:59:36
+error: constant of non-structural type `NoDerive` in a pattern
+  --> $DIR/reject_non_structural.rs:76:36
    |
+LL | struct NoDerive;
+   | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+...
 LL |     const TUPLE: (OND, OND) = (None, Some(NoDerive));
    |     ----------------------- constant defined here
 LL |     match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), };
-   |                                    ^^^^^
+   |                                    ^^^^^ constant of non-structural type
+   |
+note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+  --> $DIR/reject_non_structural.rs:32:1
    |
-   = note: the traits must be derived, manual `impl`s are not sufficient
-   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
-  --> $DIR/reject_non_structural.rs:65:28
+error: constant of non-structural type `NoDerive` in a pattern
+  --> $DIR/reject_non_structural.rs:81:28
    |
+LL | struct NoDerive;
+   | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+...
 LL |     const TYPE_ASCRIPTION: OND = type_ascribe!(Some(NoDerive), OND);
    |     -------------------------- constant defined here
 LL |     match Some(NoDerive) { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), };
-   |                            ^^^^^^^^^^^^^^^
+   |                            ^^^^^^^^^^^^^^^ constant of non-structural type
    |
-   = note: the traits must be derived, manual `impl`s are not sufficient
-   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+  --> $DIR/reject_non_structural.rs:32:1
+   |
+LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
-  --> $DIR/reject_non_structural.rs:71:36
+error: constant of non-structural type `NoDerive` in a pattern
+  --> $DIR/reject_non_structural.rs:86:36
    |
+LL | struct NoDerive;
+   | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+...
 LL |     const ARRAY: [OND; 2] = [None, Some(NoDerive)];
    |     --------------------- constant defined here
 LL |     match [None, Some(NoDerive)] { ARRAY => dbg!(ARRAY), _ => panic!("whoops"), };
-   |                                    ^^^^^
+   |                                    ^^^^^ constant of non-structural type
+   |
+note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+  --> $DIR/reject_non_structural.rs:32:1
    |
-   = note: the traits must be derived, manual `impl`s are not sufficient
-   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
-  --> $DIR/reject_non_structural.rs:77:33
+error: constant of non-structural type `NoDerive` in a pattern
+  --> $DIR/reject_non_structural.rs:91:33
    |
+LL | struct NoDerive;
+   | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+...
 LL |     const REPEAT: [OND; 2] = [Some(NoDerive); 2];
    |     ---------------------- constant defined here
 LL |     match [Some(NoDerive); 2] { REPEAT => dbg!(REPEAT), _ => panic!("whoops"), };
-   |                                 ^^^^^^
+   |                                 ^^^^^^ constant of non-structural type
+   |
+note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+  --> $DIR/reject_non_structural.rs:32:1
    |
-   = note: the traits must be derived, manual `impl`s are not sufficient
-   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
-  --> $DIR/reject_non_structural.rs:84:28
+error: constant of non-structural type `NoDerive` in a pattern
+  --> $DIR/reject_non_structural.rs:97:28
    |
+LL | struct NoDerive;
+   | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+...
 LL |     trait Trait: Sized { const ASSOC: Option<Self>; }
    |     ------------------   ------------------------- constant defined here
 LL |     impl Trait for NoDerive { const ASSOC: Option<NoDerive> = Some(NoDerive); }
 LL |     match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), };
-   |                            ^^^^^^^^^^^^^^^
+   |                            ^^^^^^^^^^^^^^^ constant of non-structural type
    |
-   = note: the traits must be derived, manual `impl`s are not sufficient
-   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+  --> $DIR/reject_non_structural.rs:32:1
+   |
+LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
-  --> $DIR/reject_non_structural.rs:90:28
+error: constant of non-structural type `NoDerive` in a pattern
+  --> $DIR/reject_non_structural.rs:102:28
    |
+LL | struct NoDerive;
+   | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+...
 LL |     const BLOCK: OND = { NoDerive; Some(NoDerive) };
    |     ---------------- constant defined here
 LL |     match Some(NoDerive) { BLOCK => dbg!(BLOCK), _ => panic!("whoops"), };
-   |                            ^^^^^
+   |                            ^^^^^ constant of non-structural type
+   |
+note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+  --> $DIR/reject_non_structural.rs:32:1
    |
-   = note: the traits must be derived, manual `impl`s are not sufficient
-   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
-  --> $DIR/reject_non_structural.rs:96:29
+error: constant of non-structural type `NoDerive` in a pattern
+  --> $DIR/reject_non_structural.rs:107:29
    |
+LL | struct NoDerive;
+   | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+...
 LL |     const ADDR_OF: &OND = &Some(NoDerive);
    |     ------------------- constant defined here
 LL |     match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), };
-   |                             ^^^^^^^
+   |                             ^^^^^^^ constant of non-structural type
+   |
+note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+  --> $DIR/reject_non_structural.rs:32:1
    |
-   = note: the traits must be derived, manual `impl`s are not sufficient
-   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 10 previous errors
 
diff --git a/tests/ui/consts/issue-89088.rs b/tests/ui/consts/issue-89088.rs
index 02a786e7465..f6dbf8f0125 100644
--- a/tests/ui/consts/issue-89088.rs
+++ b/tests/ui/consts/issue-89088.rs
@@ -13,7 +13,7 @@ fn main() {
     let var = A::Field(Cow::Borrowed("bar"));
 
     match &var {
-        FOO => todo!(), //~ERROR derive(PartialEq)
+        FOO => todo!(), //~ ERROR constant of non-structural type `Cow<'_, str>` in a pattern
         _ => todo!()
     }
 }
diff --git a/tests/ui/consts/issue-89088.stderr b/tests/ui/consts/issue-89088.stderr
index 740cc25647e..56025e0d9b2 100644
--- a/tests/ui/consts/issue-89088.stderr
+++ b/tests/ui/consts/issue-89088.stderr
@@ -1,13 +1,15 @@
-error: to use a constant of type `Cow<'_, str>` in a pattern, `Cow<'_, str>` must be annotated with `#[derive(PartialEq)]`
+error: constant of non-structural type `Cow<'_, str>` in a pattern
   --> $DIR/issue-89088.rs:16:9
    |
 LL | const FOO: &A = &A::Field(Cow::Borrowed("foo"));
    | ------------- constant defined here
 ...
 LL |         FOO => todo!(),
-   |         ^^^
+   |         ^^^ constant of non-structural type
+  --> $SRC_DIR/alloc/src/borrow.rs:LL:COL
+   |
+   = note: `Cow<'_, str>` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
    |
-   = note: the traits must be derived, manual `impl`s are not sufficient
    = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/consts/match_ice.rs b/tests/ui/consts/match_ice.rs
index ed1fd78809b..477a2de09a4 100644
--- a/tests/ui/consts/match_ice.rs
+++ b/tests/ui/consts/match_ice.rs
@@ -8,8 +8,7 @@ struct T;
 fn main() {
     const C: &S = &S;
     match C {
-        C => {}
-        //~^ ERROR must be annotated with `#[derive(PartialEq)]`
+        C => {} //~ ERROR constant of non-structural type `S` in a pattern
     }
     const K: &T = &T;
     match K {
diff --git a/tests/ui/consts/match_ice.stderr b/tests/ui/consts/match_ice.stderr
index 0841ed05025..95e96bbbd67 100644
--- a/tests/ui/consts/match_ice.stderr
+++ b/tests/ui/consts/match_ice.stderr
@@ -1,13 +1,15 @@
-error: to use a constant of type `S` in a pattern, `S` must be annotated with `#[derive(PartialEq)]`
+error: constant of non-structural type `S` in a pattern
   --> $DIR/match_ice.rs:11:9
    |
+LL | struct S;
+   | -------- `S` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+...
 LL |     const C: &S = &S;
    |     ----------- constant defined here
 LL |     match C {
 LL |         C => {}
-   |         ^
+   |         ^ constant of non-structural type
    |
-   = note: the traits must be derived, manual `impl`s are not sufficient
    = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/pattern/issue-115599.rs b/tests/ui/pattern/issue-115599.rs
index 1521d728d95..47fe6b87da9 100644
--- a/tests/ui/pattern/issue-115599.rs
+++ b/tests/ui/pattern/issue-115599.rs
@@ -3,5 +3,5 @@ const CONST_STRING: String = String::new();
 fn main() {
     let empty_str = String::from("");
     if let CONST_STRING = empty_str {}
-    //~^ ERROR to use a constant of type `Vec<u8>` in a pattern, `Vec<u8>` must be annotated with `#[derive(PartialEq)]`
+    //~^ ERROR constant of non-structural type `Vec<u8>` in a pattern
 }
diff --git a/tests/ui/pattern/issue-115599.stderr b/tests/ui/pattern/issue-115599.stderr
index 65e3b08ac48..69d10728ccd 100644
--- a/tests/ui/pattern/issue-115599.stderr
+++ b/tests/ui/pattern/issue-115599.stderr
@@ -1,13 +1,15 @@
-error: to use a constant of type `Vec<u8>` in a pattern, `Vec<u8>` must be annotated with `#[derive(PartialEq)]`
+error: constant of non-structural type `Vec<u8>` in a pattern
   --> $DIR/issue-115599.rs:5:12
    |
 LL | const CONST_STRING: String = String::new();
    | -------------------------- constant defined here
 ...
 LL |     if let CONST_STRING = empty_str {}
-   |            ^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^ constant of non-structural type
+  --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+   |
+   = note: `Vec<u8>` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
    |
-   = note: the traits must be derived, manual `impl`s are not sufficient
    = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.rs b/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.rs
index f34093ef149..f09dcf8498f 100644
--- a/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.rs
+++ b/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.rs
@@ -12,7 +12,7 @@ const CONSTANT: &&MyType = &&MyType;
 
 fn main() {
     if let CONSTANT = &&MyType {
-        //~^ ERROR must be annotated with `#[derive(PartialEq)]`
+        //~^ ERROR constant of non-structural type `MyType` in a pattern
         println!("did match!");
     }
 }
diff --git a/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr b/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr
index bcbcd0bc280..f9da0430f2e 100644
--- a/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr
+++ b/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr
@@ -1,14 +1,20 @@
-error: to use a constant of type `MyType` in a pattern, `MyType` must be annotated with `#[derive(PartialEq)]`
+error: constant of non-structural type `MyType` in a pattern
   --> $DIR/const-partial_eq-fallback-ice.rs:14:12
    |
+LL | struct MyType;
+   | ------------- `MyType` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+...
 LL | const CONSTANT: &&MyType = &&MyType;
    | ------------------------ constant defined here
 ...
 LL |     if let CONSTANT = &&MyType {
-   |            ^^^^^^^^
+   |            ^^^^^^^^ constant of non-structural type
+   |
+note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+  --> $DIR/const-partial_eq-fallback-ice.rs:5:1
    |
-   = note: the traits must be derived, manual `impl`s are not sufficient
-   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+LL | impl PartialEq<usize> for MyType {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.rs
index 65a85a5ed68..e27c8048049 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.rs
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.rs
@@ -20,7 +20,7 @@ const WRAP_DIRECT_INLINE: WrapInline = WrapInline(NoDerive(0));
 fn main() {
     match WRAP_DIRECT_INLINE {
         WRAP_DIRECT_INLINE => { panic!("WRAP_DIRECT_INLINE matched itself"); }
-        //~^ ERROR must be annotated with `#[derive(PartialEq)]`
+        //~^ ERROR constant of non-structural type `NoDerive` in a pattern
         _ => { println!("WRAP_DIRECT_INLINE did not match itself"); }
     }
 }
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.stderr
index dffaafd88a0..8787d140e17 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.stderr
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.stderr
@@ -1,14 +1,20 @@
-error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
+error: constant of non-structural type `NoDerive` in a pattern
   --> $DIR/cant-hide-behind-direct-struct-embedded.rs:22:9
    |
+LL | struct NoDerive(#[allow(dead_code)] i32);
+   | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+...
 LL | const WRAP_DIRECT_INLINE: WrapInline = WrapInline(NoDerive(0));
    | ------------------------------------ constant defined here
 ...
 LL |         WRAP_DIRECT_INLINE => { panic!("WRAP_DIRECT_INLINE matched itself"); }
-   |         ^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^ constant of non-structural type
+   |
+note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+  --> $DIR/cant-hide-behind-direct-struct-embedded.rs:11:1
    |
-   = note: the traits must be derived, manual `impl`s are not sufficient
-   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.rs
index f840b4040b6..713ff23573d 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.rs
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.rs
@@ -19,7 +19,7 @@ const WRAP_DIRECT_PARAM: WrapParam<NoDerive> = WrapParam(NoDerive(0));
 fn main() {
     match WRAP_DIRECT_PARAM {
         WRAP_DIRECT_PARAM => { panic!("WRAP_DIRECT_PARAM matched itself"); }
-        //~^ ERROR must be annotated with `#[derive(PartialEq)]`
+        //~^ ERROR constant of non-structural type `NoDerive` in a pattern
         _ => { println!("WRAP_DIRECT_PARAM did not match itself"); }
     }
 }
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr
index 8da9fa71c53..ec836db02ad 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr
@@ -1,14 +1,20 @@
-error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
+error: constant of non-structural type `NoDerive` in a pattern
   --> $DIR/cant-hide-behind-direct-struct-param.rs:21:9
    |
+LL | struct NoDerive(i32);
+   | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+...
 LL | const WRAP_DIRECT_PARAM: WrapParam<NoDerive> = WrapParam(NoDerive(0));
    | -------------------------------------------- constant defined here
 ...
 LL |         WRAP_DIRECT_PARAM => { panic!("WRAP_DIRECT_PARAM matched itself"); }
-   |         ^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^ constant of non-structural type
+   |
+note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+  --> $DIR/cant-hide-behind-direct-struct-param.rs:10:1
    |
-   = note: the traits must be derived, manual `impl`s are not sufficient
-   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs
index 898acefc83c..7766a469192 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs
@@ -20,7 +20,7 @@ const WRAP_DOUBLY_INDIRECT_INLINE: & &WrapInline = & &WrapInline(& & NoDerive(0)
 fn main() {
     match WRAP_DOUBLY_INDIRECT_INLINE {
         WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); }
-        //~^ ERROR must be annotated with `#[derive(PartialEq)]`
+        //~^ ERROR constant of non-structural type `NoDerive` in a pattern
         _ => { println!("WRAP_DOUBLY_INDIRECT_INLINE correctly did not match itself"); }
     }
 }
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr
index 3cd6a184bbe..fdc16fe300c 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr
@@ -1,14 +1,20 @@
-error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
+error: constant of non-structural type `NoDerive` in a pattern
   --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:22:9
    |
+LL | struct NoDerive(#[allow(dead_code)] i32);
+   | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+...
 LL | const WRAP_DOUBLY_INDIRECT_INLINE: & &WrapInline = & &WrapInline(& & NoDerive(0));
    | ------------------------------------------------ constant defined here
 ...
 LL |         WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); }
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant of non-structural type
+   |
+note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+  --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:11:1
    |
-   = note: the traits must be derived, manual `impl`s are not sufficient
-   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs
index 7cbaada88a3..ed84900b6e9 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs
@@ -20,7 +20,7 @@ const WRAP_DOUBLY_INDIRECT_PARAM: & &WrapParam<NoDerive> = & &WrapParam(& & NoDe
 fn main() {
     match WRAP_DOUBLY_INDIRECT_PARAM {
         WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); }
-        //~^ ERROR must be annotated with `#[derive(PartialEq)]`
+        //~^ ERROR constant of non-structural type `NoDerive` in a pattern
         _ => { println!("WRAP_DOUBLY_INDIRECT_PARAM correctly did not match itself"); }
     }
 }
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr
index 35693da99ab..b46fc041f14 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr
@@ -1,14 +1,20 @@
-error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
+error: constant of non-structural type `NoDerive` in a pattern
   --> $DIR/cant-hide-behind-doubly-indirect-param.rs:22:9
    |
+LL | struct NoDerive(#[allow(dead_code)] i32);
+   | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+...
 LL | const WRAP_DOUBLY_INDIRECT_PARAM: & &WrapParam<NoDerive> = & &WrapParam(& & NoDerive(0));
    | -------------------------------------------------------- constant defined here
 ...
 LL |         WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); }
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ constant of non-structural type
+   |
+note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+  --> $DIR/cant-hide-behind-doubly-indirect-param.rs:11:1
    |
-   = note: the traits must be derived, manual `impl`s are not sufficient
-   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs
index ac868efed6f..5743d7a24d3 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs
@@ -20,7 +20,7 @@ const WRAP_INDIRECT_INLINE: & &WrapInline = & &WrapInline(NoDerive(0));
 fn main() {
     match WRAP_INDIRECT_INLINE {
         WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); }
-        //~^ ERROR must be annotated with `#[derive(PartialEq)]`
+        //~^ ERROR constant of non-structural type `NoDerive` in a pattern
         _ => { println!("WRAP_INDIRECT_INLINE did not match itself"); }
     }
 }
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr
index 5312d61c446..70f39aa01d8 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr
@@ -1,14 +1,20 @@
-error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
+error: constant of non-structural type `NoDerive` in a pattern
   --> $DIR/cant-hide-behind-indirect-struct-embedded.rs:22:9
    |
+LL | struct NoDerive(#[allow(dead_code)] i32);
+   | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+...
 LL | const WRAP_INDIRECT_INLINE: & &WrapInline = & &WrapInline(NoDerive(0));
    | ----------------------------------------- constant defined here
 ...
 LL |         WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); }
-   |         ^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^ constant of non-structural type
+   |
+note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+  --> $DIR/cant-hide-behind-indirect-struct-embedded.rs:11:1
    |
-   = note: the traits must be derived, manual `impl`s are not sufficient
-   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs
index cbfabec6819..9226f9c3ecd 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs
@@ -20,7 +20,7 @@ const WRAP_INDIRECT_PARAM: & &WrapParam<NoDerive> = & &WrapParam(NoDerive(0));
 fn main() {
     match WRAP_INDIRECT_PARAM {
         WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); }
-        //~^ ERROR must be annotated with `#[derive(PartialEq)]`
+        //~^ ERROR constant of non-structural type `NoDerive` in a pattern
         _ => { println!("WRAP_INDIRECT_PARAM correctly did not match itself"); }
     }
 }
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr
index 2066c53e73a..fceb3acb025 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr
@@ -1,14 +1,20 @@
-error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
+error: constant of non-structural type `NoDerive` in a pattern
   --> $DIR/cant-hide-behind-indirect-struct-param.rs:22:9
    |
+LL | struct NoDerive(#[allow(dead_code)] i32);
+   | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+...
 LL | const WRAP_INDIRECT_PARAM: & &WrapParam<NoDerive> = & &WrapParam(NoDerive(0));
    | ------------------------------------------------- constant defined here
 ...
 LL |         WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); }
-   |         ^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^ constant of non-structural type
+   |
+note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+  --> $DIR/cant-hide-behind-indirect-struct-param.rs:11:1
    |
-   = note: the traits must be derived, manual `impl`s are not sufficient
-   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs
index 0fa2370c95b..843c5a38649 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs
@@ -13,27 +13,35 @@
 
 #[derive(Debug)]
 struct B(i32);
+//~^ NOTE `B` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+//~| NOTE `B` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
 
 // Overriding `PartialEq` to use this strange notion of "equality" exposes
 // whether `match` is using structural-equality or method-dispatch
 // under the hood, which is the antithesis of rust-lang/rfcs#1445
 impl PartialEq for B {
+//~^ NOTE the `PartialEq` trait must be derived, manual `impl`s are not sufficient
+//~| NOTE the `PartialEq` trait must be derived, manual `impl`s are not sufficient
     fn eq(&self, other: &B) -> bool { std::cmp::min(self.0, other.0) == 0 }
 }
 
 fn main() {
     const RR_B0: & & B = & & B(0);
     const RR_B1: & & B = & & B(1);
+    //~^ NOTE constant defined here
+    //~| NOTE constant defined here
 
     match RR_B0 {
         RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); }
-        //~^ ERROR must be annotated with `#[derive(PartialEq)]`
+        //~^ ERROR constant of non-structural type `B` in a pattern
+        //~| NOTE constant of non-structural type
         _ => { }
     }
 
     match RR_B1 {
         RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); }
-        //~^ ERROR must be annotated with `#[derive(PartialEq)]`
+        //~^ ERROR constant of non-structural type `B` in a pattern
+        //~| NOTE constant of non-structural type
         _ => { }
     }
 }
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr
index 5cfe6dabc89..34fffd99c2c 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr
@@ -1,26 +1,38 @@
-error: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq)]`
-  --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:29:9
+error: constant of non-structural type `B` in a pattern
+  --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:35:9
    |
+LL | struct B(i32);
+   | -------- `B` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+...
 LL |     const RR_B1: & & B = & & B(1);
    |     ------------------ constant defined here
 ...
 LL |         RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); }
-   |         ^^^^^
+   |         ^^^^^ constant of non-structural type
+   |
+note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+  --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:22:1
    |
-   = note: the traits must be derived, manual `impl`s are not sufficient
-   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+LL | impl PartialEq for B {
+   | ^^^^^^^^^^^^^^^^^^^^
 
-error: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq)]`
-  --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:35:9
+error: constant of non-structural type `B` in a pattern
+  --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:42:9
    |
+LL | struct B(i32);
+   | -------- `B` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+...
 LL |     const RR_B1: & & B = & & B(1);
    |     ------------------ constant defined here
 ...
 LL |         RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); }
-   |         ^^^^^
+   |         ^^^^^ constant of non-structural type
+   |
+note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+  --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:22:1
    |
-   = note: the traits must be derived, manual `impl`s are not sufficient
-   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+LL | impl PartialEq for B {
+   | ^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs
index 9020eb291f5..74394698fbc 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs
@@ -1,3 +1,5 @@
+// Note: It is no longer true that both `Eq` and `PartialEq` must the derived, only the later.
+
 #[derive(Eq)]
 struct Foo {
     x: u32
@@ -15,7 +17,7 @@ fn main() {
     let y = Foo { x: 1 };
     match y {
         FOO => { }
-        //~^ ERROR must be annotated with `#[derive(PartialEq)]`
+        //~^ ERROR constant of non-structural type `Foo` in a pattern
         _ => { }
     }
 }
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.stderr
index c471fe57254..bbcab3b62d0 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.stderr
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.stderr
@@ -1,14 +1,20 @@
-error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq)]`
-  --> $DIR/match-requires-both-partialeq-and-eq.rs:17:9
+error: constant of non-structural type `Foo` in a pattern
+  --> $DIR/match-requires-both-partialeq-and-eq.rs:19:9
    |
+LL | struct Foo {
+   | ---------- `Foo` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+...
 LL | const FOO: Foo = Foo { x: 0 };
    | -------------- constant defined here
 ...
 LL |         FOO => { }
-   |         ^^^
+   |         ^^^ constant of non-structural type
+   |
+note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+  --> $DIR/match-requires-both-partialeq-and-eq.rs:8:1
    |
-   = note: the traits must be derived, manual `impl`s are not sufficient
-   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+LL | impl PartialEq for Foo {
+   | ^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error