about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeón Orell Valerian Liehr <me@fmease.dev>2024-12-05 07:29:54 +0100
committerGitHub <noreply@github.com>2024-12-05 07:29:54 +0100
commit626db0640952ed4cce66ca3f03bfcb8897df9eda (patch)
treecd46b6561e50cde851aaa408296067a0d31416f3
parentbc13c82e6e3ddeec1ca3d72940452ffa865837cd (diff)
parent4e6a401b224342287469a1a294bba7ad10e8641c (diff)
downloadrust-626db0640952ed4cce66ca3f03bfcb8897df9eda.tar.gz
rust-626db0640952ed4cce66ca3f03bfcb8897df9eda.zip
Rollup merge of #133233 - estebank:const-errors, r=Nadrieril
Add context to "const in pattern" errors

*Each commit addresses specific diagnostics.*

- Add primary span labels
- Point at `const` item, and `const` generic param definition
- Reword messages and notes
- Point at generic param through which an associated `const` is being referenced
- Silence const in pattern with evaluation errors when they come from `const` items that already emit a diagnostic
- On non-structural type in const used as pattern, point at the type that should derive `PartialEq`
-rw-r--r--compiler/rustc_mir_build/messages.ftl37
-rw-r--r--compiler/rustc_mir_build/src/errors.rs30
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs309
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs14
-rw-r--r--src/tools/tidy/src/fluent_period.rs1
-rw-r--r--tests/ui/associated-consts/associated-const-type-parameter-pattern.rs8
-rw-r--r--tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr47
-rw-r--r--tests/ui/binding/const-param.rs2
-rw-r--r--tests/ui/binding/const-param.stderr7
-rw-r--r--tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs3
-rw-r--r--tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr8
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow-2.rs3
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow-2.stderr8
-rw-r--r--tests/ui/consts/const-eval/ref_to_int_match.32bit.stderr8
-rw-r--r--tests/ui/consts/const-eval/ref_to_int_match.64bit.stderr8
-rw-r--r--tests/ui/consts/const-eval/ref_to_int_match.rs2
-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.stderr28
-rw-r--r--tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.stderr36
-rw-r--r--tests/ui/consts/const_in_pattern/issue-44333.stderr18
-rw-r--r--tests/ui/consts/const_in_pattern/issue-65466.rs2
-rw-r--r--tests/ui/consts/const_in_pattern/issue-65466.stderr12
-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.stderr11
-rw-r--r--tests/ui/consts/const_in_pattern/reject_non_partial_eq.rs2
-rw-r--r--tests/ui/consts/const_in_pattern/reject_non_partial_eq.stderr12
-rw-r--r--tests/ui/consts/const_in_pattern/reject_non_structural.rs90
-rw-r--r--tests/ui/consts/const_in_pattern/reject_non_structural.stderr199
-rw-r--r--tests/ui/consts/const_refs_to_static_fail_invalid.rs6
-rw-r--r--tests/ui/consts/const_refs_to_static_fail_invalid.stderr20
-rw-r--r--tests/ui/consts/invalid-inline-const-in-match-arm.stderr2
-rw-r--r--tests/ui/consts/issue-43105.rs3
-rw-r--r--tests/ui/consts/issue-43105.stderr8
-rw-r--r--tests/ui/consts/issue-73976-polymorphic.rs4
-rw-r--r--tests/ui/consts/issue-73976-polymorphic.stderr22
-rw-r--r--tests/ui/consts/issue-78655.rs3
-rw-r--r--tests/ui/consts/issue-78655.stderr8
-rw-r--r--tests/ui/consts/issue-79137-toogeneric.rs2
-rw-r--r--tests/ui/consts/issue-79137-toogeneric.stderr11
-rw-r--r--tests/ui/consts/issue-87046.stderr3
-rw-r--r--tests/ui/consts/issue-89088.rs2
-rw-r--r--tests/ui/consts/issue-89088.stderr11
-rw-r--r--tests/ui/consts/match_ice.rs3
-rw-r--r--tests/ui/consts/match_ice.stderr11
-rw-r--r--tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs12
-rw-r--r--tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr26
-rw-r--r--tests/ui/consts/missing_assoc_const_type.rs5
-rw-r--r--tests/ui/consts/missing_assoc_const_type.stderr8
-rw-r--r--tests/ui/consts/transmute-size-mismatch-before-typeck.rs2
-rw-r--r--tests/ui/consts/transmute-size-mismatch-before-typeck.stderr8
-rw-r--r--tests/ui/inline-const/const-match-pat-generic.rs4
-rw-r--r--tests/ui/inline-const/const-match-pat-generic.stderr8
-rw-r--r--tests/ui/inline-const/pat-match-fndef.stderr4
-rw-r--r--tests/ui/match/issue-70972-dyn-trait.stderr7
-rw-r--r--tests/ui/match/issue-72896-non-partial-eq-const.rs2
-rw-r--r--tests/ui/match/issue-72896-non-partial-eq-const.stderr12
-rw-r--r--tests/ui/pattern/issue-115599.rs2
-rw-r--r--tests/ui/pattern/issue-115599.stderr11
-rw-r--r--tests/ui/pattern/issue-72565.stderr7
-rw-r--r--tests/ui/pattern/non-constant-in-const-path.stderr14
-rw-r--r--tests/ui/pattern/non-structural-match-types.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.stderr17
-rw-r--r--tests/ui/pattern/usefulness/consts-opaque.stderr72
-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.stderr17
-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.stderr17
-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.stderr17
-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.stderr17
-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.stderr17
-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.stderr17
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-not-structurally-matchable.stderr90
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.rs3
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.stderr12
-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.stderr38
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr18
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.stderr35
-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.stderr19
-rw-r--r--tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr7
-rw-r--r--tests/ui/type-alias-impl-trait/structural-match.stderr7
-rw-r--r--tests/ui/union/union-const-pat.stderr5
88 files changed, 1117 insertions, 511 deletions
diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl
index f28cf84fa69..f647486f62a 100644
--- a/compiler/rustc_mir_build/messages.ftl
+++ b/compiler/rustc_mir_build/messages.ftl
@@ -84,12 +84,17 @@ mir_build_call_to_unsafe_fn_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
 
 mir_build_confused = missing patterns are not covered because `{$variable}` is interpreted as a constant pattern, not a new variable
 
-mir_build_const_param_in_pattern = const parameters cannot be referenced in patterns
+mir_build_const_defined_here = constant defined here
 
-mir_build_const_pattern_depends_on_generic_parameter =
-    constant pattern depends on a generic parameter
+mir_build_const_param_in_pattern = constant parameters cannot be referenced in patterns
+    .label = can't be used in patterns
+mir_build_const_param_in_pattern_def = constant defined here
+
+mir_build_const_pattern_depends_on_generic_parameter = constant pattern cannot depend on generic parameters
+    .label = `const` depends on a generic parameter
 
 mir_build_could_not_eval_const_pattern = could not evaluate constant pattern
+    .label = could not evaluate constant
 
 mir_build_deref_raw_pointer_requires_unsafe =
     dereference of raw pointer is unsafe and requires unsafe block
@@ -147,7 +152,8 @@ mir_build_inline_assembly_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
 
 mir_build_interpreted_as_const = introduce a variable instead
 
-mir_build_invalid_pattern = `{$non_sm_ty}` cannot be used in patterns
+mir_build_invalid_pattern = {$prefix} `{$non_sm_ty}` cannot be used in patterns
+    .label = {$prefix} can't be used in patterns
 
 mir_build_irrefutable_let_patterns_if_let = irrefutable `if let` {$count ->
         [one] pattern
@@ -244,10 +250,12 @@ mir_build_mutation_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsa
     .label = mutation of layout constrained field
 
 mir_build_nan_pattern = cannot use NaN in patterns
+    .label = evaluates to `NaN`, which is not allowed in patterns
     .note = NaNs compare inequal to everything, even themselves, so this pattern would never match
     .help = try using the `is_nan` method instead
 
 mir_build_non_const_path = runtime values cannot be referenced in patterns
+    .label = references a runtime value
 
 mir_build_non_empty_never_pattern =
     mismatched types
@@ -265,13 +273,15 @@ mir_build_non_exhaustive_patterns_type_not_empty = non-exhaustive patterns: type
     .suggestion = ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
     .help = ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
 
-mir_build_non_partial_eq_match =
-    to use a constant of type `{$non_peq_ty}` in a pattern, the type must implement `PartialEq`
+mir_build_non_partial_eq_match = constant of non-structural type `{$ty}` in a pattern
+    .label = constant of non-structural type
 
 mir_build_pattern_not_covered = refutable pattern in {$origin}
     .pattern_ty = the matched value is of type `{$pattern_ty}`
 
-mir_build_pointer_pattern = function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+mir_build_pointer_pattern = function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
+    .label = can't be used in patterns
+    .note = see https://github.com/rust-lang/rust/issues/70861 for details
 
 mir_build_privately_uninhabited = pattern `{$witness_1}` is currently uninhabited, but this variant contains private fields which may become inhabited in the future
 
@@ -283,6 +293,8 @@ mir_build_rustc_box_attribute_error = `#[rustc_box]` attribute used incorrectly
     .missing_box = `#[rustc_box]` requires the `owned_box` lang item
 
 mir_build_static_in_pattern = statics cannot be referenced in patterns
+    .label = can't be used in patterns
+mir_build_static_in_pattern_def = `static` defined here
 
 mir_build_suggest_attempted_int_lit = alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits
 
@@ -310,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 `{$ty}` in a pattern
+    .label = constant of non-structural type
+mir_build_type_not_structural_def = `{$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
@@ -334,6 +346,7 @@ mir_build_union_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
     .label = access to union field
 
 mir_build_union_pattern = cannot use unions in constant patterns
+    .label = can't use a `union` here
 
 mir_build_unreachable_making_this_unreachable = collectively making this unreachable
 
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index 58487a48184..3632da943e1 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -631,20 +631,27 @@ pub(crate) struct NonExhaustiveMatchAllArmsGuarded;
 #[diag(mir_build_static_in_pattern, code = E0158)]
 pub(crate) struct StaticInPattern {
     #[primary_span]
+    #[label]
     pub(crate) span: Span,
+    #[label(mir_build_static_in_pattern_def)]
+    pub(crate) static_span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(mir_build_const_param_in_pattern, code = E0158)]
 pub(crate) struct ConstParamInPattern {
     #[primary_span]
+    #[label]
     pub(crate) span: Span,
+    #[label(mir_build_const_param_in_pattern_def)]
+    pub(crate) const_span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(mir_build_non_const_path, code = E0080)]
 pub(crate) struct NonConstPath {
     #[primary_span]
+    #[label]
     pub(crate) span: Span,
 }
 
@@ -695,6 +702,7 @@ pub(crate) struct WantedConstant {
 #[diag(mir_build_const_pattern_depends_on_generic_parameter, code = E0158)]
 pub(crate) struct ConstPatternDependsOnGenericParameter {
     #[primary_span]
+    #[label]
     pub(crate) span: Span,
 }
 
@@ -702,6 +710,7 @@ pub(crate) struct ConstPatternDependsOnGenericParameter {
 #[diag(mir_build_could_not_eval_const_pattern)]
 pub(crate) struct CouldNotEvalConstPattern {
     #[primary_span]
+    #[label]
     pub(crate) span: Span,
 }
 
@@ -867,33 +876,43 @@ pub(crate) enum Conflict {
 #[diag(mir_build_union_pattern)]
 pub(crate) struct UnionPattern {
     #[primary_span]
+    #[label]
     pub(crate) span: Span,
 }
 
 #[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,
-    pub(crate) non_sm_ty: Ty<'tcx>,
+    #[label(mir_build_type_not_structural_def)]
+    pub(crate) ty_def_span: Span,
+    pub(crate) 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)]
 #[diag(mir_build_non_partial_eq_match)]
+#[note(mir_build_type_not_structural_more_info)]
 pub(crate) struct TypeNotPartialEq<'tcx> {
     #[primary_span]
+    #[label]
     pub(crate) span: Span,
-    pub(crate) non_peq_ty: Ty<'tcx>,
+    pub(crate) ty: Ty<'tcx>,
 }
 
 #[derive(Diagnostic)]
 #[diag(mir_build_invalid_pattern)]
 pub(crate) struct InvalidPattern<'tcx> {
     #[primary_span]
+    #[label]
     pub(crate) span: Span,
     pub(crate) non_sm_ty: Ty<'tcx>,
+    pub(crate) prefix: String,
 }
 
 #[derive(Diagnostic)]
@@ -910,13 +929,16 @@ pub(crate) struct UnsizedPattern<'tcx> {
 #[help]
 pub(crate) struct NaNPattern {
     #[primary_span]
+    #[label]
     pub(crate) span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(mir_build_pointer_pattern)]
+#[note]
 pub(crate) struct PointerPattern {
     #[primary_span]
+    #[label]
     pub(crate) span: Span,
 }
 
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 5db08f01fdb..aed00aecefc 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
@@ -1,14 +1,17 @@
 use rustc_abi::{FieldIdx, VariantIdx};
 use rustc_apfloat::Float;
+use rustc_data_structures::fx::FxHashSet;
+use rustc_errors::Diag;
 use rustc_hir as hir;
 use rustc_index::Idx;
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::traits::Obligation;
 use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::thir::{FieldPat, Pat, PatKind};
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, ValTree};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypeVisitor, ValTree};
 use rustc_middle::{mir, span_bug};
-use rustc_span::Span;
+use rustc_span::def_id::DefId;
+use rustc_span::{Span, sym};
 use rustc_trait_selection::traits::ObligationCause;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
 use tracing::{debug, instrument, trace};
@@ -35,7 +38,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         id: hir::HirId,
         span: Span,
     ) -> Box<Pat<'tcx>> {
-        let mut convert = ConstToPat::new(self, id, span);
+        let mut convert = ConstToPat::new(self, id, span, c);
 
         match c.kind() {
             ty::ConstKind::Unevaluated(uv) => convert.unevaluated_to_pat(uv, ty),
@@ -49,21 +52,26 @@ struct ConstToPat<'tcx> {
     tcx: TyCtxt<'tcx>,
     typing_env: ty::TypingEnv<'tcx>,
     span: Span,
+    id: hir::HirId,
 
     treat_byte_string_as_slice: bool,
+
+    c: ty::Const<'tcx>,
 }
 
 impl<'tcx> ConstToPat<'tcx> {
-    fn new(pat_ctxt: &PatCtxt<'_, 'tcx>, id: hir::HirId, span: Span) -> Self {
+    fn new(pat_ctxt: &PatCtxt<'_, 'tcx>, id: hir::HirId, span: Span, c: ty::Const<'tcx>) -> Self {
         trace!(?pat_ctxt.typeck_results.hir_owner);
         ConstToPat {
             tcx: pat_ctxt.tcx,
             typing_env: pat_ctxt.typing_env,
             span,
+            id,
             treat_byte_string_as_slice: pat_ctxt
                 .typeck_results
                 .treat_byte_string_as_slice
                 .contains(&id.local_id),
+            c,
         }
     }
 
@@ -71,13 +79,32 @@ impl<'tcx> ConstToPat<'tcx> {
         ty.is_structural_eq_shallow(self.tcx)
     }
 
+    /// We errored. Signal that in the pattern, so that follow up errors can be silenced.
+    fn mk_err(&self, mut err: Diag<'_>, ty: Ty<'tcx>) -> Box<Pat<'tcx>> {
+        if let ty::ConstKind::Unevaluated(uv) = self.c.kind() {
+            let def_kind = self.tcx.def_kind(uv.def);
+            if let hir::def::DefKind::AssocConst = def_kind
+                && let Some(def_id) = uv.def.as_local()
+            {
+                // Include the container item in the output.
+                err.span_label(self.tcx.def_span(self.tcx.local_parent(def_id)), "");
+            }
+            if let hir::def::DefKind::Const | hir::def::DefKind::AssocConst = def_kind {
+                err.span_label(
+                    self.tcx.def_span(uv.def),
+                    crate::fluent_generated::mir_build_const_defined_here,
+                );
+            }
+        }
+        Box::new(Pat { span: self.span, ty, kind: PatKind::Error(err.emit()) })
+    }
+
     fn unevaluated_to_pat(
         &mut self,
         uv: ty::UnevaluatedConst<'tcx>,
         ty: Ty<'tcx>,
     ) -> Box<Pat<'tcx>> {
         trace!(self.treat_byte_string_as_slice);
-        let pat_from_kind = |kind| Box::new(Pat { span: self.span, ty, kind });
 
         // It's not *technically* correct to be revealing opaque types here as borrowcheck has
         // not run yet. However, CTFE itself uses `TypingMode::PostAnalysis` unconditionally even
@@ -96,32 +123,60 @@ impl<'tcx> ConstToPat<'tcx> {
             Ok(Ok(c)) => c,
             Err(ErrorHandled::Reported(_, _)) => {
                 // Let's tell the use where this failing const occurs.
-                let e = self.tcx.dcx().emit_err(CouldNotEvalConstPattern { span: self.span });
-                return pat_from_kind(PatKind::Error(e));
+                let mut err =
+                    self.tcx.dcx().create_err(CouldNotEvalConstPattern { span: self.span });
+                // We've emitted an error on the original const, it would be redundant to complain
+                // on its use as well.
+                if let ty::ConstKind::Unevaluated(uv) = self.c.kind()
+                    && let hir::def::DefKind::Const | hir::def::DefKind::AssocConst =
+                        self.tcx.def_kind(uv.def)
+                {
+                    err.downgrade_to_delayed_bug();
+                }
+                return self.mk_err(err, ty);
             }
             Err(ErrorHandled::TooGeneric(_)) => {
-                let e = self
+                let mut e = self
                     .tcx
                     .dcx()
-                    .emit_err(ConstPatternDependsOnGenericParameter { span: self.span });
-                return pat_from_kind(PatKind::Error(e));
+                    .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 parameter");
+                        if let Some(ident) = self.tcx.def_ident_span(def_id)
+                            && self.tcx.sess.source_map().is_multiline(ident.between(span))
+                        {
+                            // Display the `fn` name as well in the diagnostic, as the generic isn't
+                            // in the same line and it could be confusing otherwise.
+                            e.span_label(ident, "");
+                        }
+                    }
+                }
+                return self.mk_err(e, ty);
             }
             Ok(Err(bad_ty)) => {
                 // The pattern cannot be turned into a valtree.
                 let e = match bad_ty.kind() {
                     ty::Adt(def, ..) => {
                         assert!(def.is_union());
-                        self.tcx.dcx().emit_err(UnionPattern { span: self.span })
+                        self.tcx.dcx().create_err(UnionPattern { span: self.span })
                     }
                     ty::FnPtr(..) | ty::RawPtr(..) => {
-                        self.tcx.dcx().emit_err(PointerPattern { span: self.span })
+                        self.tcx.dcx().create_err(PointerPattern { span: self.span })
                     }
-                    _ => self
-                        .tcx
-                        .dcx()
-                        .emit_err(InvalidPattern { span: self.span, non_sm_ty: bad_ty }),
+                    _ => self.tcx.dcx().create_err(InvalidPattern {
+                        span: self.span,
+                        non_sm_ty: bad_ty,
+                        prefix: bad_ty.prefix_string(self.tcx).to_string(),
+                    }),
                 };
-                return pat_from_kind(PatKind::Error(e));
+                return self.mk_err(e, ty);
             }
         };
 
@@ -130,42 +185,16 @@ impl<'tcx> ConstToPat<'tcx> {
 
         if !inlined_const_as_pat.references_error() {
             // Always check for `PartialEq` if we had no other errors yet.
-            if !self.type_has_partial_eq_impl(ty) {
-                let err = TypeNotPartialEq { span: self.span, non_peq_ty: ty };
-                let e = self.tcx.dcx().emit_err(err);
-                return pat_from_kind(PatKind::Error(e));
+            if !type_has_partial_eq_impl(self.tcx, typing_env, ty).0 {
+                let mut err = self.tcx.dcx().create_err(TypeNotPartialEq { span: self.span, ty });
+                extend_type_not_partial_eq(self.tcx, typing_env, ty, &mut err);
+                return self.mk_err(err, ty);
             }
         }
 
         inlined_const_as_pat
     }
 
-    #[instrument(level = "trace", skip(self), ret)]
-    fn type_has_partial_eq_impl(&self, ty: Ty<'tcx>) -> bool {
-        let (infcx, param_env) = self.tcx.infer_ctxt().build_with_typing_env(self.typing_env);
-        // double-check there even *is* a semantic `PartialEq` to dispatch to.
-        //
-        // (If there isn't, then we can safely issue a hard
-        // error, because that's never worked, due to compiler
-        // using `PartialEq::eq` in this scenario in the past.)
-        let partial_eq_trait_id =
-            self.tcx.require_lang_item(hir::LangItem::PartialEq, Some(self.span));
-        let partial_eq_obligation = Obligation::new(
-            self.tcx,
-            ObligationCause::dummy(),
-            param_env,
-            ty::TraitRef::new(self.tcx, partial_eq_trait_id, [ty, ty]),
-        );
-
-        // This *could* accept a type that isn't actually `PartialEq`, because region bounds get
-        // ignored. However that should be pretty much impossible since consts that do not depend on
-        // generics can only mention the `'static` lifetime, and how would one have a type that's
-        // `PartialEq` for some lifetime but *not* for `'static`? If this ever becomes a problem
-        // we'll need to leave some sort of trace of this requirement in the MIR so that borrowck
-        // can ensure that the type really implements `PartialEq`.
-        infcx.predicate_must_hold_modulo_regions(&partial_eq_obligation)
-    }
-
     fn field_pats(
         &self,
         vals: impl Iterator<Item = (ValTree<'tcx>, Ty<'tcx>)>,
@@ -190,10 +219,25 @@ 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 e = tcx.dcx().emit_err(err);
-                // We errored. Signal that in the pattern, so that follow up errors can be silenced.
-                PatKind::Error(e)
+                let (_impls_partial_eq, derived, structural, impl_def_id) =
+                    type_has_partial_eq_impl(self.tcx, self.typing_env, ty);
+                let (manual_partialeq_impl_span, manual_partialeq_impl_note) =
+                    match (structural, impl_def_id) {
+                        (true, _) => (None, false),
+                        (_, Some(def_id)) if def_id.is_local() && !derived => {
+                            (Some(tcx.def_span(def_id)), false)
+                        }
+                        _ => (None, true),
+                    };
+                let ty_def_span = tcx.def_span(adt_def.did());
+                let err = TypeNotStructural {
+                    span,
+                    ty,
+                    ty_def_span,
+                    manual_partialeq_impl_span,
+                    manual_partialeq_impl_note,
+                };
+                return self.mk_err(tcx.dcx().create_err(err), ty);
             }
             ty::Adt(adt_def, args) if adt_def.is_enum() => {
                 let (&variant_index, fields) = cv.unwrap_branch().split_first().unwrap();
@@ -207,7 +251,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)),
                         ),
                     ),
                 }
@@ -216,7 +260,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)),
                     )),
                 }
             }
@@ -252,10 +296,10 @@ impl<'tcx> ConstToPat<'tcx> {
                 // deref pattern.
                 _ => {
                     if !pointee_ty.is_sized(tcx, self.typing_env) && !pointee_ty.is_slice() {
-                        let err = UnsizedPattern { span, non_sm_ty: *pointee_ty };
-                        let e = tcx.dcx().emit_err(err);
-                        // We errored. Signal that in the pattern, so that follow up errors can be silenced.
-                        PatKind::Error(e)
+                        return self.mk_err(
+                            tcx.dcx().create_err(UnsizedPattern { span, non_sm_ty: *pointee_ty }),
+                            ty,
+                        );
                     } else {
                         // `b"foo"` produces a `&[u8; 3]`, but you can't use constants of array type when
                         // matching against references, you can only use byte string literals.
@@ -286,8 +330,7 @@ impl<'tcx> ConstToPat<'tcx> {
                 if is_nan {
                     // NaNs are not ever equal to anything so they make no sense as patterns.
                     // Also see <https://github.com/rust-lang/rfcs/pull/3535>.
-                    let e = tcx.dcx().emit_err(NaNPattern { span });
-                    PatKind::Error(e)
+                    return self.mk_err(tcx.dcx().create_err(NaNPattern { span }), ty);
                 } else {
                     PatKind::Constant {
                         value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)),
@@ -305,13 +348,153 @@ impl<'tcx> ConstToPat<'tcx> {
                 )
             }
             _ => {
-                let err = InvalidPattern { span, non_sm_ty: ty };
-                let e = tcx.dcx().emit_err(err);
-                // We errored. Signal that in the pattern, so that follow up errors can be silenced.
-                PatKind::Error(e)
+                let err = InvalidPattern {
+                    span,
+                    non_sm_ty: ty,
+                    prefix: ty.prefix_string(tcx).to_string(),
+                };
+                return self.mk_err(tcx.dcx().create_err(err), ty);
             }
         };
 
         Box::new(Pat { span, ty, kind })
     }
 }
+
+/// Given a type with type parameters, visit every ADT looking for types that need to
+/// `#[derive(PartialEq)]` for it to be a structural type.
+fn extend_type_not_partial_eq<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    typing_env: ty::TypingEnv<'tcx>,
+    ty: Ty<'tcx>,
+    err: &mut Diag<'_>,
+) {
+    /// Collect all types that need to be `StructuralPartialEq`.
+    struct UsedParamsNeedInstantiationVisitor<'tcx> {
+        tcx: TyCtxt<'tcx>,
+        typing_env: ty::TypingEnv<'tcx>,
+        /// The user has written `impl PartialEq for Ty` which means it's non-structual.
+        adts_with_manual_partialeq: FxHashSet<Span>,
+        /// The type has no `PartialEq` implementation, neither manual or derived.
+        adts_without_partialeq: FxHashSet<Span>,
+        /// The user has written `impl PartialEq for Ty` which means it's non-structual,
+        /// but we don't have a span to point at, so we'll just add them as a `note`.
+        manual: Vec<Ty<'tcx>>,
+        /// The type has no `PartialEq` implementation, neither manual or derived, but
+        /// we don't have a span to point at, so we'll just add them as a `note`.
+        without: Vec<Ty<'tcx>>,
+    }
+
+    impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for UsedParamsNeedInstantiationVisitor<'tcx> {
+        fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
+            if let ty::Adt(def, _args) = ty.kind() {
+                let ty_def_id = def.did();
+                let ty_def_span = self.tcx.def_span(ty_def_id);
+                let (impls_partial_eq, derived, structural, impl_def_id) =
+                    type_has_partial_eq_impl(self.tcx, self.typing_env, ty);
+                match (impls_partial_eq, derived, structural, impl_def_id) {
+                    (_, _, true, _) => {}
+                    (true, false, _, Some(def_id)) if def_id.is_local() => {
+                        self.adts_with_manual_partialeq.insert(self.tcx.def_span(def_id));
+                    }
+                    (true, false, _, _) if ty_def_id.is_local() => {
+                        self.adts_with_manual_partialeq.insert(ty_def_span);
+                    }
+                    (false, _, _, _) if ty_def_id.is_local() => {
+                        self.adts_without_partialeq.insert(ty_def_span);
+                    }
+                    (true, false, _, _) => {
+                        self.manual.push(ty);
+                    }
+                    (false, _, _, _) => {
+                        self.without.push(ty);
+                    }
+                    _ => {}
+                };
+            }
+            use rustc_middle::ty::TypeSuperVisitable;
+            ty.super_visit_with(self)
+        }
+    }
+    let mut v = UsedParamsNeedInstantiationVisitor {
+        tcx,
+        typing_env,
+        adts_with_manual_partialeq: FxHashSet::default(),
+        adts_without_partialeq: FxHashSet::default(),
+        manual: vec![],
+        without: vec![],
+    };
+    v.visit_ty(ty);
+    #[allow(rustc::potential_query_instability)] // Span labels will be sorted by the rendering
+    for span in v.adts_with_manual_partialeq {
+        err.span_note(span, "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");
+    }
+    #[allow(rustc::potential_query_instability)] // Span labels will be sorted by the rendering
+    for span in v.adts_without_partialeq {
+        err.span_label(
+            span,
+            "must be annotated with `#[derive(PartialEq)]` to be usable in patterns",
+        );
+    }
+    for ty in v.manual {
+        err.note(format!(
+            "`{ty}` must be annotated with `#[derive(PartialEq)]` to be usable in patterns, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details"
+        ));
+    }
+    for ty in v.without {
+        err.note(format!(
+            "`{ty}` must be annotated with `#[derive(PartialEq)]` to be usable in patterns"
+        ));
+    }
+}
+
+#[instrument(level = "trace", skip(tcx), ret)]
+fn type_has_partial_eq_impl<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    typing_env: ty::TypingEnv<'tcx>,
+    ty: Ty<'tcx>,
+) -> (
+    /* has impl */ bool,
+    /* is derived */ bool,
+    /* structural partial eq */ bool,
+    /* non-blanket impl */ Option<DefId>,
+) {
+    let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
+    // double-check there even *is* a semantic `PartialEq` to dispatch to.
+    //
+    // (If there isn't, then we can safely issue a hard
+    // error, because that's never worked, due to compiler
+    // using `PartialEq::eq` in this scenario in the past.)
+    let partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::PartialEq, None);
+    let structural_partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::StructuralPeq, None);
+
+    let partial_eq_obligation = Obligation::new(
+        tcx,
+        ObligationCause::dummy(),
+        param_env,
+        ty::TraitRef::new(tcx, partial_eq_trait_id, [ty, ty]),
+    );
+
+    let mut automatically_derived = false;
+    let mut structural_peq = false;
+    let mut impl_def_id = None;
+    for def_id in tcx.non_blanket_impls_for_ty(partial_eq_trait_id, ty) {
+        automatically_derived = tcx.has_attr(def_id, sym::automatically_derived);
+        impl_def_id = Some(def_id);
+    }
+    for _ in tcx.non_blanket_impls_for_ty(structural_partial_eq_trait_id, ty) {
+        structural_peq = true;
+    }
+    // This *could* accept a type that isn't actually `PartialEq`, because region bounds get
+    // ignored. However that should be pretty much impossible since consts that do not depend on
+    // generics can only mention the `'static` lifetime, and how would one have a type that's
+    // `PartialEq` for some lifetime but *not* for `'static`? If this ever becomes a problem
+    // we'll need to leave some sort of trace of this requirement in the MIR so that borrowck
+    // can ensure that the type really implements `PartialEq`.
+    (
+        infcx.predicate_must_hold_modulo_regions(&partial_eq_obligation),
+        automatically_derived,
+        structural_peq,
+        impl_def_id,
+    )
+}
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 08c6b4abd3b..3ac53fa6272 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -528,11 +528,17 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
             | Res::SelfCtor(..) => PatKind::Leaf { subpatterns },
             _ => {
                 let e = match res {
-                    Res::Def(DefKind::ConstParam, _) => {
-                        self.tcx.dcx().emit_err(ConstParamInPattern { span })
+                    Res::Def(DefKind::ConstParam, def_id) => {
+                        self.tcx.dcx().emit_err(ConstParamInPattern {
+                            span,
+                            const_span: self.tcx().def_span(def_id),
+                        })
                     }
-                    Res::Def(DefKind::Static { .. }, _) => {
-                        self.tcx.dcx().emit_err(StaticInPattern { span })
+                    Res::Def(DefKind::Static { .. }, def_id) => {
+                        self.tcx.dcx().emit_err(StaticInPattern {
+                            span,
+                            static_span: self.tcx().def_span(def_id),
+                        })
                     }
                     _ => self.tcx.dcx().emit_err(NonConstPath { span }),
                 };
diff --git a/src/tools/tidy/src/fluent_period.rs b/src/tools/tidy/src/fluent_period.rs
index 8bc404dc858..6a136e5aec6 100644
--- a/src/tools/tidy/src/fluent_period.rs
+++ b/src/tools/tidy/src/fluent_period.rs
@@ -18,7 +18,6 @@ const ALLOWLIST: &[&str] = &[
     "const_eval_validation_failure_note",
     "driver_impl_ice",
     "incremental_corrupt_file",
-    "mir_build_pointer_pattern",
 ];
 
 fn check_period(filename: &str, contents: &str, bad: &mut bool) {
diff --git a/tests/ui/associated-consts/associated-const-type-parameter-pattern.rs b/tests/ui/associated-consts/associated-const-type-parameter-pattern.rs
index b5798adc71c..e6c80a7e54e 100644
--- a/tests/ui/associated-consts/associated-const-type-parameter-pattern.rs
+++ b/tests/ui/associated-consts/associated-const-type-parameter-pattern.rs
@@ -18,17 +18,17 @@ impl Foo for Def {
 pub fn test<A: Foo, B: Foo>(arg: EFoo) {
     match arg {
         A::X => println!("A::X"),
-        //~^ error: constant pattern depends on a generic parameter
+        //~^ ERROR constant pattern cannot depend on generic parameters
         B::X => println!("B::X"),
-        //~^ error: constant pattern depends on a generic parameter
+        //~^ ERROR constant pattern cannot depend on generic parameters
         _ => (),
     }
 }
 
 pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
-    //~^ ERROR constant pattern depends on a generic parameter
+    //~^ ERROR constant pattern cannot depend on generic parameters
     let A::X = arg;
-    //~^ ERROR constant pattern depends on a generic parameter
+    //~^ ERROR constant pattern cannot depend on generic parameters
 }
 
 fn main() {
diff --git a/tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr b/tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr
index adc8f399207..a8256f775a6 100644
--- a/tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr
+++ b/tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr
@@ -1,26 +1,57 @@
-error[E0158]: constant pattern depends on a generic parameter
+error[E0158]: constant pattern cannot depend on generic parameters
   --> $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 parameter
+LL |     match arg {
 LL |         A::X => println!("A::X"),
-   |         ^^^^
+   |         ^^^^ `const` depends on a generic parameter
 
-error[E0158]: constant pattern depends on a generic parameter
+error[E0158]: constant pattern cannot depend on generic parameters
   --> $DIR/associated-const-type-parameter-pattern.rs:22: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 parameter
+...
 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 cannot depend on generic parameters
   --> $DIR/associated-const-type-parameter-pattern.rs:30:9
    |
+LL | pub trait Foo {
+   | -------------
+LL |     const X: EFoo;
+   |     ------------- constant defined here
+...
+LL | pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
+   |                     - constant depends on this generic parameter
+LL |
 LL |     let A::X = arg;
-   |         ^^^^
+   |         ^^^^ `const` depends on a generic parameter
 
-error[E0158]: constant pattern depends on a generic parameter
+error[E0158]: constant pattern cannot depend on generic parameters
   --> $DIR/associated-const-type-parameter-pattern.rs:28:48
    |
+LL | pub trait Foo {
+   | -------------
+LL |     const X: EFoo;
+   |     ------------- constant defined here
+...
 LL | pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
-   |                                                ^^^^
+   |                     -                          ^^^^ `const` depends on a generic parameter
+   |                     |
+   |                     constant depends on this generic parameter
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/binding/const-param.rs b/tests/ui/binding/const-param.rs
index 2d051808fe0..98bc90f508a 100644
--- a/tests/ui/binding/const-param.rs
+++ b/tests/ui/binding/const-param.rs
@@ -2,7 +2,7 @@
 
 fn check<const N: usize>() {
     match 1 {
-        N => {} //~ ERROR const parameters cannot be referenced in patterns
+        N => {} //~ ERROR constant parameters cannot be referenced in patterns
         _ => {}
     }
 }
diff --git a/tests/ui/binding/const-param.stderr b/tests/ui/binding/const-param.stderr
index e68893a59e4..b0b8108945c 100644
--- a/tests/ui/binding/const-param.stderr
+++ b/tests/ui/binding/const-param.stderr
@@ -1,8 +1,11 @@
-error[E0158]: const parameters cannot be referenced in patterns
+error[E0158]: constant parameters cannot be referenced in patterns
   --> $DIR/const-param.rs:5:9
    |
+LL | fn check<const N: usize>() {
+   |          -------------- constant defined here
+LL |     match 1 {
 LL |         N => {}
-   |         ^
+   |         ^ can't be used in patterns
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs
index 09f7e2ba5b1..270496d45a6 100644
--- a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs
+++ b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs
@@ -12,8 +12,7 @@ impl Opcode2 {
 
 pub fn example2(msg_type: Opcode2) -> impl FnMut(&[u8]) {
     move |i| match msg_type {
-        Opcode2::OP2 => unimplemented!(),
-        //~^ ERROR: could not evaluate constant pattern
+        Opcode2::OP2 => unimplemented!(), // ok, `const` already emitted an error
     }
 }
 
diff --git a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr
index 9442eac0cf5..d95a8861230 100644
--- a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr
+++ b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr
@@ -17,13 +17,7 @@ help: you might be missing a type parameter
 LL | pub struct Opcode2<S>(&'a S);
    |                   +++
 
-error: could not evaluate constant pattern
-  --> $DIR/ice-type-mismatch-when-copying-112824.rs:15:9
-   |
-LL |         Opcode2::OP2 => unimplemented!(),
-   |         ^^^^^^^^^^^^
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0261, E0412.
 For more information about an error, try `rustc --explain E0261`.
diff --git a/tests/ui/consts/const-eval/const-eval-overflow-2.rs b/tests/ui/consts/const-eval/const-eval-overflow-2.rs
index c19a0c443ec..bae8a7ce243 100644
--- a/tests/ui/consts/const-eval/const-eval-overflow-2.rs
+++ b/tests/ui/consts/const-eval/const-eval-overflow-2.rs
@@ -12,8 +12,7 @@ const NEG_NEG_128: i8 = -NEG_128; //~ ERROR constant
 
 fn main() {
     match -128i8 {
-        NEG_NEG_128 => println!("A"),
-        //~^ ERROR could not evaluate constant pattern
+        NEG_NEG_128 => println!("A"), // ok, `const` error already emitted
         _ => println!("B"),
     }
 }
diff --git a/tests/ui/consts/const-eval/const-eval-overflow-2.stderr b/tests/ui/consts/const-eval/const-eval-overflow-2.stderr
index fc0baf11051..5599ff931e8 100644
--- a/tests/ui/consts/const-eval/const-eval-overflow-2.stderr
+++ b/tests/ui/consts/const-eval/const-eval-overflow-2.stderr
@@ -4,12 +4,6 @@ error[E0080]: evaluation of constant value failed
 LL | const NEG_NEG_128: i8 = -NEG_128;
    |                         ^^^^^^^^ attempt to negate `i8::MIN`, which would overflow
 
-error: could not evaluate constant pattern
-  --> $DIR/const-eval-overflow-2.rs:15:9
-   |
-LL |         NEG_NEG_128 => println!("A"),
-   |         ^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/ref_to_int_match.32bit.stderr b/tests/ui/consts/const-eval/ref_to_int_match.32bit.stderr
index 8175fe6016a..18935626af1 100644
--- a/tests/ui/consts/const-eval/ref_to_int_match.32bit.stderr
+++ b/tests/ui/consts/const-eval/ref_to_int_match.32bit.stderr
@@ -7,12 +7,6 @@ LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
 
-error: could not evaluate constant pattern
-  --> $DIR/ref_to_int_match.rs:7:14
-   |
-LL |         10..=BAR => {},
-   |              ^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/ref_to_int_match.64bit.stderr b/tests/ui/consts/const-eval/ref_to_int_match.64bit.stderr
index 8175fe6016a..18935626af1 100644
--- a/tests/ui/consts/const-eval/ref_to_int_match.64bit.stderr
+++ b/tests/ui/consts/const-eval/ref_to_int_match.64bit.stderr
@@ -7,12 +7,6 @@ LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
 
-error: could not evaluate constant pattern
-  --> $DIR/ref_to_int_match.rs:7:14
-   |
-LL |         10..=BAR => {},
-   |              ^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/ref_to_int_match.rs b/tests/ui/consts/const-eval/ref_to_int_match.rs
index c627ad97bb0..be9420e0215 100644
--- a/tests/ui/consts/const-eval/ref_to_int_match.rs
+++ b/tests/ui/consts/const-eval/ref_to_int_match.rs
@@ -4,7 +4,7 @@ fn main() {
     let n: Int = 40;
     match n {
         0..=10 => {},
-        10..=BAR => {}, //~ ERROR could not evaluate constant pattern
+        10..=BAR => {}, // ok, `const` error already emitted
         _ => {},
     }
 }
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 e0f97a9abd2..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,19 +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: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: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/issue-34784-match-on-non-int-raw-ptr.stderr b/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.stderr
index aa208341c13..0453a88e43d 100644
--- a/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.stderr
+++ b/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.stderr
@@ -1,26 +1,46 @@
-error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
   --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:9:9
    |
+LL | const C: *const u8 = &0;
+   | ------------------ constant defined here
+...
 LL |         C => {}
-   |         ^
+   |         ^ can't be used in patterns
+   |
+   = note: see https://github.com/rust-lang/rust/issues/70861 for details
 
-error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
   --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:16:9
    |
+LL | const C_INNER: (*const u8, u8) = (C, 0);
+   | ------------------------------ constant defined here
+...
 LL |         C_INNER => {}
-   |         ^^^^^^^
+   |         ^^^^^^^ can't be used in patterns
+   |
+   = note: see https://github.com/rust-lang/rust/issues/70861 for details
 
-error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
   --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:27:9
    |
+LL | const D: *const [u8; 4] = b"abcd";
+   | ----------------------- constant defined here
+...
 LL |         D => {}
-   |         ^
+   |         ^ can't be used in patterns
+   |
+   = note: see https://github.com/rust-lang/rust/issues/70861 for details
 
-error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
   --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:32:9
    |
+LL | const STR: *const str = "abcd";
+   | --------------------- constant defined here
+...
 LL |         STR => {}
-   |         ^^^
+   |         ^^^ can't be used in patterns
+   |
+   = note: see https://github.com/rust-lang/rust/issues/70861 for details
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/consts/const_in_pattern/issue-44333.stderr b/tests/ui/consts/const_in_pattern/issue-44333.stderr
index d377bfd95f9..61b45377c76 100644
--- a/tests/ui/consts/const_in_pattern/issue-44333.stderr
+++ b/tests/ui/consts/const_in_pattern/issue-44333.stderr
@@ -1,14 +1,24 @@
-error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
   --> $DIR/issue-44333.rs:15:9
    |
+LL | const FOO: Func = foo;
+   | --------------- constant defined here
+...
 LL |         FOO => println!("foo"),
-   |         ^^^
+   |         ^^^ can't be used in patterns
+   |
+   = note: see https://github.com/rust-lang/rust/issues/70861 for details
 
-error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
   --> $DIR/issue-44333.rs:16:9
    |
+LL | const BAR: Func = bar;
+   | --------------- constant defined here
+...
 LL |         BAR => println!("bar"),
-   |         ^^^
+   |         ^^^ can't be used in patterns
+   |
+   = note: see https://github.com/rust-lang/rust/issues/70861 for details
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/const_in_pattern/issue-65466.rs b/tests/ui/consts/const_in_pattern/issue-65466.rs
index 62efce64876..82838657b02 100644
--- a/tests/ui/consts/const_in_pattern/issue-65466.rs
+++ b/tests/ui/consts/const_in_pattern/issue-65466.rs
@@ -11,7 +11,7 @@ const C: &[O<B>] = &[O::None];
 fn main() {
     let x = O::None;
     match &[x][..] {
-        C => (), //~ERROR: the type must implement `PartialEq`
+        C => (), //~ ERROR constant of non-structural type `&[O<B>]` in a pattern
         _ => (),
     }
 }
diff --git a/tests/ui/consts/const_in_pattern/issue-65466.stderr b/tests/ui/consts/const_in_pattern/issue-65466.stderr
index 7d5e5b5b0c6..511a38bbc00 100644
--- a/tests/ui/consts/const_in_pattern/issue-65466.stderr
+++ b/tests/ui/consts/const_in_pattern/issue-65466.stderr
@@ -1,8 +1,16 @@
-error: to use a constant of type `&[O<B>]` in a pattern, the type must implement `PartialEq`
+error: constant of non-structural type `&[O<B>]` in a pattern
   --> $DIR/issue-65466.rs:14:9
    |
+LL | struct B;
+   | -------- must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+LL |
+LL | const C: &[O<B>] = &[O::None];
+   | ---------------- constant defined here
+...
 LL |         C => (),
-   |         ^
+   |         ^ constant of non-structural type
+   |
+   = 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/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 7766c6ce683..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,10 +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_partial_eq.rs b/tests/ui/consts/const_in_pattern/reject_non_partial_eq.rs
index 645e1418912..e555ecfeb8f 100644
--- a/tests/ui/consts/const_in_pattern/reject_non_partial_eq.rs
+++ b/tests/ui/consts/const_in_pattern/reject_non_partial_eq.rs
@@ -26,7 +26,7 @@ fn main() {
 
     match None {
         NO_PARTIAL_EQ_NONE => println!("NO_PARTIAL_EQ_NONE"),
-        //~^ ERROR must implement `PartialEq`
+        //~^ ERROR constant of non-structural type `Option<NoPartialEq>` in a pattern
         _ => panic!("whoops"),
     }
 }
diff --git a/tests/ui/consts/const_in_pattern/reject_non_partial_eq.stderr b/tests/ui/consts/const_in_pattern/reject_non_partial_eq.stderr
index ed531a1fead..43894f00886 100644
--- a/tests/ui/consts/const_in_pattern/reject_non_partial_eq.stderr
+++ b/tests/ui/consts/const_in_pattern/reject_non_partial_eq.stderr
@@ -1,8 +1,16 @@
-error: to use a constant of type `Option<NoPartialEq>` in a pattern, the type must implement `PartialEq`
+error: constant of non-structural type `Option<NoPartialEq>` in a pattern
   --> $DIR/reject_non_partial_eq.rs:28:9
    |
+LL | struct NoPartialEq(u32);
+   | ------------------ must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+...
+LL | const NO_PARTIAL_EQ_NONE: Option<NoPartialEq> = None;
+   | --------------------------------------------- constant defined here
+...
 LL |         NO_PARTIAL_EQ_NONE => println!("NO_PARTIAL_EQ_NONE"),
-   |         ^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^ constant of non-structural type
+   |
+   = 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 e3dcecec960..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 { }
 
@@ -36,65 +56,55 @@ fn main() {
     #[derive(PartialEq, Eq, Debug)]
     enum Derive<X> { Some(X), None, }
 
-    const ENUM: Derive<NoDerive> = Derive::Some(NoDerive);
+    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;
+    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;
+    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));
+    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);
+    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)];
+    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];
+    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>; }
+    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) };
+    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);
+    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 c068db42e4d..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,92 +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 `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: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 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 `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
-  --> $DIR/reject_non_structural.rs:53:27
+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: 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
-
-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
+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: 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 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 `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
-  --> $DIR/reject_non_structural.rs:65:28
+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: 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
-
-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
+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: 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 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 `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
-  --> $DIR/reject_non_structural.rs:77:33
+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: 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 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 `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
-  --> $DIR/reject_non_structural.rs:84:28
+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: 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
-
-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
+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: 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 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 `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
-  --> $DIR/reject_non_structural.rs:96:29
+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: 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/const_refs_to_static_fail_invalid.rs b/tests/ui/consts/const_refs_to_static_fail_invalid.rs
index a160862a0fa..aa101cf9d8a 100644
--- a/tests/ui/consts/const_refs_to_static_fail_invalid.rs
+++ b/tests/ui/consts/const_refs_to_static_fail_invalid.rs
@@ -11,7 +11,7 @@ fn invalid() {
 
     // This must be rejected here (or earlier), since it's not a valid `&bool`.
     match &true {
-        C => {} //~ERROR: could not evaluate constant pattern
+        C => {} // ok, `const` already emitted an error
         _ => {}
     }
 }
@@ -27,7 +27,7 @@ fn extern_() {
 
     // This must be rejected here (or earlier), since the pattern cannot be read.
     match &0 {
-        C => {} //~ERROR: could not evaluate constant pattern
+        C => {} // ok, `const` already emitted an error
         _ => {}
     }
 }
@@ -42,7 +42,7 @@ fn mutable() {
     // This *must not build*, the constant we are matching against
     // could change its value!
     match &42 {
-        C => {} //~ERROR: could not evaluate constant pattern
+        C => {} // ok, `const` already emitted an error
         _ => {}
     }
 }
diff --git a/tests/ui/consts/const_refs_to_static_fail_invalid.stderr b/tests/ui/consts/const_refs_to_static_fail_invalid.stderr
index 0153f501174..c9d5cb60bf7 100644
--- a/tests/ui/consts/const_refs_to_static_fail_invalid.stderr
+++ b/tests/ui/consts/const_refs_to_static_fail_invalid.stderr
@@ -31,24 +31,6 @@ LL |     const C: &i32 = unsafe { &S_MUT };
                HEX_DUMP
            }
 
-error: could not evaluate constant pattern
-  --> $DIR/const_refs_to_static_fail_invalid.rs:14:9
-   |
-LL |         C => {}
-   |         ^
-
-error: could not evaluate constant pattern
-  --> $DIR/const_refs_to_static_fail_invalid.rs:30:9
-   |
-LL |         C => {}
-   |         ^
-
-error: could not evaluate constant pattern
-  --> $DIR/const_refs_to_static_fail_invalid.rs:45:9
-   |
-LL |         C => {}
-   |         ^
-
-error: aborting due to 6 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/invalid-inline-const-in-match-arm.stderr b/tests/ui/consts/invalid-inline-const-in-match-arm.stderr
index 2e48837bdcd..b22f99f40d3 100644
--- a/tests/ui/consts/invalid-inline-const-in-match-arm.stderr
+++ b/tests/ui/consts/invalid-inline-const-in-match-arm.stderr
@@ -11,7 +11,7 @@ error: could not evaluate constant pattern
   --> $DIR/invalid-inline-const-in-match-arm.rs:5:9
    |
 LL |         const { (|| {})() } => {}
-   |         ^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^ could not evaluate constant
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/issue-43105.rs b/tests/ui/consts/issue-43105.rs
index 20b78d64209..a4ee34c0532 100644
--- a/tests/ui/consts/issue-43105.rs
+++ b/tests/ui/consts/issue-43105.rs
@@ -5,8 +5,7 @@ const NUM: u8 = xyz();
 
 fn main() {
     match 1 {
-        NUM => unimplemented!(),
-        //~^ ERROR could not evaluate constant pattern
+        NUM => unimplemented!(), // ok, the `const` already emitted an error
         _ => unimplemented!(),
     }
 }
diff --git a/tests/ui/consts/issue-43105.stderr b/tests/ui/consts/issue-43105.stderr
index 856a8f0dab6..0e08feb58de 100644
--- a/tests/ui/consts/issue-43105.stderr
+++ b/tests/ui/consts/issue-43105.stderr
@@ -6,12 +6,6 @@ LL | const NUM: u8 = xyz();
    |
    = note: calls in constants are limited to constant functions, tuple structs and tuple variants
 
-error: could not evaluate constant pattern
-  --> $DIR/issue-43105.rs:8:9
-   |
-LL |         NUM => unimplemented!(),
-   |         ^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/consts/issue-73976-polymorphic.rs b/tests/ui/consts/issue-73976-polymorphic.rs
index 2c576d1f9ef..98b4005792d 100644
--- a/tests/ui/consts/issue-73976-polymorphic.rs
+++ b/tests/ui/consts/issue-73976-polymorphic.rs
@@ -18,7 +18,7 @@ impl<T: 'static> GetTypeId<T> {
 
 const fn check_type_id<T: 'static>() -> bool {
     matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE)
-    //~^ ERROR constant pattern depends on a generic parameter
+    //~^ ERROR constant pattern cannot depend on generic parameters
 }
 
 pub struct GetTypeNameLen<T>(T);
@@ -29,7 +29,7 @@ impl<T: 'static> GetTypeNameLen<T> {
 
 const fn check_type_name_len<T: 'static>() -> bool {
     matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
-    //~^ ERROR constant pattern depends on a generic parameter
+    //~^ ERROR constant pattern cannot depend on generic parameters
 }
 
 fn main() {
diff --git a/tests/ui/consts/issue-73976-polymorphic.stderr b/tests/ui/consts/issue-73976-polymorphic.stderr
index 8a44eb9854f..ec9512a2616 100644
--- a/tests/ui/consts/issue-73976-polymorphic.stderr
+++ b/tests/ui/consts/issue-73976-polymorphic.stderr
@@ -1,14 +1,28 @@
-error[E0158]: constant pattern depends on a generic parameter
+error[E0158]: constant pattern cannot depend on generic parameters
   --> $DIR/issue-73976-polymorphic.rs:20:37
    |
+LL | impl<T: 'static> GetTypeId<T> {
+   | -----------------------------
+LL |     pub const VALUE: TypeId = TypeId::of::<T>();
+   |     ----------------------- constant defined here
+...
+LL | const fn check_type_id<T: 'static>() -> bool {
+   |                        - constant depends on this generic parameter
 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 cannot depend on generic parameters
   --> $DIR/issue-73976-polymorphic.rs:31:42
    |
+LL | impl<T: 'static> GetTypeNameLen<T> {
+   | ----------------------------------
+LL |     pub const VALUE: usize = any::type_name::<T>().len();
+   |     ---------------------- constant defined here
+...
+LL | const fn check_type_name_len<T: 'static>() -> bool {
+   |                              - constant depends on this generic parameter
 LL |     matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
-   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^ `const` depends on a generic parameter
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/issue-78655.rs b/tests/ui/consts/issue-78655.rs
index cd95ee32c60..b0f862e8418 100644
--- a/tests/ui/consts/issue-78655.rs
+++ b/tests/ui/consts/issue-78655.rs
@@ -4,6 +4,5 @@ const FOO: *const u32 = {
 };
 
 fn main() {
-    let FOO = FOO;
-    //~^ ERROR could not evaluate constant pattern
+    let FOO = FOO; // ok, the `const` already emitted an error
 }
diff --git a/tests/ui/consts/issue-78655.stderr b/tests/ui/consts/issue-78655.stderr
index ccaed03b4c1..6a93c1a8cec 100644
--- a/tests/ui/consts/issue-78655.stderr
+++ b/tests/ui/consts/issue-78655.stderr
@@ -11,12 +11,6 @@ help: consider assigning a value
 LL |     let x = 42;
    |           ++++
 
-error: could not evaluate constant pattern
-  --> $DIR/issue-78655.rs:7:9
-   |
-LL |     let FOO = FOO;
-   |         ^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0381`.
diff --git a/tests/ui/consts/issue-79137-toogeneric.rs b/tests/ui/consts/issue-79137-toogeneric.rs
index a80c9f48d7b..43e06f3d676 100644
--- a/tests/ui/consts/issue-79137-toogeneric.rs
+++ b/tests/ui/consts/issue-79137-toogeneric.rs
@@ -10,7 +10,7 @@ impl<T> GetVariantCount<T> {
 
 const fn check_variant_count<T>() -> bool {
     matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE)
-    //~^ ERROR constant pattern depends on a generic parameter
+    //~^ ERROR constant pattern cannot depend on generic parameters
 }
 
 fn main() {
diff --git a/tests/ui/consts/issue-79137-toogeneric.stderr b/tests/ui/consts/issue-79137-toogeneric.stderr
index de81512ec6d..33e32a7d15d 100644
--- a/tests/ui/consts/issue-79137-toogeneric.stderr
+++ b/tests/ui/consts/issue-79137-toogeneric.stderr
@@ -1,8 +1,15 @@
-error[E0158]: constant pattern depends on a generic parameter
+error[E0158]: constant pattern cannot depend on generic parameters
   --> $DIR/issue-79137-toogeneric.rs:12:43
    |
+LL | impl<T> GetVariantCount<T> {
+   | --------------------------
+LL |     pub const VALUE: usize = std::mem::variant_count::<T>();
+   |     ---------------------- constant defined here
+...
+LL | const fn check_variant_count<T>() -> bool {
+   |                              - constant depends on this generic parameter
 LL |     matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE)
-   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `const` depends on a generic parameter
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/issue-87046.stderr b/tests/ui/consts/issue-87046.stderr
index 0f965e1ac3f..36e2564fae6 100644
--- a/tests/ui/consts/issue-87046.stderr
+++ b/tests/ui/consts/issue-87046.stderr
@@ -1,6 +1,9 @@
 error: cannot use unsized non-slice type `Username` in constant patterns
   --> $DIR/issue-87046.rs:28:13
    |
+LL | pub const ROOT_USER: &Username = Username::from_str("root");
+   | ------------------------------ constant defined here
+...
 LL |             ROOT_USER => true,
    |             ^^^^^^^^^
 
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 362c63a2a45..56025e0d9b2 100644
--- a/tests/ui/consts/issue-89088.stderr
+++ b/tests/ui/consts/issue-89088.stderr
@@ -1,10 +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 472c24a5cbe..95e96bbbd67 100644
--- a/tests/ui/consts/match_ice.stderr
+++ b/tests/ui/consts/match_ice.stderr
@@ -1,10 +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/consts/miri_unleashed/const_refers_to_static_cross_crate.rs b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs
index a6d75658c75..facb21a04ef 100644
--- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs
+++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs
@@ -37,16 +37,14 @@ const U8_MUT3: &u8 = {
 
 pub fn test(x: &[u8; 1]) -> bool {
     match x {
-        SLICE_MUT => true,
-        //~^ ERROR could not evaluate constant pattern
+        SLICE_MUT => true, // ok, `const` error already emitted
         &[1..] => false,
     }
 }
 
 pub fn test2(x: &u8) -> bool {
     match x {
-        U8_MUT => true,
-        //~^ ERROR could not evaluate constant pattern
+        U8_MUT => true, // ok, `const` error already emitted
         &(1..) => false,
     }
 }
@@ -55,15 +53,13 @@ pub fn test2(x: &u8) -> bool {
 // the errors above otherwise stop compilation too early?
 pub fn test3(x: &u8) -> bool {
     match x {
-        U8_MUT2 => true,
-        //~^ ERROR could not evaluate constant pattern
+        U8_MUT2 => true, // ok, `const` error already emitted
         &(1..) => false,
     }
 }
 pub fn test4(x: &u8) -> bool {
     match x {
-        U8_MUT3 => true,
-        //~^ ERROR could not evaluate constant pattern
+        U8_MUT3 => true, // ok, `const` error already emitted
         &(1..) => false,
     }
 }
diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr
index 147d3f238f7..8f8271cce38 100644
--- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr
+++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr
@@ -37,30 +37,6 @@ error[E0080]: evaluation of constant value failed
 LL |         match static_cross_crate::OPT_ZERO {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses mutable global memory
 
-error: could not evaluate constant pattern
-  --> $DIR/const_refers_to_static_cross_crate.rs:40:9
-   |
-LL |         SLICE_MUT => true,
-   |         ^^^^^^^^^
-
-error: could not evaluate constant pattern
-  --> $DIR/const_refers_to_static_cross_crate.rs:48:9
-   |
-LL |         U8_MUT => true,
-   |         ^^^^^^
-
-error: could not evaluate constant pattern
-  --> $DIR/const_refers_to_static_cross_crate.rs:58:9
-   |
-LL |         U8_MUT2 => true,
-   |         ^^^^^^^
-
-error: could not evaluate constant pattern
-  --> $DIR/const_refers_to_static_cross_crate.rs:65:9
-   |
-LL |         U8_MUT3 => true,
-   |         ^^^^^^^
-
-error: aborting due to 8 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/missing_assoc_const_type.rs b/tests/ui/consts/missing_assoc_const_type.rs
index 633998e9bc1..61042bfa96d 100644
--- a/tests/ui/consts/missing_assoc_const_type.rs
+++ b/tests/ui/consts/missing_assoc_const_type.rs
@@ -9,14 +9,13 @@ trait Range {
 
 struct TwoDigits;
 impl Range for TwoDigits {
-    const FIRST:  = 10;
-    //~^ ERROR: missing type for `const` item
+    const FIRST:  = 10; //~ ERROR missing type for `const` item
     const LAST: u8 = 99;
 }
 
 const fn digits(x: u8) -> usize {
     match x {
-        TwoDigits::FIRST..=TwoDigits::LAST => 0, //~ ERROR: could not evaluate constant pattern
+        TwoDigits::FIRST..=TwoDigits::LAST => 0, // ok, `const` error already emitted
         0..=9 | 100..=255 => panic!(),
     }
 }
diff --git a/tests/ui/consts/missing_assoc_const_type.stderr b/tests/ui/consts/missing_assoc_const_type.stderr
index ef7ff962d2d..28af1f0f321 100644
--- a/tests/ui/consts/missing_assoc_const_type.stderr
+++ b/tests/ui/consts/missing_assoc_const_type.stderr
@@ -4,11 +4,5 @@ error: missing type for `const` item
 LL |     const FIRST:  = 10;
    |                 ^ help: provide a type for the associated constant: `u8`
 
-error: could not evaluate constant pattern
-  --> $DIR/missing_assoc_const_type.rs:19:9
-   |
-LL |         TwoDigits::FIRST..=TwoDigits::LAST => 0,
-   |         ^^^^^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/transmute-size-mismatch-before-typeck.rs b/tests/ui/consts/transmute-size-mismatch-before-typeck.rs
index 44eac5b16cc..ffb143da2d4 100644
--- a/tests/ui/consts/transmute-size-mismatch-before-typeck.rs
+++ b/tests/ui/consts/transmute-size-mismatch-before-typeck.rs
@@ -5,7 +5,7 @@
 
 fn main() {
     match &b""[..] {
-        ZST => {} //~ ERROR: could not evaluate constant pattern
+        ZST => {} // ok, `const` error already emitted
     }
 }
 
diff --git a/tests/ui/consts/transmute-size-mismatch-before-typeck.stderr b/tests/ui/consts/transmute-size-mismatch-before-typeck.stderr
index e0d658db997..6bc7e7203aa 100644
--- a/tests/ui/consts/transmute-size-mismatch-before-typeck.stderr
+++ b/tests/ui/consts/transmute-size-mismatch-before-typeck.stderr
@@ -7,12 +7,6 @@ LL | const ZST: &[u8] = unsafe { std::mem::transmute(1usize) };
    = note: source type: `usize` (word size)
    = note: target type: `&[u8]` (2 * word size)
 
-error: could not evaluate constant pattern
-  --> $DIR/transmute-size-mismatch-before-typeck.rs:8:9
-   |
-LL |         ZST => {}
-   |         ^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0512`.
diff --git a/tests/ui/inline-const/const-match-pat-generic.rs b/tests/ui/inline-const/const-match-pat-generic.rs
index 9d76fc2ad65..889c015e9ac 100644
--- a/tests/ui/inline-const/const-match-pat-generic.rs
+++ b/tests/ui/inline-const/const-match-pat-generic.rs
@@ -5,7 +5,7 @@
 fn foo<const V: usize>() {
     match 0 {
         const { V } => {},
-        //~^ ERROR constant pattern depends on a generic parameter
+        //~^ ERROR constant pattern cannot depend on generic parameters
         _ => {},
     }
 }
@@ -17,7 +17,7 @@ const fn f(x: usize) -> usize {
 fn bar<const V: usize>() {
     match 0 {
         const { f(V) } => {},
-        //~^ ERROR constant pattern depends on a generic parameter
+        //~^ ERROR constant pattern cannot depend on generic parameters
         _ => {},
     }
 }
diff --git a/tests/ui/inline-const/const-match-pat-generic.stderr b/tests/ui/inline-const/const-match-pat-generic.stderr
index 26f72b34eca..7d9e1d9e407 100644
--- a/tests/ui/inline-const/const-match-pat-generic.stderr
+++ b/tests/ui/inline-const/const-match-pat-generic.stderr
@@ -1,14 +1,14 @@
-error[E0158]: constant pattern depends on a generic parameter
+error[E0158]: constant pattern cannot depend on generic parameters
   --> $DIR/const-match-pat-generic.rs:7:9
    |
 LL |         const { V } => {},
-   |         ^^^^^^^^^^^
+   |         ^^^^^^^^^^^ `const` depends on a generic parameter
 
-error[E0158]: constant pattern depends on a generic parameter
+error[E0158]: constant pattern cannot depend on generic parameters
   --> $DIR/const-match-pat-generic.rs:19:9
    |
 LL |         const { f(V) } => {},
-   |         ^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^ `const` depends on a generic parameter
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/inline-const/pat-match-fndef.stderr b/tests/ui/inline-const/pat-match-fndef.stderr
index b189ec51ade..220437a0491 100644
--- a/tests/ui/inline-const/pat-match-fndef.stderr
+++ b/tests/ui/inline-const/pat-match-fndef.stderr
@@ -1,8 +1,8 @@
-error: `fn() {uwu}` cannot be used in patterns
+error: fn item `fn() {uwu}` cannot be used in patterns
   --> $DIR/pat-match-fndef.rs:8:9
    |
 LL |         const { uwu } => {}
-   |         ^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^ fn item can't be used in patterns
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/match/issue-70972-dyn-trait.stderr b/tests/ui/match/issue-70972-dyn-trait.stderr
index b0af50f8599..cec9c8539f4 100644
--- a/tests/ui/match/issue-70972-dyn-trait.stderr
+++ b/tests/ui/match/issue-70972-dyn-trait.stderr
@@ -1,8 +1,11 @@
-error: `dyn Send` cannot be used in patterns
+error: trait object `dyn Send` cannot be used in patterns
   --> $DIR/issue-70972-dyn-trait.rs:6:9
    |
+LL | const F: &'static dyn Send = &7u32;
+   | -------------------------- constant defined here
+...
 LL |         F => panic!(),
-   |         ^
+   |         ^ trait object can't be used in patterns
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/match/issue-72896-non-partial-eq-const.rs b/tests/ui/match/issue-72896-non-partial-eq-const.rs
index f15eae83896..e4fc1ac057d 100644
--- a/tests/ui/match/issue-72896-non-partial-eq-const.rs
+++ b/tests/ui/match/issue-72896-non-partial-eq-const.rs
@@ -16,7 +16,7 @@ const CONST_SET: EnumSet<Enum8> = EnumSet { __enumset_underlying: 3 };
 
 fn main() {
     match CONST_SET {
-        CONST_SET => { /* ok */ } //~ERROR: must implement `PartialEq`
+        CONST_SET => { /* ok */ } //~ ERROR constant of non-structural type `EnumSet<Enum8>` in a pattern
         _ => panic!("match fell through?"),
     }
 }
diff --git a/tests/ui/match/issue-72896-non-partial-eq-const.stderr b/tests/ui/match/issue-72896-non-partial-eq-const.stderr
index 4155586c160..1f82d3e822a 100644
--- a/tests/ui/match/issue-72896-non-partial-eq-const.stderr
+++ b/tests/ui/match/issue-72896-non-partial-eq-const.stderr
@@ -1,8 +1,16 @@
-error: to use a constant of type `EnumSet<Enum8>` in a pattern, the type must implement `PartialEq`
+error: constant of non-structural type `EnumSet<Enum8>` in a pattern
   --> $DIR/issue-72896-non-partial-eq-const.rs:19:9
    |
+LL | enum Enum8 { }
+   | ---------- must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+...
+LL | const CONST_SET: EnumSet<Enum8> = EnumSet { __enumset_underlying: 3 };
+   | ------------------------------- constant defined here
+...
 LL |         CONST_SET => { /* ok */ }
-   |         ^^^^^^^^^
+   |         ^^^^^^^^^ constant of non-structural type
+   |
+   = 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 adab4e4d241..69d10728ccd 100644
--- a/tests/ui/pattern/issue-115599.stderr
+++ b/tests/ui/pattern/issue-115599.stderr
@@ -1,10 +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/issue-72565.stderr b/tests/ui/pattern/issue-72565.stderr
index b503a17fe84..e2927ada0f7 100644
--- a/tests/ui/pattern/issue-72565.stderr
+++ b/tests/ui/pattern/issue-72565.stderr
@@ -1,8 +1,11 @@
-error: `dyn PartialEq<u32>` cannot be used in patterns
+error: trait object `dyn PartialEq<u32>` cannot be used in patterns
   --> $DIR/issue-72565.rs:6:9
    |
+LL | const F: &'static dyn PartialEq<u32> = &7u32;
+   | ------------------------------------ constant defined here
+...
 LL |         F => panic!(),
-   |         ^
+   |         ^ trait object can't be used in patterns
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/pattern/non-constant-in-const-path.stderr b/tests/ui/pattern/non-constant-in-const-path.stderr
index 53c3974f780..2ba4963e6dc 100644
--- a/tests/ui/pattern/non-constant-in-const-path.stderr
+++ b/tests/ui/pattern/non-constant-in-const-path.stderr
@@ -2,25 +2,31 @@ error[E0080]: runtime values cannot be referenced in patterns
   --> $DIR/non-constant-in-const-path.rs:8:15
    |
 LL |     let 0u8..=x = 0;
-   |               ^
+   |               ^ references a runtime value
 
 error[E0158]: statics cannot be referenced in patterns
   --> $DIR/non-constant-in-const-path.rs:10:15
    |
+LL | static FOO: u8 = 10;
+   | -------------- `static` defined here
+...
 LL |     let 0u8..=FOO = 0;
-   |               ^^^
+   |               ^^^ can't be used in patterns
 
 error[E0080]: runtime values cannot be referenced in patterns
   --> $DIR/non-constant-in-const-path.rs:13:15
    |
 LL |         0 ..= x => {}
-   |               ^
+   |               ^ references a runtime value
 
 error[E0158]: statics cannot be referenced in patterns
   --> $DIR/non-constant-in-const-path.rs:15:15
    |
+LL | static FOO: u8 = 10;
+   | -------------- `static` defined here
+...
 LL |         0 ..= FOO => {}
-   |               ^^^
+   |               ^^^ can't be used in patterns
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/pattern/non-structural-match-types.stderr b/tests/ui/pattern/non-structural-match-types.stderr
index 9075cf40dda..3588751bf66 100644
--- a/tests/ui/pattern/non-structural-match-types.stderr
+++ b/tests/ui/pattern/non-structural-match-types.stderr
@@ -1,14 +1,14 @@
-error: `{closure@$DIR/non-structural-match-types.rs:9:17: 9:19}` cannot be used in patterns
+error: closure `{closure@$DIR/non-structural-match-types.rs:9:17: 9:19}` cannot be used in patterns
   --> $DIR/non-structural-match-types.rs:9:9
    |
 LL |         const { || {} } => {}
-   |         ^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^ closure can't be used in patterns
 
-error: `{async block@$DIR/non-structural-match-types.rs:12:17: 12:22}` cannot be used in patterns
+error: `async` block `{async block@$DIR/non-structural-match-types.rs:12:17: 12:22}` cannot be used in patterns
   --> $DIR/non-structural-match-types.rs:12:9
    |
 LL |         const { async {} } => {}
-   |         ^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^ `async` block can't be used in patterns
 
 error: aborting due to 2 previous errors
 
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 0b4d9972758..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,11 +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 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/const-partial_eq-fallback-ice.rs:5:1
+   |
+LL | impl PartialEq<usize> for MyType {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/pattern/usefulness/consts-opaque.stderr b/tests/ui/pattern/usefulness/consts-opaque.stderr
index 32d385eecb4..d52451d9438 100644
--- a/tests/ui/pattern/usefulness/consts-opaque.stderr
+++ b/tests/ui/pattern/usefulness/consts-opaque.stderr
@@ -1,50 +1,90 @@
-error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
   --> $DIR/consts-opaque.rs:96:9
    |
+LL |     const QUUX: Quux = quux;
+   |     ---------------- constant defined here
+...
 LL |         QUUX => {}
-   |         ^^^^
+   |         ^^^^ can't be used in patterns
+   |
+   = note: see https://github.com/rust-lang/rust/issues/70861 for details
 
-error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
   --> $DIR/consts-opaque.rs:97:9
    |
+LL |     const QUUX: Quux = quux;
+   |     ---------------- constant defined here
+...
 LL |         QUUX => {}
-   |         ^^^^
+   |         ^^^^ can't be used in patterns
+   |
+   = note: see https://github.com/rust-lang/rust/issues/70861 for details
 
-error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
   --> $DIR/consts-opaque.rs:106:9
    |
+LL |     const WRAPQUUX: Wrap<Quux> = Wrap(quux);
+   |     -------------------------- constant defined here
+...
 LL |         WRAPQUUX => {}
-   |         ^^^^^^^^
+   |         ^^^^^^^^ can't be used in patterns
+   |
+   = note: see https://github.com/rust-lang/rust/issues/70861 for details
 
-error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
   --> $DIR/consts-opaque.rs:107:9
    |
+LL |     const WRAPQUUX: Wrap<Quux> = Wrap(quux);
+   |     -------------------------- constant defined here
+...
 LL |         WRAPQUUX => {}
-   |         ^^^^^^^^
+   |         ^^^^^^^^ can't be used in patterns
+   |
+   = note: see https://github.com/rust-lang/rust/issues/70861 for details
 
-error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
   --> $DIR/consts-opaque.rs:113:9
    |
+LL |     const WRAPQUUX: Wrap<Quux> = Wrap(quux);
+   |     -------------------------- constant defined here
+...
 LL |         WRAPQUUX => {}
-   |         ^^^^^^^^
+   |         ^^^^^^^^ can't be used in patterns
+   |
+   = note: see https://github.com/rust-lang/rust/issues/70861 for details
 
-error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
   --> $DIR/consts-opaque.rs:121:9
    |
+LL |     const WRAPQUUX: Wrap<Quux> = Wrap(quux);
+   |     -------------------------- constant defined here
+...
 LL |         WRAPQUUX => {}
-   |         ^^^^^^^^
+   |         ^^^^^^^^ can't be used in patterns
+   |
+   = note: see https://github.com/rust-lang/rust/issues/70861 for details
 
-error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
   --> $DIR/consts-opaque.rs:132:9
    |
+LL |     const WHOKNOWSQUUX: WhoKnows<Quux> = WhoKnows::Yay(quux);
+   |     ---------------------------------- constant defined here
+...
 LL |         WHOKNOWSQUUX => {}
-   |         ^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^ can't be used in patterns
+   |
+   = note: see https://github.com/rust-lang/rust/issues/70861 for details
 
-error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
   --> $DIR/consts-opaque.rs:134:9
    |
+LL |     const WHOKNOWSQUUX: WhoKnows<Quux> = WhoKnows::Yay(quux);
+   |     ---------------------------------- constant defined here
+...
 LL |         WHOKNOWSQUUX => {}
-   |         ^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^ can't be used in patterns
+   |
+   = note: see https://github.com/rust-lang/rust/issues/70861 for details
 
 error: unreachable pattern
   --> $DIR/consts-opaque.rs:48:9
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 cc5d4106331..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,11 +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 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/cant-hide-behind-direct-struct-embedded.rs:11:1
+   |
+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 3d00ef2dfbf..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,11 +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 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/cant-hide-behind-direct-struct-param.rs:10:1
+   |
+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 3636307e16c..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,11 +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 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/cant-hide-behind-doubly-indirect-embedded.rs:11:1
+   |
+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 40fd31762b2..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,11 +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 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/cant-hide-behind-doubly-indirect-param.rs:11:1
+   |
+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 dbf1848326a..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,11 +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 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/cant-hide-behind-indirect-struct-embedded.rs:11:1
+   |
+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 58acc11a744..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,11 +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 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/cant-hide-behind-indirect-struct-param.rs:11:1
+   |
+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/fn-ptr-is-not-structurally-matchable.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-not-structurally-matchable.stderr
index 0bc1e7fc89b..cdbe72ca48f 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-not-structurally-matchable.stderr
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-not-structurally-matchable.stderr
@@ -1,62 +1,112 @@
-error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
   --> $DIR/fn-ptr-is-not-structurally-matchable.rs:41:14
    |
+LL |     const CFN1: Wrap<fn()> = Wrap(trivial);
+   |     ---------------------- constant defined here
+...
 LL |         Wrap(CFN1) => count += 1,
-   |              ^^^^
+   |              ^^^^ can't be used in patterns
+   |
+   = note: see https://github.com/rust-lang/rust/issues/70861 for details
 
-error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
   --> $DIR/fn-ptr-is-not-structurally-matchable.rs:49:14
    |
+LL |     const CFN2: Wrap<fn(SM)> = Wrap(sm_to);
+   |     ------------------------ constant defined here
+...
 LL |         Wrap(CFN2) => count += 1,
-   |              ^^^^
+   |              ^^^^ can't be used in patterns
+   |
+   = note: see https://github.com/rust-lang/rust/issues/70861 for details
 
-error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
   --> $DIR/fn-ptr-is-not-structurally-matchable.rs:57:14
    |
+LL |     const CFN3: Wrap<fn() -> SM> = Wrap(to_sm);
+   |     ---------------------------- constant defined here
+...
 LL |         Wrap(CFN3) => count += 1,
-   |              ^^^^
+   |              ^^^^ can't be used in patterns
+   |
+   = note: see https://github.com/rust-lang/rust/issues/70861 for details
 
-error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
   --> $DIR/fn-ptr-is-not-structurally-matchable.rs:65:14
    |
+LL |     const CFN4: Wrap<fn(NotSM)> = Wrap(not_sm_to);
+   |     --------------------------- constant defined here
+...
 LL |         Wrap(CFN4) => count += 1,
-   |              ^^^^
+   |              ^^^^ can't be used in patterns
+   |
+   = note: see https://github.com/rust-lang/rust/issues/70861 for details
 
-error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
   --> $DIR/fn-ptr-is-not-structurally-matchable.rs:73:14
    |
+LL |     const CFN5: Wrap<fn() -> NotSM> = Wrap(to_not_sm);
+   |     ------------------------------- constant defined here
+...
 LL |         Wrap(CFN5) => count += 1,
-   |              ^^^^
+   |              ^^^^ can't be used in patterns
+   |
+   = note: see https://github.com/rust-lang/rust/issues/70861 for details
 
-error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
   --> $DIR/fn-ptr-is-not-structurally-matchable.rs:81:14
    |
+LL |     const CFN6: Wrap<fn(&SM)> = Wrap(r_sm_to);
+   |     ------------------------- constant defined here
+...
 LL |         Wrap(CFN6) => count += 1,
-   |              ^^^^
+   |              ^^^^ can't be used in patterns
+   |
+   = note: see https://github.com/rust-lang/rust/issues/70861 for details
 
-error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
   --> $DIR/fn-ptr-is-not-structurally-matchable.rs:89:14
    |
+LL |     const CFN7: Wrap<fn(&()) -> &SM> = Wrap(r_to_r_sm);
+   |     -------------------------------- constant defined here
+...
 LL |         Wrap(CFN7) => count += 1,
-   |              ^^^^
+   |              ^^^^ can't be used in patterns
+   |
+   = note: see https://github.com/rust-lang/rust/issues/70861 for details
 
-error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
   --> $DIR/fn-ptr-is-not-structurally-matchable.rs:97:14
    |
+LL |     const CFN8: Wrap<fn(&NotSM)> = Wrap(r_not_sm_to);
+   |     ---------------------------- constant defined here
+...
 LL |         Wrap(CFN8) => count += 1,
-   |              ^^^^
+   |              ^^^^ can't be used in patterns
+   |
+   = note: see https://github.com/rust-lang/rust/issues/70861 for details
 
-error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
   --> $DIR/fn-ptr-is-not-structurally-matchable.rs:105:14
    |
+LL |     const CFN9: Wrap<fn(&()) -> &NotSM> = Wrap(r_to_r_not_sm);
+   |     ----------------------------------- constant defined here
+...
 LL |         Wrap(CFN9) => count += 1,
-   |              ^^^^
+   |              ^^^^ can't be used in patterns
+   |
+   = note: see https://github.com/rust-lang/rust/issues/70861 for details
 
-error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
   --> $DIR/fn-ptr-is-not-structurally-matchable.rs:127:9
    |
+LL |     const CFOO: Foo = Foo {
+   |     --------------- constant defined here
+...
 LL |         CFOO => count += 1,
-   |         ^^^^
+   |         ^^^^ can't be used in patterns
+   |
+   = note: see https://github.com/rust-lang/rust/issues/70861 for details
 
 error: aborting due to 10 previous errors
 
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.rs
index c01f8934c75..95a3be517a9 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.rs
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.rs
@@ -12,8 +12,7 @@ const A: &[B] = &[];
 
 pub fn main() {
     match &[][..] {
-        A => (),
-        //~^ ERROR must implement `PartialEq`
+        A => (), //~ ERROR constant of non-structural type `&[B]` in a pattern
         _ => (),
     }
 }
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.stderr
index 736e4c30c8a..7d3b37686b8 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.stderr
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.stderr
@@ -1,8 +1,16 @@
-error: to use a constant of type `&[B]` in a pattern, the type must implement `PartialEq`
+error: constant of non-structural type `&[B]` in a pattern
   --> $DIR/issue-61188-match-slice-forbidden-without-eq.rs:15:9
    |
+LL | struct B(i32);
+   | -------- must be annotated with `#[derive(PartialEq)]` to be usable in patterns
+LL |
+LL | const A: &[B] = &[];
+   | ------------- constant defined here
+...
 LL |         A => (),
-   |         ^
+   |         ^ constant of non-structural type
+   |
+   = 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/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 e79b05fdf9d..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,20 +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/issue-63479-match-fnptr.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr
index 7b1832ed0fa..ea6121839be 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr
@@ -1,14 +1,24 @@
-error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
   --> $DIR/issue-63479-match-fnptr.rs:32:7
    |
+LL | const TEST: Fn = my_fn;
+   | -------------- constant defined here
+...
 LL |     B(TEST) => println!("matched"),
-   |       ^^^^
+   |       ^^^^ can't be used in patterns
+   |
+   = note: see https://github.com/rust-lang/rust/issues/70861 for details
 
-error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
   --> $DIR/issue-63479-match-fnptr.rs:37:5
    |
+LL | const TEST2: (Fn, u8) = (TEST, 0);
+   | --------------------- constant defined here
+...
 LL |     TEST2 => println!("matched"),
-   |     ^^^^^
+   |     ^^^^^ can't be used in patterns
+   |
+   = note: see https://github.com/rust-lang/rust/issues/70861 for details
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.stderr
index 44b05ea31e9..7c49870e5d0 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.stderr
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.stderr
@@ -1,8 +1,11 @@
 error: cannot use NaN in patterns
   --> $DIR/issue-6804-nan-match.rs:14:9
    |
+LL | const NAN: f64 = f64::NAN;
+   | -------------- constant defined here
+...
 LL |         NAN => {},
-   |         ^^^
+   |         ^^^ evaluates to `NaN`, which is not allowed in patterns
    |
    = note: NaNs compare inequal to everything, even themselves, so this pattern would never match
    = help: try using the `is_nan` method instead
@@ -10,8 +13,11 @@ LL |         NAN => {},
 error: cannot use NaN in patterns
   --> $DIR/issue-6804-nan-match.rs:19:10
    |
+LL | const NAN: f64 = f64::NAN;
+   | -------------- constant defined here
+...
 LL |         [NAN, _] => {},
-   |          ^^^
+   |          ^^^ evaluates to `NaN`, which is not allowed in patterns
    |
    = note: NaNs compare inequal to everything, even themselves, so this pattern would never match
    = help: try using the `is_nan` method instead
@@ -19,8 +25,11 @@ LL |         [NAN, _] => {},
 error: cannot use NaN in patterns
   --> $DIR/issue-6804-nan-match.rs:24:9
    |
+LL | const C: MyType<f32> = MyType(f32::NAN);
+   | -------------------- constant defined here
+...
 LL |         C => {},
-   |         ^
+   |         ^ evaluates to `NaN`, which is not allowed in patterns
    |
    = note: NaNs compare inequal to everything, even themselves, so this pattern would never match
    = help: try using the `is_nan` method instead
@@ -28,8 +37,11 @@ LL |         C => {},
 error: cannot use NaN in patterns
   --> $DIR/issue-6804-nan-match.rs:30:9
    |
+LL | const NAN: f64 = f64::NAN;
+   | -------------- constant defined here
+...
 LL |         NAN..=1.0 => {},
-   |         ^^^
+   |         ^^^ evaluates to `NaN`, which is not allowed in patterns
    |
    = note: NaNs compare inequal to everything, even themselves, so this pattern would never match
    = help: try using the `is_nan` method instead
@@ -37,8 +49,11 @@ LL |         NAN..=1.0 => {},
 error: cannot use NaN in patterns
   --> $DIR/issue-6804-nan-match.rs:31:16
    |
+LL | const NAN: f64 = f64::NAN;
+   | -------------- constant defined here
+...
 LL |         -1.0..=NAN => {},
-   |                ^^^
+   |                ^^^ evaluates to `NaN`, which is not allowed in patterns
    |
    = note: NaNs compare inequal to everything, even themselves, so this pattern would never match
    = help: try using the `is_nan` method instead
@@ -46,8 +61,11 @@ LL |         -1.0..=NAN => {},
 error: cannot use NaN in patterns
   --> $DIR/issue-6804-nan-match.rs:32:9
    |
+LL | const NAN: f64 = f64::NAN;
+   | -------------- constant defined here
+...
 LL |         NAN.. => {},
-   |         ^^^
+   |         ^^^ evaluates to `NaN`, which is not allowed in patterns
    |
    = note: NaNs compare inequal to everything, even themselves, so this pattern would never match
    = help: try using the `is_nan` method instead
@@ -55,8 +73,11 @@ LL |         NAN.. => {},
 error: cannot use NaN in patterns
   --> $DIR/issue-6804-nan-match.rs:33:11
    |
+LL | const NAN: f64 = f64::NAN;
+   | -------------- constant defined here
+...
 LL |         ..NAN => {},
-   |           ^^^
+   |           ^^^ evaluates to `NaN`, which is not allowed in patterns
    |
    = note: NaNs compare inequal to everything, even themselves, so this pattern would never match
    = help: try using the `is_nan` method instead
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 efd9c8c45af..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,11 +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 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/match-requires-both-partialeq-and-eq.rs:8:1
+   |
+LL | impl PartialEq for Foo {
+   | ^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr b/tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr
index 98d71aa9a17..28f5d6728a9 100644
--- a/tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr
+++ b/tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr
@@ -1,8 +1,11 @@
-error: `Bar` cannot be used in patterns
+error: opaque type `Bar` cannot be used in patterns
   --> $DIR/structural-match-no-leak.rs:16:9
    |
+LL | const LEAK_FREE: bar::Bar = bar::leak_free();
+   | ------------------------- constant defined here
+...
 LL |         LEAK_FREE => (),
-   |         ^^^^^^^^^
+   |         ^^^^^^^^^ opaque type can't be used in patterns
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/structural-match.stderr b/tests/ui/type-alias-impl-trait/structural-match.stderr
index c7478b0a135..b06b31a060f 100644
--- a/tests/ui/type-alias-impl-trait/structural-match.stderr
+++ b/tests/ui/type-alias-impl-trait/structural-match.stderr
@@ -1,8 +1,11 @@
-error: `foo::Foo` cannot be used in patterns
+error: opaque type `foo::Foo` cannot be used in patterns
   --> $DIR/structural-match.rs:18:9
    |
+LL | const VALUE: Foo = value();
+   | ---------------- constant defined here
+...
 LL |         VALUE => (),
-   |         ^^^^^
+   |         ^^^^^ opaque type can't be used in patterns
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/union/union-const-pat.stderr b/tests/ui/union/union-const-pat.stderr
index e9dbb275944..59dc89c77a4 100644
--- a/tests/ui/union/union-const-pat.stderr
+++ b/tests/ui/union/union-const-pat.stderr
@@ -1,8 +1,11 @@
 error: cannot use unions in constant patterns
   --> $DIR/union-const-pat.rs:10:9
    |
+LL | const C: U = U { a: 10 };
+   | ---------- constant defined here
+...
 LL |         C => {}
-   |         ^
+   |         ^ can't use a `union` here
 
 error: aborting due to 1 previous error