diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index a59d91ea78900..39ebd57b4b296 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -7,6 +7,7 @@ use crate::SuggestionStyle;
 use crate::ToolMetadata;
 use rustc_lint_defs::Applicability;
 use rustc_serialize::json::Json;
+use rustc_span::edition::LATEST_STABLE_EDITION;
 use rustc_span::{MultiSpan, Span, DUMMY_SP};
 use std::fmt;
 use std::hash::{Hash, Hasher};
@@ -342,6 +343,18 @@ impl Diagnostic {
         self
     }
 
+    /// Help the user upgrade to the latest edition.
+    /// This is factored out to make sure it does the right thing with `Cargo.toml`.
+    pub fn help_use_latest_edition(&mut self) -> &mut Self {
+        if std::env::var_os("CARGO").is_some() {
+            self.help(&format!("set `edition = \"{}\"` in `Cargo.toml`", LATEST_STABLE_EDITION));
+        } else {
+            self.help(&format!("pass `--edition {}` to `rustc`", LATEST_STABLE_EDITION));
+        }
+        self.note("for more on editions, read https://doc.rust-lang.org/edition-guide");
+        self
+    }
+
     /// Disallow attaching suggestions this diagnostic.
     /// Any suggestions attached e.g. with the `span_suggestion_*` methods
     /// (before and after the call to `disable_suggestions`) will be ignored.
diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs
index 5dc71f1620096..98b8b2a569edd 100644
--- a/compiler/rustc_errors/src/diagnostic_builder.rs
+++ b/compiler/rustc_errors/src/diagnostic_builder.rs
@@ -409,6 +409,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
         sp: impl Into<MultiSpan>,
         msg: &str,
     ) -> &mut Self);
+    forward!(pub fn help_use_latest_edition(&mut self,) -> &mut Self);
     forward!(pub fn set_is_lint(&mut self,) -> &mut Self);
 
     forward!(pub fn disable_suggestions(&mut self,) -> &mut Self);
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 4b9cf784495fe..bb51f880099a6 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -606,17 +606,17 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     rustc_attr!(
         rustc_layout_scalar_valid_range_start, Normal, template!(List: "value"), ErrorFollowing,
         "the `#[rustc_layout_scalar_valid_range_start]` attribute is just used to enable \
-        niche optimizations in libcore and will never be stable",
+        niche optimizations in libcore and libstd and will never be stable",
     ),
     rustc_attr!(
         rustc_layout_scalar_valid_range_end, Normal, template!(List: "value"), ErrorFollowing,
         "the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \
-        niche optimizations in libcore and will never be stable",
+        niche optimizations in libcore and libstd and will never be stable",
     ),
     rustc_attr!(
         rustc_nonnull_optimization_guaranteed, Normal, template!(Word), WarnFollowing,
         "the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to enable \
-        niche optimizations in libcore and will never be stable",
+        niche optimizations in libcore and libstd and will never be stable",
     ),
 
     // ==========================================================================
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index f46f74fa45fb0..bbfbf61f4869a 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -258,7 +258,7 @@ impl<'s> LintLevelsBuilder<'s> {
             };
 
             if metas.is_empty() {
-                // FIXME (#55112): issue unused-attributes lint for `#[level()]`
+                // This emits the unused_attributes lint for `#[level()]`
                 continue;
             }
 
@@ -271,8 +271,6 @@ impl<'s> LintLevelsBuilder<'s> {
                     ast::MetaItemKind::Word => {} // actual lint names handled later
                     ast::MetaItemKind::NameValue(ref name_value) => {
                         if item.path == sym::reason {
-                            // FIXME (#55112): issue unused-attributes lint if we thereby
-                            // don't have any lint names (`#[level(reason = "foo")]`)
                             if let ast::LitKind::Str(rationale, _) = name_value.kind {
                                 if !self.sess.features_untracked().lint_reasons {
                                     feature_err(
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 0d5e1e7f5513c..d4dac640cc7e1 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -795,7 +795,9 @@ crate fn repr_nullable_ptr<'tcx>(
         let field_ty_abi = &cx.layout_of(field_ty).unwrap().abi;
         if let Abi::Scalar(field_ty_scalar) = field_ty_abi {
             match (field_ty_scalar.valid_range.start, field_ty_scalar.valid_range.end) {
-                (0, _) => unreachable!("Non-null optimisation extended to a non-zero value."),
+                (0, x) if x == field_ty_scalar.value.size(&cx.tcx).unsigned_int_max() - 1 => {
+                    return Some(get_nullable_type(cx, field_ty).unwrap());
+                }
                 (1, _) => {
                     return Some(get_nullable_type(cx, field_ty).unwrap());
                 }
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index 27a6b5beb627c..b80d2e52ee709 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -20,7 +20,7 @@ use rustc_session::lint::builtin::{
 };
 use rustc_session::Session;
 use rustc_span::source_map::Spanned;
-use rustc_span::{DesugaringKind, ExpnKind, Span};
+use rustc_span::{DesugaringKind, ExpnKind, MultiSpan, Span};
 
 crate fn check_match(tcx: TyCtxt<'_>, def_id: DefId) {
     let body_id = match def_id.as_local() {
@@ -64,7 +64,9 @@ impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, '_, 'tcx> {
     fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
         intravisit::walk_expr(self, ex);
         match &ex.kind {
-            hir::ExprKind::Match(scrut, arms, source) => self.check_match(scrut, arms, *source),
+            hir::ExprKind::Match(scrut, arms, source) => {
+                self.check_match(scrut, arms, *source, ex.span)
+            }
             hir::ExprKind::Let(hir::Let { pat, init, span, .. }) => {
                 self.check_let(pat, init, *span)
             }
@@ -163,6 +165,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
         scrut: &hir::Expr<'_>,
         hir_arms: &'tcx [hir::Arm<'tcx>],
         source: hir::MatchSource,
+        expr_span: Span,
     ) {
         let mut cx = self.new_cx(scrut.hir_id);
 
@@ -208,7 +211,6 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
         }
 
         // Check if the match is exhaustive.
-        let is_empty_match = arms.is_empty();
         let witnesses = report.non_exhaustiveness_witnesses;
         if !witnesses.is_empty() {
             if source == hir::MatchSource::ForLoopDesugar && hir_arms.len() == 2 {
@@ -216,7 +218,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
                 let pat = hir_arms[1].pat.for_loop_some().unwrap();
                 self.check_irrefutable(pat, "`for` loop binding", None);
             } else {
-                non_exhaustive_match(&cx, scrut_ty, scrut.span, witnesses, is_empty_match);
+                non_exhaustive_match(&cx, scrut_ty, scrut.span, witnesses, hir_arms, expr_span);
             }
         }
     }
@@ -334,7 +336,7 @@ fn check_for_bindings_named_same_as_variants(
                     let ty_path = cx.tcx.def_path_str(edef.did);
                     let mut err = lint.build(&format!(
                         "pattern binding `{}` is named the same as one \
-                                        of the variants of the type `{}`",
+                         of the variants of the type `{}`",
                         ident, ty_path
                     ));
                     err.code(error_code!(E0170));
@@ -494,8 +496,10 @@ fn non_exhaustive_match<'p, 'tcx>(
     scrut_ty: Ty<'tcx>,
     sp: Span,
     witnesses: Vec<DeconstructedPat<'p, 'tcx>>,
-    is_empty_match: bool,
+    arms: &[hir::Arm<'tcx>],
+    expr_span: Span,
 ) {
+    let is_empty_match = arms.is_empty();
     let non_empty_enum = match scrut_ty.kind() {
         ty::Adt(def, _) => def.is_enum() && !def.variants.is_empty(),
         _ => false,
@@ -503,12 +507,15 @@ fn non_exhaustive_match<'p, 'tcx>(
     // In the case of an empty match, replace the '`_` not covered' diagnostic with something more
     // informative.
     let mut err;
+    let pattern;
+    let mut patterns_len = 0;
     if is_empty_match && !non_empty_enum {
         err = create_e0004(
             cx.tcx.sess,
             sp,
             format!("non-exhaustive patterns: type `{}` is non-empty", scrut_ty),
         );
+        pattern = "_".to_string();
     } else {
         let joined_patterns = joined_uncovered_patterns(cx, &witnesses);
         err = create_e0004(
@@ -517,6 +524,16 @@ fn non_exhaustive_match<'p, 'tcx>(
             format!("non-exhaustive patterns: {} not covered", joined_patterns),
         );
         err.span_label(sp, pattern_not_covered_label(&witnesses, &joined_patterns));
+        patterns_len = witnesses.len();
+        pattern = if witnesses.len() < 4 {
+            witnesses
+                .iter()
+                .map(|witness| witness.to_pat(cx).to_string())
+                .collect::<Vec<String>>()
+                .join(" | ")
+        } else {
+            "_".to_string()
+        };
     };
 
     let is_variant_list_non_exhaustive = match scrut_ty.kind() {
@@ -525,10 +542,6 @@ fn non_exhaustive_match<'p, 'tcx>(
     };
 
     adt_defined_here(cx, &mut err, scrut_ty, &witnesses);
-    err.help(
-        "ensure that all possible cases are being handled, \
-              possibly by adding wildcards or more match arms",
-    );
     err.note(&format!(
         "the matched value is of type `{}`{}",
         scrut_ty,
@@ -540,14 +553,14 @@ fn non_exhaustive_match<'p, 'tcx>(
         && matches!(witnesses[0].ctor(), Constructor::NonExhaustive)
     {
         err.note(&format!(
-            "`{}` does not have a fixed maximum value, \
-                so a wildcard `_` is necessary to match exhaustively",
+            "`{}` does not have a fixed maximum value, so a wildcard `_` is necessary to match \
+             exhaustively",
             scrut_ty,
         ));
         if cx.tcx.sess.is_nightly_build() {
             err.help(&format!(
-                "add `#![feature(precise_pointer_size_matching)]` \
-                    to the crate attributes to enable precise `{}` matching",
+                "add `#![feature(precise_pointer_size_matching)]` to the crate attributes to \
+                 enable precise `{}` matching",
                 scrut_ty,
             ));
         }
@@ -557,6 +570,84 @@ fn non_exhaustive_match<'p, 'tcx>(
             err.note("references are always considered inhabited");
         }
     }
+
+    let mut suggestion = None;
+    let sm = cx.tcx.sess.source_map();
+    match arms {
+        [] if sp.ctxt() == expr_span.ctxt() => {
+            // Get the span for the empty match body `{}`.
+            let (indentation, more) = if let Some(snippet) = sm.indentation_before(sp) {
+                (format!("\n{}", snippet), "    ")
+            } else {
+                (" ".to_string(), "")
+            };
+            suggestion = Some((
+                sp.shrink_to_hi().with_hi(expr_span.hi()),
+                format!(
+                    " {{{indentation}{more}{pattern} => todo!(),{indentation}}}",
+                    indentation = indentation,
+                    more = more,
+                    pattern = pattern,
+                ),
+            ));
+        }
+        [only] => {
+            let pre_indentation = if let (Some(snippet), true) = (
+                sm.indentation_before(only.span),
+                sm.is_multiline(sp.shrink_to_hi().with_hi(only.span.lo())),
+            ) {
+                format!("\n{}", snippet)
+            } else {
+                " ".to_string()
+            };
+            let comma = if matches!(only.body.kind, hir::ExprKind::Block(..)) { "" } else { "," };
+            suggestion = Some((
+                only.span.shrink_to_hi(),
+                format!("{}{}{} => todo!()", comma, pre_indentation, pattern),
+            ));
+        }
+        [.., prev, last] if prev.span.ctxt() == last.span.ctxt() => {
+            if let Ok(snippet) = sm.span_to_snippet(prev.span.between(last.span)) {
+                let comma =
+                    if matches!(last.body.kind, hir::ExprKind::Block(..)) { "" } else { "," };
+                suggestion = Some((
+                    last.span.shrink_to_hi(),
+                    format!(
+                        "{}{}{} => todo!()",
+                        comma,
+                        snippet.strip_prefix(",").unwrap_or(&snippet),
+                        pattern
+                    ),
+                ));
+            }
+        }
+        _ => {}
+    }
+
+    let msg = format!(
+        "ensure that all possible cases are being handled by adding a match arm with a wildcard \
+         pattern{}{}",
+        if patterns_len > 1 && patterns_len < 4 && suggestion.is_some() {
+            ", a match arm with multiple or-patterns"
+        } else {
+            // we are either not suggesting anything, or suggesting `_`
+            ""
+        },
+        match patterns_len {
+            // non-exhaustive enum case
+            0 if suggestion.is_some() => " as shown",
+            0 => "",
+            1 if suggestion.is_some() => " or an explicit pattern as shown",
+            1 => " or an explicit pattern",
+            _ if suggestion.is_some() => " as shown, or multiple match arms",
+            _ => " or multiple match arms",
+        },
+    );
+    if let Some((span, sugg)) = suggestion {
+        err.span_suggestion_verbose(span, &msg, sugg, Applicability::HasPlaceholders);
+    } else {
+        err.help(&msg);
+    }
     err.emit();
 }
 
@@ -597,15 +688,27 @@ fn adt_defined_here<'p, 'tcx>(
 ) {
     let ty = ty.peel_refs();
     if let ty::Adt(def, _) = ty.kind() {
-        if let Some(sp) = cx.tcx.hir().span_if_local(def.did) {
-            err.span_label(sp, format!("`{}` defined here", ty));
-        }
-
-        if witnesses.len() < 4 {
+        let mut spans = vec![];
+        if witnesses.len() < 5 {
             for sp in maybe_point_at_variant(cx, def, witnesses.iter()) {
-                err.span_label(sp, "not covered");
+                spans.push(sp);
             }
         }
+        let def_span = cx
+            .tcx
+            .hir()
+            .get_if_local(def.did)
+            .and_then(|node| node.ident())
+            .map(|ident| ident.span)
+            .unwrap_or_else(|| cx.tcx.def_span(def.did));
+        let mut span: MultiSpan =
+            if spans.is_empty() { def_span.into() } else { spans.clone().into() };
+
+        span.push_span_label(def_span, String::new());
+        for pat in spans {
+            span.push_span_label(pat, "not covered".to_string());
+        }
+        err.span_note(span, &format!("`{}` defined here", ty));
     }
 }
 
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index df865d77b9bb4..b993d48c995b4 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -20,7 +20,6 @@ use rustc_ast_pretty::pprust;
 use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, PResult};
 use rustc_session::lint::builtin::BREAK_WITH_LABEL_AND_LOOP;
 use rustc_session::lint::BuiltinLintDiagnostics;
-use rustc_span::edition::LATEST_STABLE_EDITION;
 use rustc_span::source_map::{self, Span, Spanned};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{BytePos, Pos};
@@ -2712,8 +2711,7 @@ impl<'a> Parser<'a> {
         let mut async_block_err = |e: &mut Diagnostic, span: Span| {
             recover_async = true;
             e.span_label(span, "`async` blocks are only allowed in Rust 2018 or later");
-            e.help(&format!("set `edition = \"{}\"` in `Cargo.toml`", LATEST_STABLE_EDITION));
-            e.note("for more on editions, read https://doc.rust-lang.org/edition-guide");
+            e.help_use_latest_edition();
         };
 
         while self.token != token::CloseDelim(close_delim) {
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 5db1e4e0523ff..06460c7b1b31d 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -14,7 +14,7 @@ use rustc_ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, Visibility
 use rustc_ast::{MacArgs, MacCall, MacDelimiter};
 use rustc_ast_pretty::pprust;
 use rustc_errors::{struct_span_err, Applicability, PResult, StashKey};
-use rustc_span::edition::{Edition, LATEST_STABLE_EDITION};
+use rustc_span::edition::Edition;
 use rustc_span::lev_distance::lev_distance;
 use rustc_span::source_map::{self, Span};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
@@ -2102,8 +2102,7 @@ impl<'a> Parser<'a> {
             let diag = self.diagnostic();
             struct_span_err!(diag, span, E0670, "`async fn` is not permitted in Rust 2015")
                 .span_label(span, "to use `async fn`, switch to Rust 2018 or later")
-                .help(&format!("set `edition = \"{}\"` in `Cargo.toml`", LATEST_STABLE_EDITION))
-                .note("for more on editions, read https://doc.rust-lang.org/edition-guide")
+                .help_use_latest_edition()
                 .emit();
         }
     }
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index d94ad7ba71a9c..2202001555084 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -4,7 +4,7 @@
 //! conflicts between multiple such attributes attached to the same
 //! item.
 
-use rustc_ast::{ast, AttrStyle, Attribute, Lit, LitKind, NestedMetaItem};
+use rustc_ast::{ast, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{pluralize, struct_span_err, Applicability};
 use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
@@ -178,34 +178,7 @@ impl CheckAttrVisitor<'_> {
                 check_duplicates(self.tcx, attr, hir_id, *duplicates, &mut seen);
             }
 
-            // Warn on useless empty attributes.
-            if matches!(
-                attr.name_or_empty(),
-                sym::macro_use
-                    | sym::allow
-                    | sym::warn
-                    | sym::deny
-                    | sym::forbid
-                    | sym::feature
-                    | sym::repr
-                    | sym::target_feature
-            ) && attr.meta_item_list().map_or(false, |list| list.is_empty())
-            {
-                self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
-                    lint.build("unused attribute")
-                        .span_suggestion(
-                            attr.span,
-                            "remove this attribute",
-                            String::new(),
-                            Applicability::MachineApplicable,
-                        )
-                        .note(&format!(
-                            "attribute `{}` with an empty list has no effect",
-                            attr.name_or_empty()
-                        ))
-                        .emit();
-                });
-            }
+            self.check_unused_attribute(hir_id, attr)
         }
 
         if !is_valid {
@@ -1969,6 +1942,55 @@ impl CheckAttrVisitor<'_> {
             });
         }
     }
+
+    fn check_unused_attribute(&self, hir_id: HirId, attr: &Attribute) {
+        // Warn on useless empty attributes.
+        let note = if matches!(
+            attr.name_or_empty(),
+            sym::macro_use
+                | sym::allow
+                | sym::expect
+                | sym::warn
+                | sym::deny
+                | sym::forbid
+                | sym::feature
+                | sym::repr
+                | sym::target_feature
+        ) && attr.meta_item_list().map_or(false, |list| list.is_empty())
+        {
+            format!(
+                "attribute `{}` with an empty list has no effect",
+                attr.name_or_empty()
+            )
+        } else if matches!(
+                attr.name_or_empty(),
+                sym::allow | sym::warn | sym::deny | sym::forbid | sym::expect
+            ) && let Some(meta) = attr.meta_item_list()
+            && meta.len() == 1
+            && let Some(item) = meta[0].meta_item()
+            && let MetaItemKind::NameValue(_) = &item.kind
+            && item.path == sym::reason
+        {
+            format!(
+                "attribute `{}` without any lints has no effect",
+                attr.name_or_empty()
+            )
+        } else {
+            return;
+        };
+
+        self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
+            lint.build("unused attribute")
+                .span_suggestion(
+                    attr.span,
+                    "remove this attribute",
+                    String::new(),
+                    Applicability::MachineApplicable,
+                )
+                .note(&note)
+                .emit();
+        });
+    }
 }
 
 impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index 8e245beaa3db0..7e7104f62fdc6 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -43,7 +43,6 @@ use rustc_middle::ty::error::TypeError::{FieldMisMatch, Sorts};
 use rustc_middle::ty::subst::SubstsRef;
 use rustc_middle::ty::{self, AdtKind, Ty, TypeFoldable};
 use rustc_session::parse::feature_err;
-use rustc_span::edition::LATEST_STABLE_EDITION;
 use rustc_span::hygiene::DesugaringKind;
 use rustc_span::lev_distance::find_best_match_for_name;
 use rustc_span::source_map::Span;
@@ -2010,8 +2009,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // We know by construction that `<expr>.await` is either on Rust 2015
             // or results in `ExprKind::Await`. Suggest switching the edition to 2018.
             err.note("to `.await` a `Future`, switch to Rust 2018 or later");
-            err.help(&format!("set `edition = \"{}\"` in `Cargo.toml`", LATEST_STABLE_EDITION));
-            err.note("for more on editions, read https://doc.rust-lang.org/edition-guide");
+            err.help_use_latest_edition();
         }
 
         err.emit();
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index 801e3a0b3a4cc..1827860a39045 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -632,10 +632,16 @@ impl<T, E> Result<T, E> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn ok(self) -> Option<T> {
+    #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")]
+    pub const fn ok(self) -> Option<T>
+    where
+        E: ~const Drop,
+    {
         match self {
             Ok(x) => Some(x),
-            Err(_) => None,
+            // FIXME: ~const Drop doesn't quite work right yet
+            #[allow(unused_variables)]
+            Err(x) => None,
         }
     }
 
@@ -657,9 +663,15 @@ impl<T, E> Result<T, E> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn err(self) -> Option<E> {
+    #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")]
+    pub const fn err(self) -> Option<E>
+    where
+        T: ~const Drop,
+    {
         match self {
-            Ok(_) => None,
+            // FIXME: ~const Drop doesn't quite work right yet
+            #[allow(unused_variables)]
+            Ok(x) => None,
             Err(x) => Some(x),
         }
     }
@@ -1266,10 +1278,18 @@ impl<T, E> Result<T, E> {
     /// assert_eq!(x.and(y), Ok("different result type"));
     /// ```
     #[inline]
+    #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn and<U>(self, res: Result<U, E>) -> Result<U, E> {
+    pub const fn and<U>(self, res: Result<U, E>) -> Result<U, E>
+    where
+        T: ~const Drop,
+        U: ~const Drop,
+        E: ~const Drop,
+    {
         match self {
-            Ok(_) => res,
+            // FIXME: ~const Drop doesn't quite work right yet
+            #[allow(unused_variables)]
+            Ok(x) => res,
             Err(e) => Err(e),
         }
     }
@@ -1343,11 +1363,19 @@ impl<T, E> Result<T, E> {
     /// assert_eq!(x.or(y), Ok(2));
     /// ```
     #[inline]
+    #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn or<F>(self, res: Result<T, F>) -> Result<T, F> {
+    pub const fn or<F>(self, res: Result<T, F>) -> Result<T, F>
+    where
+        T: ~const Drop,
+        E: ~const Drop,
+        F: ~const Drop,
+    {
         match self {
             Ok(v) => Ok(v),
-            Err(_) => res,
+            // FIXME: ~const Drop doesn't quite work right yet
+            #[allow(unused_variables)]
+            Err(e) => res,
         }
     }
 
@@ -1399,11 +1427,18 @@ impl<T, E> Result<T, E> {
     /// assert_eq!(x.unwrap_or(default), default);
     /// ```
     #[inline]
+    #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn unwrap_or(self, default: T) -> T {
+    pub const fn unwrap_or(self, default: T) -> T
+    where
+        T: ~const Drop,
+        E: ~const Drop,
+    {
         match self {
             Ok(t) => t,
-            Err(_) => default,
+            // FIXME: ~const Drop doesn't quite work right yet
+            #[allow(unused_variables)]
+            Err(e) => default,
         }
     }
 
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index 2b8bbe1924450..2da04ab2cea7d 100644
--- a/library/core/src/sync/atomic.rs
+++ b/library/core/src/sync/atomic.rs
@@ -352,7 +352,7 @@ impl AtomicBool {
     /// let a = &*AtomicBool::from_mut_slice(&mut some_bools);
     /// std::thread::scope(|s| {
     ///     for i in 0..a.len() {
-    ///         s.spawn(move |_| a[i].store(true, Ordering::Relaxed));
+    ///         s.spawn(move || a[i].store(true, Ordering::Relaxed));
     ///     }
     /// });
     /// assert_eq!(some_bools, [true; 10]);
@@ -984,7 +984,7 @@ impl<T> AtomicPtr<T> {
     /// let a = &*AtomicPtr::from_mut_slice(&mut some_ptrs);
     /// std::thread::scope(|s| {
     ///     for i in 0..a.len() {
-    ///         s.spawn(move |_| {
+    ///         s.spawn(move || {
     ///             let name = Box::new(format!("thread{i}"));
     ///             a[i].store(Box::into_raw(name), Ordering::Relaxed);
     ///         });
@@ -1533,7 +1533,7 @@ macro_rules! atomic_int {
             #[doc = concat!("let a = &*", stringify!($atomic_type), "::from_mut_slice(&mut some_ints);")]
             /// std::thread::scope(|s| {
             ///     for i in 0..a.len() {
-            ///         s.spawn(move |_| a[i].store(i as _, Ordering::Relaxed));
+            ///         s.spawn(move || a[i].store(i as _, Ordering::Relaxed));
             ///     }
             /// });
             /// for (i, n) in some_ints.into_iter().enumerate() {
diff --git a/library/std/src/sys/unix/rwlock.rs b/library/std/src/sys/unix/rwlock.rs
index b1faf12c22614..1318c5b8e3a61 100644
--- a/library/std/src/sys/unix/rwlock.rs
+++ b/library/std/src/sys/unix/rwlock.rs
@@ -48,9 +48,9 @@ impl RWLock {
             }
             panic!("rwlock read lock would result in deadlock");
         } else {
-            // According to POSIX, for a properly initialized rwlock this can only
-            // return EAGAIN or EDEADLK or 0. We rely on that.
-            debug_assert_eq!(r, 0);
+            // POSIX does not make guarantees about all the errors that may be returned.
+            // See issue #94705 for more details.
+            assert_eq!(r, 0, "unexpected error during rwlock read lock: {:?}", r);
             self.num_readers.fetch_add(1, Ordering::Relaxed);
         }
     }
diff --git a/library/std/src/thread/scoped.rs b/library/std/src/thread/scoped.rs
index ea9623be63bc7..4af58f1a38075 100644
--- a/library/std/src/thread/scoped.rs
+++ b/library/std/src/thread/scoped.rs
@@ -9,23 +9,24 @@ use crate::sync::Arc;
 /// A scope to spawn scoped threads in.
 ///
 /// See [`scope`] for details.
-pub struct Scope<'env> {
+pub struct Scope<'scope, 'env: 'scope> {
     data: ScopeData,
-    /// Invariance over 'env, to make sure 'env cannot shrink,
+    /// Invariance over 'scope, to make sure 'scope cannot shrink,
     /// which is necessary for soundness.
     ///
     /// Without invariance, this would compile fine but be unsound:
     ///
-    /// ```compile_fail
+    /// ```compile_fail,E0373
     /// #![feature(scoped_threads)]
     ///
     /// std::thread::scope(|s| {
-    ///     s.spawn(|s| {
+    ///     s.spawn(|| {
     ///         let a = String::from("abcd");
-    ///         s.spawn(|_| println!("{:?}", a)); // might run after `a` is dropped
+    ///         s.spawn(|| println!("{:?}", a)); // might run after `a` is dropped
     ///     });
     /// });
     /// ```
+    scope: PhantomData<&'scope mut &'scope ()>,
     env: PhantomData<&'env mut &'env ()>,
 }
 
@@ -88,12 +89,12 @@ impl ScopeData {
 /// let mut x = 0;
 ///
 /// thread::scope(|s| {
-///     s.spawn(|_| {
+///     s.spawn(|| {
 ///         println!("hello from the first scoped thread");
 ///         // We can borrow `a` here.
 ///         dbg!(&a);
 ///     });
-///     s.spawn(|_| {
+///     s.spawn(|| {
 ///         println!("hello from the second scoped thread");
 ///         // We can even mutably borrow `x` here,
 ///         // because no other threads are using it.
@@ -109,7 +110,7 @@ impl ScopeData {
 #[track_caller]
 pub fn scope<'env, F, T>(f: F) -> T
 where
-    F: FnOnce(&Scope<'env>) -> T,
+    F: for<'scope> FnOnce(&'scope Scope<'scope, 'env>) -> T,
 {
     let scope = Scope {
         data: ScopeData {
@@ -118,6 +119,7 @@ where
             a_thread_panicked: AtomicBool::new(false),
         },
         env: PhantomData,
+        scope: PhantomData,
     };
 
     // Run `f`, but catch panics so we can make sure to wait for all the threads to join.
@@ -138,7 +140,7 @@ where
     }
 }
 
-impl<'env> Scope<'env> {
+impl<'scope, 'env> Scope<'scope, 'env> {
     /// Spawns a new thread within a scope, returning a [`ScopedJoinHandle`] for it.
     ///
     /// Unlike non-scoped threads, threads spawned with this function may
@@ -163,10 +165,10 @@ impl<'env> Scope<'env> {
     /// to recover from such errors.
     ///
     /// [`join`]: ScopedJoinHandle::join
-    pub fn spawn<'scope, F, T>(&'scope self, f: F) -> ScopedJoinHandle<'scope, T>
+    pub fn spawn<F, T>(&'scope self, f: F) -> ScopedJoinHandle<'scope, T>
     where
-        F: FnOnce(&Scope<'env>) -> T + Send + 'env,
-        T: Send + 'env,
+        F: FnOnce() -> T + Send + 'scope,
+        T: Send + 'scope,
     {
         Builder::new().spawn_scoped(self, f).expect("failed to spawn thread")
     }
@@ -196,7 +198,7 @@ impl Builder {
     /// thread::scope(|s| {
     ///     thread::Builder::new()
     ///         .name("first".to_string())
-    ///         .spawn_scoped(s, |_|
+    ///         .spawn_scoped(s, ||
     ///     {
     ///         println!("hello from the {:?} scoped thread", thread::current().name());
     ///         // We can borrow `a` here.
@@ -205,7 +207,7 @@ impl Builder {
     ///     .unwrap();
     ///     thread::Builder::new()
     ///         .name("second".to_string())
-    ///         .spawn_scoped(s, |_|
+    ///         .spawn_scoped(s, ||
     ///     {
     ///         println!("hello from the {:?} scoped thread", thread::current().name());
     ///         // We can even mutably borrow `x` here,
@@ -222,14 +224,14 @@ impl Builder {
     /// ```
     pub fn spawn_scoped<'scope, 'env, F, T>(
         self,
-        scope: &'scope Scope<'env>,
+        scope: &'scope Scope<'scope, 'env>,
         f: F,
     ) -> io::Result<ScopedJoinHandle<'scope, T>>
     where
-        F: FnOnce(&Scope<'env>) -> T + Send + 'env,
-        T: Send + 'env,
+        F: FnOnce() -> T + Send + 'scope,
+        T: Send + 'scope,
     {
-        Ok(ScopedJoinHandle(unsafe { self.spawn_unchecked_(|| f(scope), Some(&scope.data)) }?))
+        Ok(ScopedJoinHandle(unsafe { self.spawn_unchecked_(f, Some(&scope.data)) }?))
     }
 }
 
@@ -244,7 +246,7 @@ impl<'scope, T> ScopedJoinHandle<'scope, T> {
     /// use std::thread;
     ///
     /// thread::scope(|s| {
-    ///     let t = s.spawn(|_| {
+    ///     let t = s.spawn(|| {
     ///         println!("hello");
     ///     });
     ///     println!("thread id: {:?}", t.thread().id());
@@ -277,7 +279,7 @@ impl<'scope, T> ScopedJoinHandle<'scope, T> {
     /// use std::thread;
     ///
     /// thread::scope(|s| {
-    ///     let t = s.spawn(|_| {
+    ///     let t = s.spawn(|| {
     ///         panic!("oh no");
     ///     });
     ///     assert!(t.join().is_err());
@@ -302,7 +304,7 @@ impl<'scope, T> ScopedJoinHandle<'scope, T> {
     }
 }
 
-impl<'env> fmt::Debug for Scope<'env> {
+impl fmt::Debug for Scope<'_, '_> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("Scope")
             .field("num_running_threads", &self.data.num_running_threads.load(Ordering::Relaxed))
diff --git a/src/test/ui/async-await/edition-deny-async-fns-2015.stderr b/src/test/ui/async-await/edition-deny-async-fns-2015.stderr
index 8fb570d67562a..35f9c581c7b21 100644
--- a/src/test/ui/async-await/edition-deny-async-fns-2015.stderr
+++ b/src/test/ui/async-await/edition-deny-async-fns-2015.stderr
@@ -4,7 +4,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015
 LL | async fn foo() {}
    | ^^^^^ to use `async fn`, switch to Rust 2018 or later
    |
-   = help: set `edition = "2021"` in `Cargo.toml`
+   = help: pass `--edition 2021` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
@@ -13,7 +13,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015
 LL | fn baz() { async fn foo() {} }
    |            ^^^^^ to use `async fn`, switch to Rust 2018 or later
    |
-   = help: set `edition = "2021"` in `Cargo.toml`
+   = help: pass `--edition 2021` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
@@ -22,7 +22,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015
 LL | async fn async_baz() {
    | ^^^^^ to use `async fn`, switch to Rust 2018 or later
    |
-   = help: set `edition = "2021"` in `Cargo.toml`
+   = help: pass `--edition 2021` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
@@ -31,7 +31,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015
 LL |     async fn bar() {}
    |     ^^^^^ to use `async fn`, switch to Rust 2018 or later
    |
-   = help: set `edition = "2021"` in `Cargo.toml`
+   = help: pass `--edition 2021` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
@@ -40,7 +40,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015
 LL |     async fn foo() {}
    |     ^^^^^ to use `async fn`, switch to Rust 2018 or later
    |
-   = help: set `edition = "2021"` in `Cargo.toml`
+   = help: pass `--edition 2021` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
@@ -49,7 +49,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015
 LL |     async fn foo() {}
    |     ^^^^^ to use `async fn`, switch to Rust 2018 or later
    |
-   = help: set `edition = "2021"` in `Cargo.toml`
+   = help: pass `--edition 2021` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
@@ -58,7 +58,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015
 LL |         async fn bar() {}
    |         ^^^^^ to use `async fn`, switch to Rust 2018 or later
    |
-   = help: set `edition = "2021"` in `Cargo.toml`
+   = help: pass `--edition 2021` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
@@ -67,7 +67,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015
 LL |         async fn foo() {}
    |         ^^^^^ to use `async fn`, switch to Rust 2018 or later
    |
-   = help: set `edition = "2021"` in `Cargo.toml`
+   = help: pass `--edition 2021` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
@@ -76,7 +76,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015
 LL |             async fn bar() {}
    |             ^^^^^ to use `async fn`, switch to Rust 2018 or later
    |
-   = help: set `edition = "2021"` in `Cargo.toml`
+   = help: pass `--edition 2021` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0706]: functions in traits cannot be declared `async`
diff --git a/src/test/ui/async-await/suggest-switching-edition-on-await-cargo.rs b/src/test/ui/async-await/suggest-switching-edition-on-await-cargo.rs
new file mode 100644
index 0000000000000..4919e0a051dcb
--- /dev/null
+++ b/src/test/ui/async-await/suggest-switching-edition-on-await-cargo.rs
@@ -0,0 +1,47 @@
+// rustc-env:CARGO=/usr/bin/cargo
+
+use std::pin::Pin;
+use std::future::Future;
+
+fn main() {}
+
+fn await_on_struct_missing() {
+    struct S;
+    let x = S;
+    x.await;
+    //~^ ERROR no field `await` on type
+    //~| NOTE unknown field
+    //~| NOTE to `.await` a `Future`, switch to Rust 2018
+    //~| HELP set `edition = "2021"` in `Cargo.toml`
+    //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
+}
+
+fn await_on_struct_similar() {
+    struct S {
+        awai: u8,
+    }
+    let x = S { awai: 42 };
+    x.await;
+    //~^ ERROR no field `await` on type
+    //~| HELP a field with a similar name exists
+    //~| NOTE to `.await` a `Future`, switch to Rust 2018
+    //~| HELP set `edition = "2021"` in `Cargo.toml`
+    //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
+}
+
+fn await_on_63533(x: Pin<&mut dyn Future<Output = ()>>) {
+    x.await;
+    //~^ ERROR no field `await` on type
+    //~| NOTE unknown field
+    //~| NOTE to `.await` a `Future`, switch to Rust 2018
+    //~| HELP set `edition = "2021"` in `Cargo.toml`
+    //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
+}
+
+fn await_on_apit(x: impl Future<Output = ()>) {
+    x.await;
+    //~^ ERROR no field `await` on type
+    //~| NOTE to `.await` a `Future`, switch to Rust 2018
+    //~| HELP set `edition = "2021"` in `Cargo.toml`
+    //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
+}
diff --git a/src/test/ui/async-await/suggest-switching-edition-on-await-cargo.stderr b/src/test/ui/async-await/suggest-switching-edition-on-await-cargo.stderr
new file mode 100644
index 0000000000000..409eb179e83a0
--- /dev/null
+++ b/src/test/ui/async-await/suggest-switching-edition-on-await-cargo.stderr
@@ -0,0 +1,43 @@
+error[E0609]: no field `await` on type `await_on_struct_missing::S`
+  --> $DIR/suggest-switching-edition-on-await-cargo.rs:11:7
+   |
+LL |     x.await;
+   |       ^^^^^ unknown field
+   |
+   = note: to `.await` a `Future`, switch to Rust 2018 or later
+   = help: set `edition = "2021"` in `Cargo.toml`
+   = note: for more on editions, read https://doc.rust-lang.org/edition-guide
+
+error[E0609]: no field `await` on type `await_on_struct_similar::S`
+  --> $DIR/suggest-switching-edition-on-await-cargo.rs:24:7
+   |
+LL |     x.await;
+   |       ^^^^^ help: a field with a similar name exists: `awai`
+   |
+   = note: to `.await` a `Future`, switch to Rust 2018 or later
+   = help: set `edition = "2021"` in `Cargo.toml`
+   = note: for more on editions, read https://doc.rust-lang.org/edition-guide
+
+error[E0609]: no field `await` on type `Pin<&mut dyn Future<Output = ()>>`
+  --> $DIR/suggest-switching-edition-on-await-cargo.rs:33:7
+   |
+LL |     x.await;
+   |       ^^^^^ unknown field
+   |
+   = note: to `.await` a `Future`, switch to Rust 2018 or later
+   = help: set `edition = "2021"` in `Cargo.toml`
+   = note: for more on editions, read https://doc.rust-lang.org/edition-guide
+
+error[E0609]: no field `await` on type `impl Future<Output = ()>`
+  --> $DIR/suggest-switching-edition-on-await-cargo.rs:42:7
+   |
+LL |     x.await;
+   |       ^^^^^
+   |
+   = note: to `.await` a `Future`, switch to Rust 2018 or later
+   = help: set `edition = "2021"` in `Cargo.toml`
+   = note: for more on editions, read https://doc.rust-lang.org/edition-guide
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0609`.
diff --git a/src/test/ui/async-await/suggest-switching-edition-on-await.rs b/src/test/ui/async-await/suggest-switching-edition-on-await.rs
index f2e0fb19c631d..9852e8fc918fe 100644
--- a/src/test/ui/async-await/suggest-switching-edition-on-await.rs
+++ b/src/test/ui/async-await/suggest-switching-edition-on-await.rs
@@ -10,7 +10,7 @@ fn await_on_struct_missing() {
     //~^ ERROR no field `await` on type
     //~| NOTE unknown field
     //~| NOTE to `.await` a `Future`, switch to Rust 2018
-    //~| HELP set `edition = "2021"` in `Cargo.toml`
+    //~| HELP pass `--edition 2021` to `rustc`
     //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
 }
 
@@ -23,7 +23,7 @@ fn await_on_struct_similar() {
     //~^ ERROR no field `await` on type
     //~| HELP a field with a similar name exists
     //~| NOTE to `.await` a `Future`, switch to Rust 2018
-    //~| HELP set `edition = "2021"` in `Cargo.toml`
+    //~| HELP pass `--edition 2021` to `rustc`
     //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
 }
 
@@ -32,7 +32,7 @@ fn await_on_63533(x: Pin<&mut dyn Future<Output = ()>>) {
     //~^ ERROR no field `await` on type
     //~| NOTE unknown field
     //~| NOTE to `.await` a `Future`, switch to Rust 2018
-    //~| HELP set `edition = "2021"` in `Cargo.toml`
+    //~| HELP pass `--edition 2021` to `rustc`
     //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
 }
 
@@ -40,6 +40,6 @@ fn await_on_apit(x: impl Future<Output = ()>) {
     x.await;
     //~^ ERROR no field `await` on type
     //~| NOTE to `.await` a `Future`, switch to Rust 2018
-    //~| HELP set `edition = "2021"` in `Cargo.toml`
+    //~| HELP pass `--edition 2021` to `rustc`
     //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
 }
diff --git a/src/test/ui/async-await/suggest-switching-edition-on-await.stderr b/src/test/ui/async-await/suggest-switching-edition-on-await.stderr
index b38c897fc7447..ef3334381b715 100644
--- a/src/test/ui/async-await/suggest-switching-edition-on-await.stderr
+++ b/src/test/ui/async-await/suggest-switching-edition-on-await.stderr
@@ -5,7 +5,7 @@ LL |     x.await;
    |       ^^^^^ unknown field
    |
    = note: to `.await` a `Future`, switch to Rust 2018 or later
-   = help: set `edition = "2021"` in `Cargo.toml`
+   = help: pass `--edition 2021` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0609]: no field `await` on type `await_on_struct_similar::S`
@@ -15,7 +15,7 @@ LL |     x.await;
    |       ^^^^^ help: a field with a similar name exists: `awai`
    |
    = note: to `.await` a `Future`, switch to Rust 2018 or later
-   = help: set `edition = "2021"` in `Cargo.toml`
+   = help: pass `--edition 2021` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0609]: no field `await` on type `Pin<&mut dyn Future<Output = ()>>`
@@ -25,7 +25,7 @@ LL |     x.await;
    |       ^^^^^ unknown field
    |
    = note: to `.await` a `Future`, switch to Rust 2018 or later
-   = help: set `edition = "2021"` in `Cargo.toml`
+   = help: pass `--edition 2021` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0609]: no field `await` on type `impl Future<Output = ()>`
@@ -35,7 +35,7 @@ LL |     x.await;
    |       ^^^^^
    |
    = note: to `.await` a `Future`, switch to Rust 2018 or later
-   = help: set `edition = "2021"` in `Cargo.toml`
+   = help: pass `--edition 2021` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error: aborting due to 4 previous errors
diff --git a/src/test/ui/closures/2229_closure_analysis/match/issue-88331.stderr b/src/test/ui/closures/2229_closure_analysis/match/issue-88331.stderr
index f02d23464f168..7e22defa98dd4 100644
--- a/src/test/ui/closures/2229_closure_analysis/match/issue-88331.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/match/issue-88331.stderr
@@ -1,26 +1,38 @@
 error[E0004]: non-exhaustive patterns: `Opcode(0_u8)` and `Opcode(2_u8..=u8::MAX)` not covered
   --> $DIR/issue-88331.rs:11:20
    |
-LL | pub struct Opcode(pub u8);
-   | -------------------------- `Opcode` defined here
-...
 LL |     move |i| match msg_type {
    |                    ^^^^^^^^ patterns `Opcode(0_u8)` and `Opcode(2_u8..=u8::MAX)` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `Opcode` defined here
+  --> $DIR/issue-88331.rs:4:12
+   |
+LL | pub struct Opcode(pub u8);
+   |            ^^^^^^
    = note: the matched value is of type `Opcode`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~         Opcode::OP1 => unimplemented!(),
+LL ~         Opcode(0_u8) | Opcode(2_u8..=u8::MAX) => todo!(),
+   |
 
 error[E0004]: non-exhaustive patterns: `Opcode2(Opcode(0_u8))` and `Opcode2(Opcode(2_u8..=u8::MAX))` not covered
   --> $DIR/issue-88331.rs:27:20
    |
-LL | pub struct Opcode2(Opcode);
-   | --------------------------- `Opcode2` defined here
-...
 LL |     move |i| match msg_type {
    |                    ^^^^^^^^ patterns `Opcode2(Opcode(0_u8))` and `Opcode2(Opcode(2_u8..=u8::MAX))` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `Opcode2` defined here
+  --> $DIR/issue-88331.rs:18:12
+   |
+LL | pub struct Opcode2(Opcode);
+   |            ^^^^^^^
    = note: the matched value is of type `Opcode2`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~         Opcode2::OP2=> unimplemented!(),
+LL ~         Opcode2(Opcode(0_u8)) | Opcode2(Opcode(2_u8..=u8::MAX)) => todo!(),
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr b/src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr
index 91ffe1a47f413..32d36274ff6ef 100644
--- a/src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr
@@ -1,17 +1,19 @@
 error[E0004]: non-exhaustive patterns: `B` not covered
   --> $DIR/non-exhaustive-match.rs:26:25
    |
-LL | enum L1 { A, B }
-   | ----------------
-   | |            |
-   | |            not covered
-   | `L1` defined here
-...
 LL |     let _b = || { match l1 { L1::A => () } };
    |                         ^^ pattern `B` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `L1` defined here
+  --> $DIR/non-exhaustive-match.rs:12:14
+   |
+LL | enum L1 { A, B }
+   |      --      ^ not covered
    = note: the matched value is of type `L1`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL |     let _b = || { match l1 { L1::A => (), B => todo!() } };
+   |                                         ++++++++++++++
 
 error[E0004]: non-exhaustive patterns: type `E1` is non-empty
   --> $DIR/non-exhaustive-match.rs:37:25
@@ -19,8 +21,18 @@ error[E0004]: non-exhaustive patterns: type `E1` is non-empty
 LL |     let _d = || { match e1 {} };
    |                         ^^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `E1` defined here
+  --> $DIR/auxiliary/match_non_exhaustive_lib.rs:2:1
+   |
+LL | pub enum E1 {}
+   | ^^^^^^^^^^^^^^
    = note: the matched value is of type `E1`, which is marked as non-exhaustive
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     let _d = || { match e1 {
+LL +         _ => todo!(),
+LL ~     } };
+   |
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/non-exhaustive-match.rs:39:25
@@ -28,8 +40,16 @@ error[E0004]: non-exhaustive patterns: `_` not covered
 LL |     let _e = || { match e2 { E2::A => (), E2::B => () } };
    |                         ^^ pattern `_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `E2` defined here
+  --> $DIR/auxiliary/match_non_exhaustive_lib.rs:5:1
+   |
+LL | pub enum E2 { A, B }
+   | ^^^^^^^^^^^^^^^^^^^^
    = note: the matched value is of type `E2`, which is marked as non-exhaustive
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL |     let _e = || { match e2 { E2::A => (), E2::B => (), _ => todo!() } };
+   |                                                      ++++++++++++++
 
 error[E0505]: cannot move out of `e3` because it is borrowed
   --> $DIR/non-exhaustive-match.rs:46:22
diff --git a/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr b/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr
index 45641ea3de3e0..e55fb7ce4bbe9 100644
--- a/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr
@@ -4,8 +4,13 @@ error[E0004]: non-exhaustive patterns: type `u8` is non-empty
 LL |     let c1 = || match x { };
    |                       ^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u8`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     let c1 = || match x {
+LL +         _ => todo!(),
+LL ~     };
+   |
 
 error[E0381]: use of possibly-uninitialized variable: `x`
   --> $DIR/pattern-matching-should-fail.rs:8:23
diff --git a/src/test/ui/editions/async-block-2015.rs b/src/test/ui/editions/async-block-2015.rs
index 24112c9855acd..3daf4930c5b4b 100644
--- a/src/test/ui/editions/async-block-2015.rs
+++ b/src/test/ui/editions/async-block-2015.rs
@@ -1,7 +1,7 @@
 async fn foo() {
 //~^ ERROR `async fn` is not permitted in Rust 2015
 //~| NOTE to use `async fn`, switch to Rust 2018 or later
-//~| HELP set `edition = "2021"` in `Cargo.toml`
+//~| HELP pass `--edition 2021` to `rustc`
 //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
 
     let x = async {};
@@ -11,7 +11,7 @@ async fn foo() {
         let x = 42;
         //~^ ERROR expected identifier, found keyword `let`
         //~| NOTE expected identifier, found keyword
-        //~| HELP set `edition = "2021"` in `Cargo.toml`
+        //~| HELP pass `--edition 2021` to `rustc`
         //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
         42
     };
@@ -19,7 +19,7 @@ async fn foo() {
         42
         //~^ ERROR expected identifier, found `42`
         //~| NOTE expected identifier
-        //~| HELP set `edition = "2021"` in `Cargo.toml`
+        //~| HELP pass `--edition 2021` to `rustc`
         //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
     };
     y.await;
diff --git a/src/test/ui/editions/async-block-2015.stderr b/src/test/ui/editions/async-block-2015.stderr
index da8412ddcb333..b792b8c1e0dd8 100644
--- a/src/test/ui/editions/async-block-2015.stderr
+++ b/src/test/ui/editions/async-block-2015.stderr
@@ -4,7 +4,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015
 LL | async fn foo() {
    | ^^^^^ to use `async fn`, switch to Rust 2018 or later
    |
-   = help: set `edition = "2021"` in `Cargo.toml`
+   = help: pass `--edition 2021` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error: expected identifier, found keyword `let`
@@ -15,7 +15,7 @@ LL |     let y = async {
 LL |         let x = 42;
    |         ^^^ expected identifier, found keyword
    |
-   = help: set `edition = "2021"` in `Cargo.toml`
+   = help: pass `--edition 2021` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error: expected identifier, found `42`
@@ -26,7 +26,7 @@ LL |     let z = async {
 LL |         42
    |         ^^ expected identifier
    |
-   = help: set `edition = "2021"` in `Cargo.toml`
+   = help: pass `--edition 2021` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0422]: cannot find struct, variant or union type `async` in this scope
diff --git a/src/test/ui/empty/empty-attributes.rs b/src/test/ui/empty/empty-attributes.rs
index 7e9b05587b075..d319227b217a7 100644
--- a/src/test/ui/empty/empty-attributes.rs
+++ b/src/test/ui/empty/empty-attributes.rs
@@ -1,5 +1,8 @@
+#![feature(lint_reasons)]
+
 #![deny(unused_attributes)]
 #![allow()] //~ ERROR unused attribute
+#![expect()] //~ ERROR unused attribute
 #![warn()] //~ ERROR unused attribute
 #![deny()] //~ ERROR unused attribute
 #![forbid()] //~ ERROR unused attribute
diff --git a/src/test/ui/empty/empty-attributes.stderr b/src/test/ui/empty/empty-attributes.stderr
index e0798e4f0c69f..8653eaf5ccdf3 100644
--- a/src/test/ui/empty/empty-attributes.stderr
+++ b/src/test/ui/empty/empty-attributes.stderr
@@ -1,18 +1,18 @@
 error: unused attribute
-  --> $DIR/empty-attributes.rs:8:1
+  --> $DIR/empty-attributes.rs:11:1
    |
 LL | #[repr()]
    | ^^^^^^^^^ help: remove this attribute
    |
 note: the lint level is defined here
-  --> $DIR/empty-attributes.rs:1:9
+  --> $DIR/empty-attributes.rs:3:9
    |
 LL | #![deny(unused_attributes)]
    |         ^^^^^^^^^^^^^^^^^
    = note: attribute `repr` with an empty list has no effect
 
 error: unused attribute
-  --> $DIR/empty-attributes.rs:11:1
+  --> $DIR/empty-attributes.rs:14:1
    |
 LL | #[target_feature()]
    | ^^^^^^^^^^^^^^^^^^^ help: remove this attribute
@@ -20,7 +20,7 @@ LL | #[target_feature()]
    = note: attribute `target_feature` with an empty list has no effect
 
 error: unused attribute
-  --> $DIR/empty-attributes.rs:2:1
+  --> $DIR/empty-attributes.rs:4:1
    |
 LL | #![allow()]
    | ^^^^^^^^^^^ help: remove this attribute
@@ -28,7 +28,15 @@ LL | #![allow()]
    = note: attribute `allow` with an empty list has no effect
 
 error: unused attribute
-  --> $DIR/empty-attributes.rs:3:1
+  --> $DIR/empty-attributes.rs:5:1
+   |
+LL | #![expect()]
+   | ^^^^^^^^^^^^ help: remove this attribute
+   |
+   = note: attribute `expect` with an empty list has no effect
+
+error: unused attribute
+  --> $DIR/empty-attributes.rs:6:1
    |
 LL | #![warn()]
    | ^^^^^^^^^^ help: remove this attribute
@@ -36,7 +44,7 @@ LL | #![warn()]
    = note: attribute `warn` with an empty list has no effect
 
 error: unused attribute
-  --> $DIR/empty-attributes.rs:4:1
+  --> $DIR/empty-attributes.rs:7:1
    |
 LL | #![deny()]
    | ^^^^^^^^^^ help: remove this attribute
@@ -44,7 +52,7 @@ LL | #![deny()]
    = note: attribute `deny` with an empty list has no effect
 
 error: unused attribute
-  --> $DIR/empty-attributes.rs:5:1
+  --> $DIR/empty-attributes.rs:8:1
    |
 LL | #![forbid()]
    | ^^^^^^^^^^^^ help: remove this attribute
@@ -52,12 +60,12 @@ LL | #![forbid()]
    = note: attribute `forbid` with an empty list has no effect
 
 error: unused attribute
-  --> $DIR/empty-attributes.rs:6:1
+  --> $DIR/empty-attributes.rs:9:1
    |
 LL | #![feature()]
    | ^^^^^^^^^^^^^ help: remove this attribute
    |
    = note: attribute `feature` with an empty list has no effect
 
-error: aborting due to 7 previous errors
+error: aborting due to 8 previous errors
 
diff --git a/src/test/ui/empty/empty-never-array.stderr b/src/test/ui/empty/empty-never-array.stderr
index 64d640c0e9dbc..8dd0f377533ce 100644
--- a/src/test/ui/empty/empty-never-array.stderr
+++ b/src/test/ui/empty/empty-never-array.stderr
@@ -1,19 +1,18 @@
 error[E0005]: refutable pattern in local binding: `T(_, _)` not covered
   --> $DIR/empty-never-array.rs:10:9
    |
-LL | / enum Helper<T, U> {
-LL | |     T(T, [!; 0]),
-   | |     - not covered
-LL | |     #[allow(dead_code)]
-LL | |     U(U),
-LL | | }
-   | |_- `Helper<T, U>` defined here
-...
-LL |       let Helper::U(u) = Helper::T(t, []);
-   |           ^^^^^^^^^^^^ pattern `T(_, _)` not covered
+LL |     let Helper::U(u) = Helper::T(t, []);
+   |         ^^^^^^^^^^^^ pattern `T(_, _)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+note: `Helper<T, U>` defined here
+  --> $DIR/empty-never-array.rs:4:5
+   |
+LL | enum Helper<T, U> {
+   |      ------
+LL |     T(T, [!; 0]),
+   |     ^ not covered
    = note: the matched value is of type `Helper<T, U>`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
diff --git a/src/test/ui/error-codes/E0004-2.stderr b/src/test/ui/error-codes/E0004-2.stderr
index fd0215e72ee24..d4519af540859 100644
--- a/src/test/ui/error-codes/E0004-2.stderr
+++ b/src/test/ui/error-codes/E0004-2.stderr
@@ -4,16 +4,27 @@ error[E0004]: non-exhaustive patterns: `None` and `Some(_)` not covered
 LL |     match x { }
    |           ^ patterns `None` and `Some(_)` not covered
    |
-  ::: $SRC_DIR/core/src/option.rs:LL:COL
+note: `Option<i32>` defined here
+  --> $SRC_DIR/core/src/option.rs:LL:COL
    |
-LL |     None,
-   |     ---- not covered
-...
-LL |     Some(#[stable(feature = "rust1", since = "1.0.0")] T),
-   |     ---- not covered
-   |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | / pub enum Option<T> {
+LL | |     /// No value.
+LL | |     #[lang = "None"]
+LL | |     #[stable(feature = "rust1", since = "1.0.0")]
+LL | |     None,
+   | |     ^^^^ not covered
+...  |
+LL | |     Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+   | |     ^^^^ not covered
+LL | | }
+   | |_-
    = note: the matched value is of type `Option<i32>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~     match x {
+LL +         None | Some(_) => todo!(),
+LL ~     }
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0004.stderr b/src/test/ui/error-codes/E0004.stderr
index 5bf375a64843a..8ba151d9e65fa 100644
--- a/src/test/ui/error-codes/E0004.stderr
+++ b/src/test/ui/error-codes/E0004.stderr
@@ -1,18 +1,22 @@
 error[E0004]: non-exhaustive patterns: `HastaLaVistaBaby` not covered
   --> $DIR/E0004.rs:9:11
    |
-LL | / enum Terminator {
-LL | |     HastaLaVistaBaby,
-   | |     ---------------- not covered
-LL | |     TalkToMyHand,
-LL | | }
-   | |_- `Terminator` defined here
-...
-LL |       match x {
-   |             ^ pattern `HastaLaVistaBaby` not covered
+LL |     match x {
+   |           ^ pattern `HastaLaVistaBaby` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `Terminator` defined here
+  --> $DIR/E0004.rs:2:5
+   |
+LL | enum Terminator {
+   |      ----------
+LL |     HastaLaVistaBaby,
+   |     ^^^^^^^^^^^^^^^^ not covered
    = note: the matched value is of type `Terminator`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         Terminator::TalkToMyHand => {}
+LL +         HastaLaVistaBaby => todo!()
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0005.stderr b/src/test/ui/error-codes/E0005.stderr
index b95dcbd8935b3..208c625a53e95 100644
--- a/src/test/ui/error-codes/E0005.stderr
+++ b/src/test/ui/error-codes/E0005.stderr
@@ -4,13 +4,21 @@ error[E0005]: refutable pattern in local binding: `None` not covered
 LL |     let Some(y) = x;
    |         ^^^^^^^ pattern `None` not covered
    |
-  ::: $SRC_DIR/core/src/option.rs:LL:COL
-   |
-LL |     None,
-   |     ---- not covered
-   |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+note: `Option<i32>` defined here
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+   |
+LL | / pub enum Option<T> {
+LL | |     /// No value.
+LL | |     #[lang = "None"]
+LL | |     #[stable(feature = "rust1", since = "1.0.0")]
+LL | |     None,
+   | |     ^^^^ not covered
+...  |
+LL | |     Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+LL | | }
+   | |_-
    = note: the matched value is of type `Option<i32>`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
diff --git a/src/test/ui/error-codes/E0297.stderr b/src/test/ui/error-codes/E0297.stderr
index 957e79a9f3981..95d95003c616f 100644
--- a/src/test/ui/error-codes/E0297.stderr
+++ b/src/test/ui/error-codes/E0297.stderr
@@ -4,11 +4,19 @@ error[E0005]: refutable pattern in `for` loop binding: `None` not covered
 LL |     for Some(x) in xs {}
    |         ^^^^^^^ pattern `None` not covered
    |
-  ::: $SRC_DIR/core/src/option.rs:LL:COL
-   |
-LL |     None,
-   |     ---- not covered
+note: `Option<i32>` defined here
+  --> $SRC_DIR/core/src/option.rs:LL:COL
    |
+LL | / pub enum Option<T> {
+LL | |     /// No value.
+LL | |     #[lang = "None"]
+LL | |     #[stable(feature = "rust1", since = "1.0.0")]
+LL | |     None,
+   | |     ^^^^ not covered
+...  |
+LL | |     Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+LL | | }
+   | |_-
    = note: the matched value is of type `Option<i32>`
 
 error: aborting due to previous error
diff --git a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr
index c5ffa55ebec6f..c2ffda6bb72d2 100644
--- a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr
+++ b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr
@@ -4,13 +4,20 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered
 LL |     let Ok(_x) = foo();
    |         ^^^^^^ pattern `Err(_)` not covered
    |
-  ::: $SRC_DIR/core/src/result.rs:LL:COL
-   |
-LL |     Err(#[stable(feature = "rust1", since = "1.0.0")] E),
-   |     --- not covered
-   |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+note: `Result<u32, !>` defined here
+  --> $SRC_DIR/core/src/result.rs:LL:COL
+   |
+LL | / pub enum Result<T, E> {
+LL | |     /// Contains the success value
+LL | |     #[lang = "Ok"]
+LL | |     #[stable(feature = "rust1", since = "1.0.0")]
+...  |
+LL | |     Err(#[stable(feature = "rust1", since = "1.0.0")] E),
+   | |     ^^^ not covered
+LL | | }
+   | |_-
    = note: the matched value is of type `Result<u32, !>`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
diff --git a/src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.stderr b/src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.stderr
index 9895646fc2ba4..b5510683328f5 100644
--- a/src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.stderr
+++ b/src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.stderr
@@ -4,10 +4,14 @@ error[E0004]: non-exhaustive patterns: `_` not covered
 LL |     match 0usize {
    |           ^^^^^^ pattern `_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `usize`
    = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
    = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         0..=usize::MAX => {}
+LL +         _ => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/feature-gate-precise_pointer_size_matching.rs:10:11
@@ -15,10 +19,14 @@ error[E0004]: non-exhaustive patterns: `_` not covered
 LL |     match 0isize {
    |           ^^^^^^ pattern `_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `isize`
    = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
    = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         isize::MIN..=isize::MAX => {}
+LL +         _ => todo!()
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.rs b/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.rs
index 04f816ea50164..667bc9f8ddf18 100644
--- a/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.rs
+++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.rs
@@ -2,6 +2,6 @@
 
 #[rustc_variance] //~ ERROR the `#[rustc_variance]` attribute is just used for rustc unit tests and will never be stable
 #[rustc_error] //~ ERROR the `#[rustc_error]` attribute is just used for rustc unit tests and will never be stable
-#[rustc_nonnull_optimization_guaranteed] //~ ERROR the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to enable niche optimizations in libcore and will never be stable
+#[rustc_nonnull_optimization_guaranteed] //~ ERROR the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to enable niche optimizations in libcore and libstd and will never be stable
 
 fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.stderr b/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.stderr
index 822368a5946ec..45a095903d2a7 100644
--- a/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.stderr
+++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.stderr
@@ -14,7 +14,7 @@ LL | #[rustc_error]
    |
    = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
 
-error[E0658]: the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to enable niche optimizations in libcore and will never be stable
+error[E0658]: the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to enable niche optimizations in libcore and libstd and will never be stable
   --> $DIR/feature-gate-rustc-attrs-1.rs:5:1
    |
 LL | #[rustc_nonnull_optimization_guaranteed]
diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr b/src/test/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr
index 14dbca60b78f2..c2c77290c4374 100644
--- a/src/test/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr
+++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr
@@ -4,8 +4,12 @@ error[E0004]: non-exhaustive patterns: `_` not covered
 LL |     m!(0f32, f32::NEG_INFINITY..);
    |        ^^^^ pattern `_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `f32`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         _ => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:17:8
@@ -13,8 +17,12 @@ error[E0004]: non-exhaustive patterns: `_` not covered
 LL |     m!(0f32, ..f32::INFINITY);
    |        ^^^^ pattern `_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `f32`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         _ => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `'\u{10ffff}'` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:26:8
@@ -22,8 +30,12 @@ error[E0004]: non-exhaustive patterns: `'\u{10ffff}'` not covered
 LL |     m!('a', ..core::char::MAX);
    |        ^^^ pattern `'\u{10ffff}'` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `char`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         '\u{10ffff}' => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `'\u{10fffe}'..='\u{10ffff}'` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:27:8
@@ -31,8 +43,12 @@ error[E0004]: non-exhaustive patterns: `'\u{10fffe}'..='\u{10ffff}'` not covered
 LL |     m!('a', ..ALMOST_MAX);
    |        ^^^ pattern `'\u{10fffe}'..='\u{10ffff}'` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `char`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         '\u{10fffe}'..='\u{10ffff}' => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `'\u{0}'` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:28:8
@@ -40,8 +56,12 @@ error[E0004]: non-exhaustive patterns: `'\u{0}'` not covered
 LL |     m!('a', ALMOST_MIN..);
    |        ^^^ pattern `'\u{0}'` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `char`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         '\u{0}' => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `'\u{10ffff}'` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:29:8
@@ -49,8 +69,12 @@ error[E0004]: non-exhaustive patterns: `'\u{10ffff}'` not covered
 LL |     m!('a', ..=ALMOST_MAX);
    |        ^^^ pattern `'\u{10ffff}'` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `char`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         '\u{10ffff}' => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `'b'` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:30:8
@@ -58,8 +82,12 @@ error[E0004]: non-exhaustive patterns: `'b'` not covered
 LL |     m!('a', ..=VAL | VAL_2..);
    |        ^^^ pattern `'b'` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `char`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         'b' => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `'b'` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:31:8
@@ -67,8 +95,12 @@ error[E0004]: non-exhaustive patterns: `'b'` not covered
 LL |     m!('a', ..VAL_1 | VAL_2..);
    |        ^^^ pattern `'b'` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `char`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         'b' => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `u8::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:41:12
@@ -76,8 +108,12 @@ error[E0004]: non-exhaustive patterns: `u8::MAX` not covered
 LL |         m!(0, ..u8::MAX);
    |            ^ pattern `u8::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u8`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         u8::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `254_u8..=u8::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:42:12
@@ -85,8 +121,12 @@ error[E0004]: non-exhaustive patterns: `254_u8..=u8::MAX` not covered
 LL |         m!(0, ..ALMOST_MAX);
    |            ^ pattern `254_u8..=u8::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u8`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         254_u8..=u8::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `0_u8` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:43:12
@@ -94,8 +134,12 @@ error[E0004]: non-exhaustive patterns: `0_u8` not covered
 LL |         m!(0, ALMOST_MIN..);
    |            ^ pattern `0_u8` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u8`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         0_u8 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `u8::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:44:12
@@ -103,8 +147,12 @@ error[E0004]: non-exhaustive patterns: `u8::MAX` not covered
 LL |         m!(0, ..=ALMOST_MAX);
    |            ^ pattern `u8::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u8`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         u8::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `43_u8` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:45:12
@@ -112,8 +160,12 @@ error[E0004]: non-exhaustive patterns: `43_u8` not covered
 LL |         m!(0, ..=VAL | VAL_2..);
    |            ^ pattern `43_u8` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u8`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         43_u8 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `43_u8` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:46:12
@@ -121,8 +173,12 @@ error[E0004]: non-exhaustive patterns: `43_u8` not covered
 LL |         m!(0, ..VAL_1 | VAL_2..);
    |            ^ pattern `43_u8` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u8`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         43_u8 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `u16::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:54:12
@@ -130,8 +186,12 @@ error[E0004]: non-exhaustive patterns: `u16::MAX` not covered
 LL |         m!(0, ..u16::MAX);
    |            ^ pattern `u16::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u16`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         u16::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `65534_u16..=u16::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:55:12
@@ -139,8 +199,12 @@ error[E0004]: non-exhaustive patterns: `65534_u16..=u16::MAX` not covered
 LL |         m!(0, ..ALMOST_MAX);
    |            ^ pattern `65534_u16..=u16::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u16`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         65534_u16..=u16::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `0_u16` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:56:12
@@ -148,8 +212,12 @@ error[E0004]: non-exhaustive patterns: `0_u16` not covered
 LL |         m!(0, ALMOST_MIN..);
    |            ^ pattern `0_u16` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u16`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         0_u16 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `u16::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:57:12
@@ -157,8 +225,12 @@ error[E0004]: non-exhaustive patterns: `u16::MAX` not covered
 LL |         m!(0, ..=ALMOST_MAX);
    |            ^ pattern `u16::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u16`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         u16::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `43_u16` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:58:12
@@ -166,8 +238,12 @@ error[E0004]: non-exhaustive patterns: `43_u16` not covered
 LL |         m!(0, ..=VAL | VAL_2..);
    |            ^ pattern `43_u16` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u16`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         43_u16 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `43_u16` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:59:12
@@ -175,8 +251,12 @@ error[E0004]: non-exhaustive patterns: `43_u16` not covered
 LL |         m!(0, ..VAL_1 | VAL_2..);
    |            ^ pattern `43_u16` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u16`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         43_u16 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `u32::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:67:12
@@ -184,8 +264,12 @@ error[E0004]: non-exhaustive patterns: `u32::MAX` not covered
 LL |         m!(0, ..u32::MAX);
    |            ^ pattern `u32::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u32`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         u32::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `4294967294_u32..=u32::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:68:12
@@ -193,8 +277,12 @@ error[E0004]: non-exhaustive patterns: `4294967294_u32..=u32::MAX` not covered
 LL |         m!(0, ..ALMOST_MAX);
    |            ^ pattern `4294967294_u32..=u32::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u32`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         4294967294_u32..=u32::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `0_u32` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:69:12
@@ -202,8 +290,12 @@ error[E0004]: non-exhaustive patterns: `0_u32` not covered
 LL |         m!(0, ALMOST_MIN..);
    |            ^ pattern `0_u32` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u32`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         0_u32 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `u32::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:70:12
@@ -211,8 +303,12 @@ error[E0004]: non-exhaustive patterns: `u32::MAX` not covered
 LL |         m!(0, ..=ALMOST_MAX);
    |            ^ pattern `u32::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u32`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         u32::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `43_u32` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:71:12
@@ -220,8 +316,12 @@ error[E0004]: non-exhaustive patterns: `43_u32` not covered
 LL |         m!(0, ..=VAL | VAL_2..);
    |            ^ pattern `43_u32` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u32`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         43_u32 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `43_u32` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:72:12
@@ -229,8 +329,12 @@ error[E0004]: non-exhaustive patterns: `43_u32` not covered
 LL |         m!(0, ..VAL_1 | VAL_2..);
    |            ^ pattern `43_u32` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u32`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         43_u32 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `u64::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:80:12
@@ -238,8 +342,12 @@ error[E0004]: non-exhaustive patterns: `u64::MAX` not covered
 LL |         m!(0, ..u64::MAX);
    |            ^ pattern `u64::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u64`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         u64::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `18446744073709551614_u64..=u64::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:81:12
@@ -247,8 +355,12 @@ error[E0004]: non-exhaustive patterns: `18446744073709551614_u64..=u64::MAX` not
 LL |         m!(0, ..ALMOST_MAX);
    |            ^ pattern `18446744073709551614_u64..=u64::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u64`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         18446744073709551614_u64..=u64::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `0_u64` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:82:12
@@ -256,8 +368,12 @@ error[E0004]: non-exhaustive patterns: `0_u64` not covered
 LL |         m!(0, ALMOST_MIN..);
    |            ^ pattern `0_u64` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u64`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         0_u64 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `u64::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:83:12
@@ -265,8 +381,12 @@ error[E0004]: non-exhaustive patterns: `u64::MAX` not covered
 LL |         m!(0, ..=ALMOST_MAX);
    |            ^ pattern `u64::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u64`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         u64::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `43_u64` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:84:12
@@ -274,8 +394,12 @@ error[E0004]: non-exhaustive patterns: `43_u64` not covered
 LL |         m!(0, ..=VAL | VAL_2..);
    |            ^ pattern `43_u64` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u64`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         43_u64 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `43_u64` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:85:12
@@ -283,8 +407,12 @@ error[E0004]: non-exhaustive patterns: `43_u64` not covered
 LL |         m!(0, ..VAL_1 | VAL_2..);
    |            ^ pattern `43_u64` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u64`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         43_u64 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `u128::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:93:12
@@ -292,8 +420,12 @@ error[E0004]: non-exhaustive patterns: `u128::MAX` not covered
 LL |         m!(0, ..u128::MAX);
    |            ^ pattern `u128::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u128`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         u128::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `340282366920938463463374607431768211454_u128..=u128::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:94:12
@@ -301,8 +433,12 @@ error[E0004]: non-exhaustive patterns: `340282366920938463463374607431768211454_
 LL |         m!(0, ..ALMOST_MAX);
    |            ^ pattern `340282366920938463463374607431768211454_u128..=u128::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u128`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         340282366920938463463374607431768211454_u128..=u128::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `0_u128` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:95:12
@@ -310,8 +446,12 @@ error[E0004]: non-exhaustive patterns: `0_u128` not covered
 LL |         m!(0, ALMOST_MIN..);
    |            ^ pattern `0_u128` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u128`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         0_u128 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `u128::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:96:12
@@ -319,8 +459,12 @@ error[E0004]: non-exhaustive patterns: `u128::MAX` not covered
 LL |         m!(0, ..=ALMOST_MAX);
    |            ^ pattern `u128::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u128`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         u128::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `43_u128` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:97:12
@@ -328,8 +472,12 @@ error[E0004]: non-exhaustive patterns: `43_u128` not covered
 LL |         m!(0, ..=VAL | VAL_2..);
    |            ^ pattern `43_u128` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u128`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         43_u128 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `43_u128` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:98:12
@@ -337,8 +485,12 @@ error[E0004]: non-exhaustive patterns: `43_u128` not covered
 LL |         m!(0, ..VAL_1 | VAL_2..);
    |            ^ pattern `43_u128` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u128`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         43_u128 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `i8::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:109:12
@@ -346,8 +498,12 @@ error[E0004]: non-exhaustive patterns: `i8::MAX` not covered
 LL |         m!(0, ..i8::MAX);
    |            ^ pattern `i8::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i8`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         i8::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `126_i8..=i8::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:110:12
@@ -355,8 +511,12 @@ error[E0004]: non-exhaustive patterns: `126_i8..=i8::MAX` not covered
 LL |         m!(0, ..ALMOST_MAX);
    |            ^ pattern `126_i8..=i8::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i8`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         126_i8..=i8::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `i8::MIN` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:111:12
@@ -364,8 +524,12 @@ error[E0004]: non-exhaustive patterns: `i8::MIN` not covered
 LL |         m!(0, ALMOST_MIN..);
    |            ^ pattern `i8::MIN` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i8`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         i8::MIN => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `i8::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:112:12
@@ -373,8 +537,12 @@ error[E0004]: non-exhaustive patterns: `i8::MAX` not covered
 LL |         m!(0, ..=ALMOST_MAX);
    |            ^ pattern `i8::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i8`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         i8::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `43_i8` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:113:12
@@ -382,8 +550,12 @@ error[E0004]: non-exhaustive patterns: `43_i8` not covered
 LL |         m!(0, ..=VAL | VAL_2..);
    |            ^ pattern `43_i8` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i8`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         43_i8 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `43_i8` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:114:12
@@ -391,8 +563,12 @@ error[E0004]: non-exhaustive patterns: `43_i8` not covered
 LL |         m!(0, ..VAL_1 | VAL_2..);
    |            ^ pattern `43_i8` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i8`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         43_i8 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `i16::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:122:12
@@ -400,8 +576,12 @@ error[E0004]: non-exhaustive patterns: `i16::MAX` not covered
 LL |         m!(0, ..i16::MAX);
    |            ^ pattern `i16::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i16`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         i16::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `32766_i16..=i16::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:123:12
@@ -409,8 +589,12 @@ error[E0004]: non-exhaustive patterns: `32766_i16..=i16::MAX` not covered
 LL |         m!(0, ..ALMOST_MAX);
    |            ^ pattern `32766_i16..=i16::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i16`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         32766_i16..=i16::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `i16::MIN` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:124:12
@@ -418,8 +602,12 @@ error[E0004]: non-exhaustive patterns: `i16::MIN` not covered
 LL |         m!(0, ALMOST_MIN..);
    |            ^ pattern `i16::MIN` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i16`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         i16::MIN => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `i16::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:125:12
@@ -427,8 +615,12 @@ error[E0004]: non-exhaustive patterns: `i16::MAX` not covered
 LL |         m!(0, ..=ALMOST_MAX);
    |            ^ pattern `i16::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i16`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         i16::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `43_i16` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:126:12
@@ -436,8 +628,12 @@ error[E0004]: non-exhaustive patterns: `43_i16` not covered
 LL |         m!(0, ..=VAL | VAL_2..);
    |            ^ pattern `43_i16` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i16`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         43_i16 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `43_i16` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:127:12
@@ -445,8 +641,12 @@ error[E0004]: non-exhaustive patterns: `43_i16` not covered
 LL |         m!(0, ..VAL_1 | VAL_2..);
    |            ^ pattern `43_i16` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i16`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         43_i16 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `i32::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:135:12
@@ -454,8 +654,12 @@ error[E0004]: non-exhaustive patterns: `i32::MAX` not covered
 LL |         m!(0, ..i32::MAX);
    |            ^ pattern `i32::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i32`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         i32::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `2147483646_i32..=i32::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:136:12
@@ -463,8 +667,12 @@ error[E0004]: non-exhaustive patterns: `2147483646_i32..=i32::MAX` not covered
 LL |         m!(0, ..ALMOST_MAX);
    |            ^ pattern `2147483646_i32..=i32::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i32`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         2147483646_i32..=i32::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `i32::MIN` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:137:12
@@ -472,8 +680,12 @@ error[E0004]: non-exhaustive patterns: `i32::MIN` not covered
 LL |         m!(0, ALMOST_MIN..);
    |            ^ pattern `i32::MIN` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i32`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         i32::MIN => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `i32::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:138:12
@@ -481,8 +693,12 @@ error[E0004]: non-exhaustive patterns: `i32::MAX` not covered
 LL |         m!(0, ..=ALMOST_MAX);
    |            ^ pattern `i32::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i32`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         i32::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `43_i32` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:139:12
@@ -490,8 +706,12 @@ error[E0004]: non-exhaustive patterns: `43_i32` not covered
 LL |         m!(0, ..=VAL | VAL_2..);
    |            ^ pattern `43_i32` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i32`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         43_i32 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `43_i32` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:140:12
@@ -499,8 +719,12 @@ error[E0004]: non-exhaustive patterns: `43_i32` not covered
 LL |         m!(0, ..VAL_1 | VAL_2..);
    |            ^ pattern `43_i32` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i32`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         43_i32 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `i64::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:148:12
@@ -508,8 +732,12 @@ error[E0004]: non-exhaustive patterns: `i64::MAX` not covered
 LL |         m!(0, ..i64::MAX);
    |            ^ pattern `i64::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i64`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         i64::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `9223372036854775806_i64..=i64::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:149:12
@@ -517,8 +745,12 @@ error[E0004]: non-exhaustive patterns: `9223372036854775806_i64..=i64::MAX` not
 LL |         m!(0, ..ALMOST_MAX);
    |            ^ pattern `9223372036854775806_i64..=i64::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i64`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         9223372036854775806_i64..=i64::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `i64::MIN` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:150:12
@@ -526,8 +758,12 @@ error[E0004]: non-exhaustive patterns: `i64::MIN` not covered
 LL |         m!(0, ALMOST_MIN..);
    |            ^ pattern `i64::MIN` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i64`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         i64::MIN => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `i64::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:151:12
@@ -535,8 +771,12 @@ error[E0004]: non-exhaustive patterns: `i64::MAX` not covered
 LL |         m!(0, ..=ALMOST_MAX);
    |            ^ pattern `i64::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i64`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         i64::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `43_i64` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:152:12
@@ -544,8 +784,12 @@ error[E0004]: non-exhaustive patterns: `43_i64` not covered
 LL |         m!(0, ..=VAL | VAL_2..);
    |            ^ pattern `43_i64` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i64`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         43_i64 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `43_i64` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:153:12
@@ -553,8 +797,12 @@ error[E0004]: non-exhaustive patterns: `43_i64` not covered
 LL |         m!(0, ..VAL_1 | VAL_2..);
    |            ^ pattern `43_i64` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i64`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         43_i64 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `i128::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:161:12
@@ -562,8 +810,12 @@ error[E0004]: non-exhaustive patterns: `i128::MAX` not covered
 LL |         m!(0, ..i128::MAX);
    |            ^ pattern `i128::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i128`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         i128::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `170141183460469231731687303715884105726_i128..=i128::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:162:12
@@ -571,8 +823,12 @@ error[E0004]: non-exhaustive patterns: `170141183460469231731687303715884105726_
 LL |         m!(0, ..ALMOST_MAX);
    |            ^ pattern `170141183460469231731687303715884105726_i128..=i128::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i128`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         170141183460469231731687303715884105726_i128..=i128::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `i128::MIN` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:163:12
@@ -580,8 +836,12 @@ error[E0004]: non-exhaustive patterns: `i128::MIN` not covered
 LL |         m!(0, ALMOST_MIN..);
    |            ^ pattern `i128::MIN` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i128`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         i128::MIN => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `i128::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:164:12
@@ -589,8 +849,12 @@ error[E0004]: non-exhaustive patterns: `i128::MAX` not covered
 LL |         m!(0, ..=ALMOST_MAX);
    |            ^ pattern `i128::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i128`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         i128::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `43_i128` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:165:12
@@ -598,8 +862,12 @@ error[E0004]: non-exhaustive patterns: `43_i128` not covered
 LL |         m!(0, ..=VAL | VAL_2..);
    |            ^ pattern `43_i128` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i128`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         43_i128 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `43_i128` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:166:12
@@ -607,8 +875,12 @@ error[E0004]: non-exhaustive patterns: `43_i128` not covered
 LL |         m!(0, ..VAL_1 | VAL_2..);
    |            ^ pattern `43_i128` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i128`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         43_i128 => todo!() }
+   |
 
 error: aborting due to 68 previous errors
 
diff --git a/src/test/ui/impl-trait/issues/issue-79099.stderr b/src/test/ui/impl-trait/issues/issue-79099.stderr
index 4c9ec2a83ff37..362c67dafd2c5 100644
--- a/src/test/ui/impl-trait/issues/issue-79099.stderr
+++ b/src/test/ui/impl-trait/issues/issue-79099.stderr
@@ -6,7 +6,7 @@ LL |         let f: impl core::future::Future<Output = u8> = async { 1 };
    |                                                         |
    |                                                         `async` blocks are only allowed in Rust 2018 or later
    |
-   = help: set `edition = "2021"` in `Cargo.toml`
+   = help: pass `--edition 2021` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding
diff --git a/src/test/ui/lint/rfc-2383-lint-reason/lint-attribute-only-with-reason.rs b/src/test/ui/lint/rfc-2383-lint-reason/lint-attribute-only-with-reason.rs
new file mode 100644
index 0000000000000..bafdea96e08df
--- /dev/null
+++ b/src/test/ui/lint/rfc-2383-lint-reason/lint-attribute-only-with-reason.rs
@@ -0,0 +1,14 @@
+#![feature(lint_reasons)]
+
+#![deny(unused_attributes)]
+
+#[allow(reason = "I want to allow something")]//~ ERROR unused attribute
+#[expect(reason = "I don't know what I'm waiting for")]//~ ERROR unused attribute
+#[warn(reason = "This should be warn by default")]//~ ERROR unused attribute
+#[deny(reason = "All listed lints are denied")]//~ ERROR unused attribute
+#[forbid(reason = "Just some reason")]//~ ERROR unused attribute
+
+#[allow(clippy::box_collection, reason = "This is still valid")]
+#[warn(dead_code, reason = "This is also reasonable")]
+
+fn main() {}
diff --git a/src/test/ui/lint/rfc-2383-lint-reason/lint-attribute-only-with-reason.stderr b/src/test/ui/lint/rfc-2383-lint-reason/lint-attribute-only-with-reason.stderr
new file mode 100644
index 0000000000000..3bf8137dc6e40
--- /dev/null
+++ b/src/test/ui/lint/rfc-2383-lint-reason/lint-attribute-only-with-reason.stderr
@@ -0,0 +1,47 @@
+error: unused attribute
+  --> $DIR/lint-attribute-only-with-reason.rs:5:1
+   |
+LL | #[allow(reason = "I want to allow something")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attribute-only-with-reason.rs:3:9
+   |
+LL | #![deny(unused_attributes)]
+   |         ^^^^^^^^^^^^^^^^^
+   = note: attribute `allow` without any lints has no effect
+
+error: unused attribute
+  --> $DIR/lint-attribute-only-with-reason.rs:6:1
+   |
+LL | #[expect(reason = "I don't know what I'm waiting for")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+   |
+   = note: attribute `expect` without any lints has no effect
+
+error: unused attribute
+  --> $DIR/lint-attribute-only-with-reason.rs:7:1
+   |
+LL | #[warn(reason = "This should be warn by default")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+   |
+   = note: attribute `warn` without any lints has no effect
+
+error: unused attribute
+  --> $DIR/lint-attribute-only-with-reason.rs:8:1
+   |
+LL | #[deny(reason = "All listed lints are denied")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+   |
+   = note: attribute `deny` without any lints has no effect
+
+error: unused attribute
+  --> $DIR/lint-attribute-only-with-reason.rs:9:1
+   |
+LL | #[forbid(reason = "Just some reason")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+   |
+   = note: attribute `forbid` without any lints has no effect
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/match/match_non_exhaustive.stderr b/src/test/ui/match/match_non_exhaustive.stderr
index 5debfe1c566c4..6206dc85ea05f 100644
--- a/src/test/ui/match/match_non_exhaustive.stderr
+++ b/src/test/ui/match/match_non_exhaustive.stderr
@@ -1,17 +1,19 @@
 error[E0004]: non-exhaustive patterns: `B` not covered
   --> $DIR/match_non_exhaustive.rs:23:11
    |
-LL | enum L { A, B }
-   | ---------------
-   | |           |
-   | |           not covered
-   | `L` defined here
-...
 LL |     match l { L::A => () };
    |           ^ pattern `B` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `L` defined here
+  --> $DIR/match_non_exhaustive.rs:10:13
+   |
+LL | enum L { A, B }
+   |      -      ^ not covered
    = note: the matched value is of type `L`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL |     match l { L::A => (), B => todo!() };
+   |                         ++++++++++++++
 
 error[E0004]: non-exhaustive patterns: type `E1` is non-empty
   --> $DIR/match_non_exhaustive.rs:28:11
@@ -19,8 +21,18 @@ error[E0004]: non-exhaustive patterns: type `E1` is non-empty
 LL |     match e1 {};
    |           ^^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `E1` defined here
+  --> $DIR/auxiliary/match_non_exhaustive_lib.rs:2:1
+   |
+LL | pub enum E1 {}
+   | ^^^^^^^^^^^^^^
    = note: the matched value is of type `E1`, which is marked as non-exhaustive
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match e1 {
+LL +         _ => todo!(),
+LL ~     };
+   |
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/match_non_exhaustive.rs:30:11
@@ -28,8 +40,16 @@ error[E0004]: non-exhaustive patterns: `_` not covered
 LL |     match e2 { E2::A => (), E2::B => () };
    |           ^^ pattern `_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `E2` defined here
+  --> $DIR/auxiliary/match_non_exhaustive_lib.rs:5:1
+   |
+LL | pub enum E2 { A, B }
+   | ^^^^^^^^^^^^^^^^^^^^
    = note: the matched value is of type `E2`, which is marked as non-exhaustive
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL |     match e2 { E2::A => (), E2::B => (), _ => todo!() };
+   |                                        ++++++++++++++
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.stderr b/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.stderr
index 44f334eee9386..9aa808e6bc9a6 100644
--- a/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.stderr
+++ b/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.stderr
@@ -4,8 +4,12 @@ error[E0004]: non-exhaustive patterns: `(2_u8..=u8::MAX, _)` not covered
 LL |     match (0u8, 0u8) {
    |           ^^^^^^^^^^ pattern `(2_u8..=u8::MAX, _)` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `(u8, u8)`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         (0 | 1, 2 | 3) => {}
+LL +         (2_u8..=u8::MAX, _) => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `((4_u8..=u8::MAX))` not covered
   --> $DIR/exhaustiveness-non-exhaustive.rs:9:11
@@ -13,8 +17,12 @@ error[E0004]: non-exhaustive patterns: `((4_u8..=u8::MAX))` not covered
 LL |     match ((0u8,),) {
    |           ^^^^^^^^^ pattern `((4_u8..=u8::MAX))` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `((u8,),)`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         ((0 | 1,) | (2 | 3,),) => {}
+LL +         ((4_u8..=u8::MAX)) => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `(Some(2_u8..=u8::MAX))` not covered
   --> $DIR/exhaustiveness-non-exhaustive.rs:13:11
@@ -22,8 +30,12 @@ error[E0004]: non-exhaustive patterns: `(Some(2_u8..=u8::MAX))` not covered
 LL |     match (Some(0u8),) {
    |           ^^^^^^^^^^^^ pattern `(Some(2_u8..=u8::MAX))` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `(Option<u8>,)`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         (None | Some(0 | 1),) => {}
+LL +         (Some(2_u8..=u8::MAX)) => todo!()
+   |
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr b/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr
index 8e6964e30623d..37a35700b36d5 100644
--- a/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr
+++ b/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr
@@ -18,8 +18,12 @@ error[E0004]: non-exhaustive patterns: `i32::MIN..=-1_i32` and `3_i32..=i32::MAX
 LL |     match 0 {
    |           ^ patterns `i32::MIN..=-1_i32` and `3_i32..=i32::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i32`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~         0 | (1 | 2) => {}
+LL +         i32::MIN..=-1_i32 | 3_i32..=i32::MAX => todo!()
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/pattern/usefulness/always-inhabited-union-ref.stderr b/src/test/ui/pattern/usefulness/always-inhabited-union-ref.stderr
index 2ca774a48b66b..cd5c283f9fd93 100644
--- a/src/test/ui/pattern/usefulness/always-inhabited-union-ref.stderr
+++ b/src/test/ui/pattern/usefulness/always-inhabited-union-ref.stderr
@@ -4,23 +4,33 @@ error[E0004]: non-exhaustive patterns: type `&!` is non-empty
 LL |     match uninhab_ref() {
    |           ^^^^^^^^^^^^^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&!`
    = note: references are always considered inhabited
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match uninhab_ref() {
+LL +         _ => todo!(),
+LL +     }
+   |
 
 error[E0004]: non-exhaustive patterns: type `Foo` is non-empty
   --> $DIR/always-inhabited-union-ref.rs:27:11
    |
-LL | / pub union Foo {
-LL | |     foo: !,
-LL | | }
-   | |_- `Foo` defined here
-...
-LL |       match uninhab_union() {
-   |             ^^^^^^^^^^^^^^^
+LL |     match uninhab_union() {
+   |           ^^^^^^^^^^^^^^^
+   |
+note: `Foo` defined here
+  --> $DIR/always-inhabited-union-ref.rs:10:11
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | pub union Foo {
+   |           ^^^
    = note: the matched value is of type `Foo`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match uninhab_union() {
+LL +         _ => todo!(),
+LL +     }
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.stderr b/src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.stderr
index 6c9539822b3dd..7d0b71a497ec2 100644
--- a/src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.stderr
+++ b/src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.stderr
@@ -4,8 +4,22 @@ error[E0004]: non-exhaustive patterns: `_` not covered
 LL |     match Foo::A {
    |           ^^^^^^ pattern `_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `Foo` defined here
+  --> $DIR/auxiliary/hidden.rs:1:1
+   |
+LL | / pub enum Foo {
+LL | |     A,
+LL | |     B,
+LL | |     #[doc(hidden)]
+LL | |     C,
+LL | | }
+   | |_^
    = note: the matched value is of type `Foo`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         Foo::B => {}
+LL +         _ => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `B` not covered
   --> $DIR/doc-hidden-non-exhaustive.rs:14:11
@@ -13,13 +27,23 @@ error[E0004]: non-exhaustive patterns: `B` not covered
 LL |     match Foo::A {
    |           ^^^^^^ pattern `B` not covered
    |
-  ::: $DIR/auxiliary/hidden.rs:3:5
+note: `Foo` defined here
+  --> $DIR/auxiliary/hidden.rs:3:5
    |
-LL |     B,
-   |     - not covered
-   |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | / pub enum Foo {
+LL | |     A,
+LL | |     B,
+   | |     ^ not covered
+LL | |     #[doc(hidden)]
+LL | |     C,
+LL | | }
+   | |_-
    = note: the matched value is of type `Foo`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         Foo::C => {}
+LL +         B => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `B` and `_` not covered
   --> $DIR/doc-hidden-non-exhaustive.rs:20:11
@@ -27,13 +51,23 @@ error[E0004]: non-exhaustive patterns: `B` and `_` not covered
 LL |     match Foo::A {
    |           ^^^^^^ patterns `B` and `_` not covered
    |
-  ::: $DIR/auxiliary/hidden.rs:3:5
+note: `Foo` defined here
+  --> $DIR/auxiliary/hidden.rs:3:5
    |
-LL |     B,
-   |     - not covered
-   |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | / pub enum Foo {
+LL | |     A,
+LL | |     B,
+   | |     ^ not covered
+LL | |     #[doc(hidden)]
+LL | |     C,
+LL | | }
+   | |_-
    = note: the matched value is of type `Foo`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~         Foo::A => {}
+LL +         B | _ => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `Some(B)` and `Some(_)` not covered
   --> $DIR/doc-hidden-non-exhaustive.rs:25:11
@@ -41,13 +75,24 @@ error[E0004]: non-exhaustive patterns: `Some(B)` and `Some(_)` not covered
 LL |     match None {
    |           ^^^^ patterns `Some(B)` and `Some(_)` not covered
    |
-  ::: $SRC_DIR/core/src/option.rs:LL:COL
+note: `Option<Foo>` defined here
+  --> $SRC_DIR/core/src/option.rs:LL:COL
    |
-LL |     Some(#[stable(feature = "rust1", since = "1.0.0")] T),
-   |     ---- not covered
-   |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | / pub enum Option<T> {
+LL | |     /// No value.
+LL | |     #[lang = "None"]
+LL | |     #[stable(feature = "rust1", since = "1.0.0")]
+...  |
+LL | |     Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+   | |     ^^^^ not covered
+LL | | }
+   | |_-
    = note: the matched value is of type `Option<Foo>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~         Some(Foo::A) => {}
+LL +         Some(B) | Some(_) => todo!()
+   |
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr b/src/test/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr
index b99386e74020e..d31ee0dbd14e5 100644
--- a/src/test/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr
+++ b/src/test/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr
@@ -46,107 +46,112 @@ error[E0004]: non-exhaustive patterns: type `u8` is non-empty
 LL |     match_no_arms!(0u8);
    |                    ^^^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u8`
+   = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
 
 error[E0004]: non-exhaustive patterns: type `NonEmptyStruct1` is non-empty
   --> $DIR/empty-match.rs:79:20
    |
-LL | struct NonEmptyStruct1;
-   | ----------------------- `NonEmptyStruct1` defined here
-...
 LL |     match_no_arms!(NonEmptyStruct1);
    |                    ^^^^^^^^^^^^^^^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `NonEmptyStruct1` defined here
+  --> $DIR/empty-match.rs:14:8
+   |
+LL | struct NonEmptyStruct1;
+   |        ^^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyStruct1`
+   = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
 
 error[E0004]: non-exhaustive patterns: type `NonEmptyStruct2` is non-empty
   --> $DIR/empty-match.rs:80:20
    |
-LL | struct NonEmptyStruct2(bool);
-   | ----------------------------- `NonEmptyStruct2` defined here
-...
 LL |     match_no_arms!(NonEmptyStruct2(true));
    |                    ^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `NonEmptyStruct2` defined here
+  --> $DIR/empty-match.rs:15:8
+   |
+LL | struct NonEmptyStruct2(bool);
+   |        ^^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyStruct2`
+   = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
 
 error[E0004]: non-exhaustive patterns: type `NonEmptyUnion1` is non-empty
   --> $DIR/empty-match.rs:81:20
    |
-LL | / union NonEmptyUnion1 {
-LL | |     foo: (),
-LL | | }
-   | |_- `NonEmptyUnion1` defined here
-...
-LL |       match_no_arms!((NonEmptyUnion1 { foo: () }));
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     match_no_arms!((NonEmptyUnion1 { foo: () }));
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: `NonEmptyUnion1` defined here
+  --> $DIR/empty-match.rs:16:7
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | union NonEmptyUnion1 {
+   |       ^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyUnion1`
+   = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
 
 error[E0004]: non-exhaustive patterns: type `NonEmptyUnion2` is non-empty
   --> $DIR/empty-match.rs:82:20
    |
-LL | / union NonEmptyUnion2 {
-LL | |     foo: (),
-LL | |     bar: (),
-LL | | }
-   | |_- `NonEmptyUnion2` defined here
-...
-LL |       match_no_arms!((NonEmptyUnion2 { foo: () }));
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     match_no_arms!((NonEmptyUnion2 { foo: () }));
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: `NonEmptyUnion2` defined here
+  --> $DIR/empty-match.rs:19:7
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | union NonEmptyUnion2 {
+   |       ^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyUnion2`
+   = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
 
 error[E0004]: non-exhaustive patterns: `Foo(_)` not covered
   --> $DIR/empty-match.rs:83:20
    |
-LL | / enum NonEmptyEnum1 {
-LL | |     Foo(bool),
-   | |     --- not covered
-LL | | }
-   | |_- `NonEmptyEnum1` defined here
-...
-LL |       match_no_arms!(NonEmptyEnum1::Foo(true));
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo(_)` not covered
+LL |     match_no_arms!(NonEmptyEnum1::Foo(true));
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo(_)` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `NonEmptyEnum1` defined here
+  --> $DIR/empty-match.rs:24:5
+   |
+LL | enum NonEmptyEnum1 {
+   |      -------------
+LL |     Foo(bool),
+   |     ^^^ not covered
    = note: the matched value is of type `NonEmptyEnum1`
+   = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern
 
 error[E0004]: non-exhaustive patterns: `Foo(_)` and `Bar` not covered
   --> $DIR/empty-match.rs:84:20
    |
-LL | / enum NonEmptyEnum2 {
-LL | |     Foo(bool),
-   | |     --- not covered
-LL | |     Bar,
-   | |     --- not covered
-LL | | }
-   | |_- `NonEmptyEnum2` defined here
-...
-LL |       match_no_arms!(NonEmptyEnum2::Foo(true));
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `Foo(_)` and `Bar` not covered
-   |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL |     match_no_arms!(NonEmptyEnum2::Foo(true));
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `Foo(_)` and `Bar` not covered
+   |
+note: `NonEmptyEnum2` defined here
+  --> $DIR/empty-match.rs:27:5
+   |
+LL | enum NonEmptyEnum2 {
+   |      -------------
+LL |     Foo(bool),
+   |     ^^^ not covered
+LL |     Bar,
+   |     ^^^ not covered
    = note: the matched value is of type `NonEmptyEnum2`
+   = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or multiple match arms
 
 error[E0004]: non-exhaustive patterns: `V1`, `V2`, `V3` and 2 more not covered
   --> $DIR/empty-match.rs:85:20
    |
-LL | / enum NonEmptyEnum5 {
-LL | |     V1, V2, V3, V4, V5,
-LL | | }
-   | |_- `NonEmptyEnum5` defined here
-...
-LL |       match_no_arms!(NonEmptyEnum5::V1);
-   |                      ^^^^^^^^^^^^^^^^^ patterns `V1`, `V2`, `V3` and 2 more not covered
+LL |     match_no_arms!(NonEmptyEnum5::V1);
+   |                    ^^^^^^^^^^^^^^^^^ patterns `V1`, `V2`, `V3` and 2 more not covered
+   |
+note: `NonEmptyEnum5` defined here
+  --> $DIR/empty-match.rs:30:6
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | enum NonEmptyEnum5 {
+   |      ^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyEnum5`
+   = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or multiple match arms
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/empty-match.rs:87:24
@@ -154,107 +159,144 @@ error[E0004]: non-exhaustive patterns: `_` not covered
 LL |     match_guarded_arm!(0u8);
    |                        ^^^ pattern `_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u8`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~             _ if false => {}
+LL +             _ => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyStruct1` not covered
   --> $DIR/empty-match.rs:88:24
    |
-LL | struct NonEmptyStruct1;
-   | ----------------------- `NonEmptyStruct1` defined here
-...
 LL |     match_guarded_arm!(NonEmptyStruct1);
    |                        ^^^^^^^^^^^^^^^ pattern `NonEmptyStruct1` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `NonEmptyStruct1` defined here
+  --> $DIR/empty-match.rs:14:8
+   |
+LL | struct NonEmptyStruct1;
+   |        ^^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyStruct1`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~             _ if false => {}
+LL +             NonEmptyStruct1 => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyStruct2(_)` not covered
   --> $DIR/empty-match.rs:89:24
    |
-LL | struct NonEmptyStruct2(bool);
-   | ----------------------------- `NonEmptyStruct2` defined here
-...
 LL |     match_guarded_arm!(NonEmptyStruct2(true));
    |                        ^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyStruct2(_)` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `NonEmptyStruct2` defined here
+  --> $DIR/empty-match.rs:15:8
+   |
+LL | struct NonEmptyStruct2(bool);
+   |        ^^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyStruct2`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~             _ if false => {}
+LL +             NonEmptyStruct2(_) => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyUnion1 { .. }` not covered
   --> $DIR/empty-match.rs:90:24
    |
-LL | / union NonEmptyUnion1 {
-LL | |     foo: (),
-LL | | }
-   | |_- `NonEmptyUnion1` defined here
-...
-LL |       match_guarded_arm!((NonEmptyUnion1 { foo: () }));
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion1 { .. }` not covered
+LL |     match_guarded_arm!((NonEmptyUnion1 { foo: () }));
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion1 { .. }` not covered
+   |
+note: `NonEmptyUnion1` defined here
+  --> $DIR/empty-match.rs:16:7
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | union NonEmptyUnion1 {
+   |       ^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyUnion1`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~             _ if false => {}
+LL +             NonEmptyUnion1 { .. } => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyUnion2 { .. }` not covered
   --> $DIR/empty-match.rs:91:24
    |
-LL | / union NonEmptyUnion2 {
-LL | |     foo: (),
-LL | |     bar: (),
-LL | | }
-   | |_- `NonEmptyUnion2` defined here
-...
-LL |       match_guarded_arm!((NonEmptyUnion2 { foo: () }));
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion2 { .. }` not covered
+LL |     match_guarded_arm!((NonEmptyUnion2 { foo: () }));
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion2 { .. }` not covered
+   |
+note: `NonEmptyUnion2` defined here
+  --> $DIR/empty-match.rs:19:7
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | union NonEmptyUnion2 {
+   |       ^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyUnion2`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~             _ if false => {}
+LL +             NonEmptyUnion2 { .. } => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `Foo(_)` not covered
   --> $DIR/empty-match.rs:92:24
    |
-LL | / enum NonEmptyEnum1 {
-LL | |     Foo(bool),
-   | |     --- not covered
-LL | | }
-   | |_- `NonEmptyEnum1` defined here
-...
-LL |       match_guarded_arm!(NonEmptyEnum1::Foo(true));
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo(_)` not covered
+LL |     match_guarded_arm!(NonEmptyEnum1::Foo(true));
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo(_)` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `NonEmptyEnum1` defined here
+  --> $DIR/empty-match.rs:24:5
+   |
+LL | enum NonEmptyEnum1 {
+   |      -------------
+LL |     Foo(bool),
+   |     ^^^ not covered
    = note: the matched value is of type `NonEmptyEnum1`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~             _ if false => {}
+LL +             Foo(_) => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `Foo(_)` and `Bar` not covered
   --> $DIR/empty-match.rs:93:24
    |
-LL | / enum NonEmptyEnum2 {
-LL | |     Foo(bool),
-   | |     --- not covered
-LL | |     Bar,
-   | |     --- not covered
-LL | | }
-   | |_- `NonEmptyEnum2` defined here
-...
-LL |       match_guarded_arm!(NonEmptyEnum2::Foo(true));
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `Foo(_)` and `Bar` not covered
-   |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL |     match_guarded_arm!(NonEmptyEnum2::Foo(true));
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `Foo(_)` and `Bar` not covered
+   |
+note: `NonEmptyEnum2` defined here
+  --> $DIR/empty-match.rs:27:5
+   |
+LL | enum NonEmptyEnum2 {
+   |      -------------
+LL |     Foo(bool),
+   |     ^^^ not covered
+LL |     Bar,
+   |     ^^^ not covered
    = note: the matched value is of type `NonEmptyEnum2`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~             _ if false => {}
+LL +             Foo(_) | Bar => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `V1`, `V2`, `V3` and 2 more not covered
   --> $DIR/empty-match.rs:94:24
    |
-LL | / enum NonEmptyEnum5 {
-LL | |     V1, V2, V3, V4, V5,
-LL | | }
-   | |_- `NonEmptyEnum5` defined here
-...
-LL |       match_guarded_arm!(NonEmptyEnum5::V1);
-   |                          ^^^^^^^^^^^^^^^^^ patterns `V1`, `V2`, `V3` and 2 more not covered
+LL |     match_guarded_arm!(NonEmptyEnum5::V1);
+   |                        ^^^^^^^^^^^^^^^^^ patterns `V1`, `V2`, `V3` and 2 more not covered
+   |
+note: `NonEmptyEnum5` defined here
+  --> $DIR/empty-match.rs:30:6
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | enum NonEmptyEnum5 {
+   |      ^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyEnum5`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
+   |
+LL ~             _ if false => {}
+LL +             _ => todo!()
+   |
 
 error: aborting due to 22 previous errors
 
diff --git a/src/test/ui/pattern/usefulness/empty-match.normal.stderr b/src/test/ui/pattern/usefulness/empty-match.normal.stderr
index b99386e74020e..d31ee0dbd14e5 100644
--- a/src/test/ui/pattern/usefulness/empty-match.normal.stderr
+++ b/src/test/ui/pattern/usefulness/empty-match.normal.stderr
@@ -46,107 +46,112 @@ error[E0004]: non-exhaustive patterns: type `u8` is non-empty
 LL |     match_no_arms!(0u8);
    |                    ^^^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u8`
+   = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
 
 error[E0004]: non-exhaustive patterns: type `NonEmptyStruct1` is non-empty
   --> $DIR/empty-match.rs:79:20
    |
-LL | struct NonEmptyStruct1;
-   | ----------------------- `NonEmptyStruct1` defined here
-...
 LL |     match_no_arms!(NonEmptyStruct1);
    |                    ^^^^^^^^^^^^^^^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `NonEmptyStruct1` defined here
+  --> $DIR/empty-match.rs:14:8
+   |
+LL | struct NonEmptyStruct1;
+   |        ^^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyStruct1`
+   = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
 
 error[E0004]: non-exhaustive patterns: type `NonEmptyStruct2` is non-empty
   --> $DIR/empty-match.rs:80:20
    |
-LL | struct NonEmptyStruct2(bool);
-   | ----------------------------- `NonEmptyStruct2` defined here
-...
 LL |     match_no_arms!(NonEmptyStruct2(true));
    |                    ^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `NonEmptyStruct2` defined here
+  --> $DIR/empty-match.rs:15:8
+   |
+LL | struct NonEmptyStruct2(bool);
+   |        ^^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyStruct2`
+   = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
 
 error[E0004]: non-exhaustive patterns: type `NonEmptyUnion1` is non-empty
   --> $DIR/empty-match.rs:81:20
    |
-LL | / union NonEmptyUnion1 {
-LL | |     foo: (),
-LL | | }
-   | |_- `NonEmptyUnion1` defined here
-...
-LL |       match_no_arms!((NonEmptyUnion1 { foo: () }));
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     match_no_arms!((NonEmptyUnion1 { foo: () }));
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: `NonEmptyUnion1` defined here
+  --> $DIR/empty-match.rs:16:7
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | union NonEmptyUnion1 {
+   |       ^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyUnion1`
+   = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
 
 error[E0004]: non-exhaustive patterns: type `NonEmptyUnion2` is non-empty
   --> $DIR/empty-match.rs:82:20
    |
-LL | / union NonEmptyUnion2 {
-LL | |     foo: (),
-LL | |     bar: (),
-LL | | }
-   | |_- `NonEmptyUnion2` defined here
-...
-LL |       match_no_arms!((NonEmptyUnion2 { foo: () }));
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     match_no_arms!((NonEmptyUnion2 { foo: () }));
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: `NonEmptyUnion2` defined here
+  --> $DIR/empty-match.rs:19:7
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | union NonEmptyUnion2 {
+   |       ^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyUnion2`
+   = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
 
 error[E0004]: non-exhaustive patterns: `Foo(_)` not covered
   --> $DIR/empty-match.rs:83:20
    |
-LL | / enum NonEmptyEnum1 {
-LL | |     Foo(bool),
-   | |     --- not covered
-LL | | }
-   | |_- `NonEmptyEnum1` defined here
-...
-LL |       match_no_arms!(NonEmptyEnum1::Foo(true));
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo(_)` not covered
+LL |     match_no_arms!(NonEmptyEnum1::Foo(true));
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo(_)` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `NonEmptyEnum1` defined here
+  --> $DIR/empty-match.rs:24:5
+   |
+LL | enum NonEmptyEnum1 {
+   |      -------------
+LL |     Foo(bool),
+   |     ^^^ not covered
    = note: the matched value is of type `NonEmptyEnum1`
+   = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern
 
 error[E0004]: non-exhaustive patterns: `Foo(_)` and `Bar` not covered
   --> $DIR/empty-match.rs:84:20
    |
-LL | / enum NonEmptyEnum2 {
-LL | |     Foo(bool),
-   | |     --- not covered
-LL | |     Bar,
-   | |     --- not covered
-LL | | }
-   | |_- `NonEmptyEnum2` defined here
-...
-LL |       match_no_arms!(NonEmptyEnum2::Foo(true));
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `Foo(_)` and `Bar` not covered
-   |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL |     match_no_arms!(NonEmptyEnum2::Foo(true));
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `Foo(_)` and `Bar` not covered
+   |
+note: `NonEmptyEnum2` defined here
+  --> $DIR/empty-match.rs:27:5
+   |
+LL | enum NonEmptyEnum2 {
+   |      -------------
+LL |     Foo(bool),
+   |     ^^^ not covered
+LL |     Bar,
+   |     ^^^ not covered
    = note: the matched value is of type `NonEmptyEnum2`
+   = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or multiple match arms
 
 error[E0004]: non-exhaustive patterns: `V1`, `V2`, `V3` and 2 more not covered
   --> $DIR/empty-match.rs:85:20
    |
-LL | / enum NonEmptyEnum5 {
-LL | |     V1, V2, V3, V4, V5,
-LL | | }
-   | |_- `NonEmptyEnum5` defined here
-...
-LL |       match_no_arms!(NonEmptyEnum5::V1);
-   |                      ^^^^^^^^^^^^^^^^^ patterns `V1`, `V2`, `V3` and 2 more not covered
+LL |     match_no_arms!(NonEmptyEnum5::V1);
+   |                    ^^^^^^^^^^^^^^^^^ patterns `V1`, `V2`, `V3` and 2 more not covered
+   |
+note: `NonEmptyEnum5` defined here
+  --> $DIR/empty-match.rs:30:6
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | enum NonEmptyEnum5 {
+   |      ^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyEnum5`
+   = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or multiple match arms
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/empty-match.rs:87:24
@@ -154,107 +159,144 @@ error[E0004]: non-exhaustive patterns: `_` not covered
 LL |     match_guarded_arm!(0u8);
    |                        ^^^ pattern `_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u8`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~             _ if false => {}
+LL +             _ => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyStruct1` not covered
   --> $DIR/empty-match.rs:88:24
    |
-LL | struct NonEmptyStruct1;
-   | ----------------------- `NonEmptyStruct1` defined here
-...
 LL |     match_guarded_arm!(NonEmptyStruct1);
    |                        ^^^^^^^^^^^^^^^ pattern `NonEmptyStruct1` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `NonEmptyStruct1` defined here
+  --> $DIR/empty-match.rs:14:8
+   |
+LL | struct NonEmptyStruct1;
+   |        ^^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyStruct1`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~             _ if false => {}
+LL +             NonEmptyStruct1 => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyStruct2(_)` not covered
   --> $DIR/empty-match.rs:89:24
    |
-LL | struct NonEmptyStruct2(bool);
-   | ----------------------------- `NonEmptyStruct2` defined here
-...
 LL |     match_guarded_arm!(NonEmptyStruct2(true));
    |                        ^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyStruct2(_)` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `NonEmptyStruct2` defined here
+  --> $DIR/empty-match.rs:15:8
+   |
+LL | struct NonEmptyStruct2(bool);
+   |        ^^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyStruct2`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~             _ if false => {}
+LL +             NonEmptyStruct2(_) => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyUnion1 { .. }` not covered
   --> $DIR/empty-match.rs:90:24
    |
-LL | / union NonEmptyUnion1 {
-LL | |     foo: (),
-LL | | }
-   | |_- `NonEmptyUnion1` defined here
-...
-LL |       match_guarded_arm!((NonEmptyUnion1 { foo: () }));
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion1 { .. }` not covered
+LL |     match_guarded_arm!((NonEmptyUnion1 { foo: () }));
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion1 { .. }` not covered
+   |
+note: `NonEmptyUnion1` defined here
+  --> $DIR/empty-match.rs:16:7
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | union NonEmptyUnion1 {
+   |       ^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyUnion1`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~             _ if false => {}
+LL +             NonEmptyUnion1 { .. } => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyUnion2 { .. }` not covered
   --> $DIR/empty-match.rs:91:24
    |
-LL | / union NonEmptyUnion2 {
-LL | |     foo: (),
-LL | |     bar: (),
-LL | | }
-   | |_- `NonEmptyUnion2` defined here
-...
-LL |       match_guarded_arm!((NonEmptyUnion2 { foo: () }));
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion2 { .. }` not covered
+LL |     match_guarded_arm!((NonEmptyUnion2 { foo: () }));
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion2 { .. }` not covered
+   |
+note: `NonEmptyUnion2` defined here
+  --> $DIR/empty-match.rs:19:7
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | union NonEmptyUnion2 {
+   |       ^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyUnion2`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~             _ if false => {}
+LL +             NonEmptyUnion2 { .. } => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `Foo(_)` not covered
   --> $DIR/empty-match.rs:92:24
    |
-LL | / enum NonEmptyEnum1 {
-LL | |     Foo(bool),
-   | |     --- not covered
-LL | | }
-   | |_- `NonEmptyEnum1` defined here
-...
-LL |       match_guarded_arm!(NonEmptyEnum1::Foo(true));
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo(_)` not covered
+LL |     match_guarded_arm!(NonEmptyEnum1::Foo(true));
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo(_)` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `NonEmptyEnum1` defined here
+  --> $DIR/empty-match.rs:24:5
+   |
+LL | enum NonEmptyEnum1 {
+   |      -------------
+LL |     Foo(bool),
+   |     ^^^ not covered
    = note: the matched value is of type `NonEmptyEnum1`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~             _ if false => {}
+LL +             Foo(_) => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `Foo(_)` and `Bar` not covered
   --> $DIR/empty-match.rs:93:24
    |
-LL | / enum NonEmptyEnum2 {
-LL | |     Foo(bool),
-   | |     --- not covered
-LL | |     Bar,
-   | |     --- not covered
-LL | | }
-   | |_- `NonEmptyEnum2` defined here
-...
-LL |       match_guarded_arm!(NonEmptyEnum2::Foo(true));
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `Foo(_)` and `Bar` not covered
-   |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL |     match_guarded_arm!(NonEmptyEnum2::Foo(true));
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `Foo(_)` and `Bar` not covered
+   |
+note: `NonEmptyEnum2` defined here
+  --> $DIR/empty-match.rs:27:5
+   |
+LL | enum NonEmptyEnum2 {
+   |      -------------
+LL |     Foo(bool),
+   |     ^^^ not covered
+LL |     Bar,
+   |     ^^^ not covered
    = note: the matched value is of type `NonEmptyEnum2`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~             _ if false => {}
+LL +             Foo(_) | Bar => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `V1`, `V2`, `V3` and 2 more not covered
   --> $DIR/empty-match.rs:94:24
    |
-LL | / enum NonEmptyEnum5 {
-LL | |     V1, V2, V3, V4, V5,
-LL | | }
-   | |_- `NonEmptyEnum5` defined here
-...
-LL |       match_guarded_arm!(NonEmptyEnum5::V1);
-   |                          ^^^^^^^^^^^^^^^^^ patterns `V1`, `V2`, `V3` and 2 more not covered
+LL |     match_guarded_arm!(NonEmptyEnum5::V1);
+   |                        ^^^^^^^^^^^^^^^^^ patterns `V1`, `V2`, `V3` and 2 more not covered
+   |
+note: `NonEmptyEnum5` defined here
+  --> $DIR/empty-match.rs:30:6
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | enum NonEmptyEnum5 {
+   |      ^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyEnum5`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
+   |
+LL ~             _ if false => {}
+LL +             _ => todo!()
+   |
 
 error: aborting due to 22 previous errors
 
diff --git a/src/test/ui/pattern/usefulness/floats.stderr b/src/test/ui/pattern/usefulness/floats.stderr
index 464bfbdb2c3b2..c926e50b3580b 100644
--- a/src/test/ui/pattern/usefulness/floats.stderr
+++ b/src/test/ui/pattern/usefulness/floats.stderr
@@ -4,8 +4,12 @@ error[E0004]: non-exhaustive patterns: `_` not covered
 LL |     match 0.0 {
    |           ^^^ pattern `_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `f64`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~       0.0..=1.0 => {}
+LL +       _ => todo!()
+   |
 
 error: unreachable pattern
   --> $DIR/floats.rs:16:7
diff --git a/src/test/ui/pattern/usefulness/guards.stderr b/src/test/ui/pattern/usefulness/guards.stderr
index 61f7facb330da..0c1563c160c1c 100644
--- a/src/test/ui/pattern/usefulness/guards.stderr
+++ b/src/test/ui/pattern/usefulness/guards.stderr
@@ -4,8 +4,12 @@ error[E0004]: non-exhaustive patterns: `128_u8..=u8::MAX` not covered
 LL |     match 0u8 {
    |           ^^^ pattern `128_u8..=u8::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u8`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         128 ..= 255 if true => {}
+LL +         128_u8..=u8::MAX => todo!()
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr b/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr
index 2e0023348e4d8..fec54e89d63cf 100644
--- a/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr
+++ b/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr
@@ -4,8 +4,12 @@ error[E0004]: non-exhaustive patterns: `u8::MAX` not covered
 LL |     m!(0u8, 0..255);
    |        ^^^ pattern `u8::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u8`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         u8::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `u8::MAX` not covered
   --> $DIR/exhaustiveness.rs:48:8
@@ -13,8 +17,12 @@ error[E0004]: non-exhaustive patterns: `u8::MAX` not covered
 LL |     m!(0u8, 0..=254);
    |        ^^^ pattern `u8::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u8`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         u8::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `0_u8` not covered
   --> $DIR/exhaustiveness.rs:49:8
@@ -22,8 +30,12 @@ error[E0004]: non-exhaustive patterns: `0_u8` not covered
 LL |     m!(0u8, 1..=255);
    |        ^^^ pattern `0_u8` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u8`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         0_u8 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `42_u8` not covered
   --> $DIR/exhaustiveness.rs:50:8
@@ -31,8 +43,12 @@ error[E0004]: non-exhaustive patterns: `42_u8` not covered
 LL |     m!(0u8, 0..42 | 43..=255);
    |        ^^^ pattern `42_u8` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u8`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         42_u8 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `i8::MAX` not covered
   --> $DIR/exhaustiveness.rs:51:8
@@ -40,8 +56,12 @@ error[E0004]: non-exhaustive patterns: `i8::MAX` not covered
 LL |     m!(0i8, -128..127);
    |        ^^^ pattern `i8::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i8`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         i8::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `i8::MAX` not covered
   --> $DIR/exhaustiveness.rs:52:8
@@ -49,8 +69,12 @@ error[E0004]: non-exhaustive patterns: `i8::MAX` not covered
 LL |     m!(0i8, -128..=126);
    |        ^^^ pattern `i8::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i8`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         i8::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `i8::MIN` not covered
   --> $DIR/exhaustiveness.rs:53:8
@@ -58,8 +82,12 @@ error[E0004]: non-exhaustive patterns: `i8::MIN` not covered
 LL |     m!(0i8, -127..=127);
    |        ^^^ pattern `i8::MIN` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i8`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         i8::MIN => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `0_i8` not covered
   --> $DIR/exhaustiveness.rs:54:11
@@ -67,8 +95,12 @@ error[E0004]: non-exhaustive patterns: `0_i8` not covered
 LL |     match 0i8 {
    |           ^^^ pattern `0_i8` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i8`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         1 ..= i8::MAX => {}
+LL +         0_i8 => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `u128::MAX` not covered
   --> $DIR/exhaustiveness.rs:59:8
@@ -76,8 +108,12 @@ error[E0004]: non-exhaustive patterns: `u128::MAX` not covered
 LL |     m!(0u128, 0..=ALMOST_MAX);
    |        ^^^^^ pattern `u128::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u128`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         u128::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `5_u128..=u128::MAX` not covered
   --> $DIR/exhaustiveness.rs:60:8
@@ -85,8 +121,12 @@ error[E0004]: non-exhaustive patterns: `5_u128..=u128::MAX` not covered
 LL |     m!(0u128, 0..=4);
    |        ^^^^^ pattern `5_u128..=u128::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u128`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         5_u128..=u128::MAX => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `0_u128` not covered
   --> $DIR/exhaustiveness.rs:61:8
@@ -94,8 +134,12 @@ error[E0004]: non-exhaustive patterns: `0_u128` not covered
 LL |     m!(0u128, 1..=u128::MAX);
    |        ^^^^^ pattern `0_u128` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `u128`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         0_u128 => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `(126_u8..=127_u8, false)` not covered
   --> $DIR/exhaustiveness.rs:69:11
@@ -103,8 +147,12 @@ error[E0004]: non-exhaustive patterns: `(126_u8..=127_u8, false)` not covered
 LL |     match (0u8, true) {
    |           ^^^^^^^^^^^ pattern `(126_u8..=127_u8, false)` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `(u8, bool)`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         (0 ..= 255, true) => {}
+LL +         (126_u8..=127_u8, false) => todo!()
+   |
 
 error: aborting due to 12 previous errors
 
diff --git a/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int.allow.stderr b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int.allow.stderr
index 2563293458379..9f277fa1e1800 100644
--- a/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int.allow.stderr
+++ b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int.allow.stderr
@@ -4,8 +4,13 @@ error[E0004]: non-exhaustive patterns: type `usize` is non-empty
 LL |     match 7usize {}
    |           ^^^^^^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `usize`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match 7usize {
+LL +         _ => todo!(),
+LL +     }
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr
index e8ac9f3cfe156..fa4146a7ad892 100644
--- a/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr
+++ b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr
@@ -4,10 +4,14 @@ error[E0004]: non-exhaustive patterns: `_` not covered
 LL |     match 0usize {
    |           ^^^^^^ pattern `_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `usize`
    = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
    = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         0 ..= usize::MAX => {}
+LL +         _ => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/pointer-sized-int.rs:17:11
@@ -15,10 +19,14 @@ error[E0004]: non-exhaustive patterns: `_` not covered
 LL |     match 0isize {
    |           ^^^^^^ pattern `_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `isize`
    = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
    = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         isize::MIN ..= isize::MAX => {}
+LL +         _ => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/pointer-sized-int.rs:22:8
@@ -26,10 +34,14 @@ error[E0004]: non-exhaustive patterns: `_` not covered
 LL |     m!(0usize, 0..=usize::MAX);
    |        ^^^^^^ pattern `_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `usize`
    = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
    = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         _ => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/pointer-sized-int.rs:24:8
@@ -37,10 +49,14 @@ error[E0004]: non-exhaustive patterns: `_` not covered
 LL |     m!(0usize, 0..5 | 5..=usize::MAX);
    |        ^^^^^^ pattern `_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `usize`
    = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
    = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         _ => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/pointer-sized-int.rs:26:8
@@ -48,10 +64,14 @@ error[E0004]: non-exhaustive patterns: `_` not covered
 LL |     m!(0usize, 0..usize::MAX | usize::MAX);
    |        ^^^^^^ pattern `_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `usize`
    = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
    = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         _ => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `(_, _)` not covered
   --> $DIR/pointer-sized-int.rs:28:8
@@ -59,8 +79,12 @@ error[E0004]: non-exhaustive patterns: `(_, _)` not covered
 LL |     m!((0usize, true), (0..5, true) | (5..=usize::MAX, true) | (0..=usize::MAX, false));
    |        ^^^^^^^^^^^^^^ pattern `(_, _)` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `(usize, bool)`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         (_, _) => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/pointer-sized-int.rs:31:8
@@ -68,10 +92,14 @@ error[E0004]: non-exhaustive patterns: `_` not covered
 LL |     m!(0isize, isize::MIN..=isize::MAX);
    |        ^^^^^^ pattern `_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `isize`
    = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
    = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         _ => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/pointer-sized-int.rs:33:8
@@ -79,10 +107,14 @@ error[E0004]: non-exhaustive patterns: `_` not covered
 LL |     m!(0isize, isize::MIN..5 | 5..=isize::MAX);
    |        ^^^^^^ pattern `_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `isize`
    = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
    = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         _ => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/pointer-sized-int.rs:35:8
@@ -90,10 +122,14 @@ error[E0004]: non-exhaustive patterns: `_` not covered
 LL |     m!(0isize, isize::MIN..isize::MAX | isize::MAX);
    |        ^^^^^^ pattern `_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `isize`
    = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
    = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         _ => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `(_, _)` not covered
   --> $DIR/pointer-sized-int.rs:37:8
@@ -101,8 +137,12 @@ error[E0004]: non-exhaustive patterns: `(_, _)` not covered
 LL |     m!((0isize, true), (isize::MIN..5, true)
    |        ^^^^^^^^^^^^^^ pattern `(_, _)` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `(isize, bool)`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         match $s { $($t)+ => {}
+LL ~         (_, _) => todo!() }
+   |
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/pointer-sized-int.rs:41:11
@@ -110,10 +150,14 @@ error[E0004]: non-exhaustive patterns: `_` not covered
 LL |     match 0isize {
    |           ^^^^^^ pattern `_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `isize`
    = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
    = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         1 ..= isize::MAX => {}
+LL +         _ => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: type `usize` is non-empty
   --> $DIR/pointer-sized-int.rs:48:11
@@ -121,8 +165,13 @@ error[E0004]: non-exhaustive patterns: type `usize` is non-empty
 LL |     match 7usize {}
    |           ^^^^^^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `usize`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match 7usize {
+LL +         _ => todo!(),
+LL +     }
+   |
 
 error: aborting due to 12 previous errors
 
diff --git a/src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.stderr b/src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.stderr
index 37e73a68f22bb..30492c98206c9 100644
--- a/src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.stderr
+++ b/src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.stderr
@@ -4,10 +4,14 @@ error[E0004]: non-exhaustive patterns: `_` not covered
 LL |     match 0usize {
    |           ^^^^^^ pattern `_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `usize`
    = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
    = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         0..=usize::MAX => {}
+LL +         _ => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/precise_pointer_matching-message.rs:11:11
@@ -15,10 +19,14 @@ error[E0004]: non-exhaustive patterns: `_` not covered
 LL |     match 0isize {
    |           ^^^^^^ pattern `_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `isize`
    = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
    = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         isize::MIN..=isize::MAX => {}
+LL +         _ => todo!()
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/pattern/usefulness/issue-15129.stderr b/src/test/ui/pattern/usefulness/issue-15129.stderr
index 79a77240937ac..af60f3ff50bf3 100644
--- a/src/test/ui/pattern/usefulness/issue-15129.stderr
+++ b/src/test/ui/pattern/usefulness/issue-15129.stderr
@@ -4,8 +4,12 @@ error[E0004]: non-exhaustive patterns: `(T1(()), V2(_))` and `(T2(()), V1(_))` n
 LL |     match (T::T1(()), V::V2(true)) {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `(T1(()), V2(_))` and `(T2(()), V1(_))` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `(T, V)`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~         (T::T2(()), V::V2(b)) => (),
+LL ~         (T1(()), V2(_)) | (T2(()), V1(_)) => todo!(),
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/pattern/usefulness/issue-2111.stderr b/src/test/ui/pattern/usefulness/issue-2111.stderr
index 60d9b8514b7fb..01890b73cbdd8 100644
--- a/src/test/ui/pattern/usefulness/issue-2111.stderr
+++ b/src/test/ui/pattern/usefulness/issue-2111.stderr
@@ -4,8 +4,12 @@ error[E0004]: non-exhaustive patterns: `(None, None)` and `(Some(_), Some(_))` n
 LL |     match (a, b) {
    |           ^^^^^^ patterns `(None, None)` and `(Some(_), Some(_))` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `(Option<usize>, Option<usize>)`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~         (Some(_), None) | (None, Some(_)) => {}
+LL +         (None, None) | (Some(_), Some(_)) => todo!()
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/pattern/usefulness/issue-30240.stderr b/src/test/ui/pattern/usefulness/issue-30240.stderr
index a2c58d6e051b5..759fdeafe4eb5 100644
--- a/src/test/ui/pattern/usefulness/issue-30240.stderr
+++ b/src/test/ui/pattern/usefulness/issue-30240.stderr
@@ -4,8 +4,12 @@ error[E0004]: non-exhaustive patterns: `&_` not covered
 LL |     match "world" {
    |           ^^^^^^^ pattern `&_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&str`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         "hello" => {}
+LL +         &_ => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `&_` not covered
   --> $DIR/issue-30240.rs:6:11
@@ -13,8 +17,12 @@ error[E0004]: non-exhaustive patterns: `&_` not covered
 LL |     match "world" {
    |           ^^^^^^^ pattern `&_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&str`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         "hello" => {}
+LL +         &_ => todo!()
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/pattern/usefulness/issue-3096-1.stderr b/src/test/ui/pattern/usefulness/issue-3096-1.stderr
index 97c34755189de..d8884394f8e96 100644
--- a/src/test/ui/pattern/usefulness/issue-3096-1.stderr
+++ b/src/test/ui/pattern/usefulness/issue-3096-1.stderr
@@ -4,8 +4,13 @@ error[E0004]: non-exhaustive patterns: type `()` is non-empty
 LL |     match () { }
    |           ^^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `()`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match () {
+LL +         _ => todo!(),
+LL ~     }
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/pattern/usefulness/issue-3096-2.stderr b/src/test/ui/pattern/usefulness/issue-3096-2.stderr
index 472d1a91e6a15..2df8911badcda 100644
--- a/src/test/ui/pattern/usefulness/issue-3096-2.stderr
+++ b/src/test/ui/pattern/usefulness/issue-3096-2.stderr
@@ -4,8 +4,13 @@ error[E0004]: non-exhaustive patterns: type `*const Bottom` is non-empty
 LL |     match x { }
    |           ^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `*const Bottom`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match x {
+LL +         _ => todo!(),
+LL ~     }
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/pattern/usefulness/issue-31561.stderr b/src/test/ui/pattern/usefulness/issue-31561.stderr
index 2f562b23692de..dffcfc016072f 100644
--- a/src/test/ui/pattern/usefulness/issue-31561.stderr
+++ b/src/test/ui/pattern/usefulness/issue-31561.stderr
@@ -1,20 +1,21 @@
 error[E0005]: refutable pattern in local binding: `Bar` and `Baz` not covered
   --> $DIR/issue-31561.rs:8:9
    |
-LL | / enum Thing {
-LL | |     Foo(u8),
-LL | |     Bar,
-   | |     --- not covered
-LL | |     Baz
-   | |     --- not covered
-LL | | }
-   | |_- `Thing` defined here
-...
-LL |       let Thing::Foo(y) = Thing::Foo(1);
-   |           ^^^^^^^^^^^^^ patterns `Bar` and `Baz` not covered
+LL |     let Thing::Foo(y) = Thing::Foo(1);
+   |         ^^^^^^^^^^^^^ patterns `Bar` and `Baz` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+note: `Thing` defined here
+  --> $DIR/issue-31561.rs:3:5
+   |
+LL | enum Thing {
+   |      -----
+LL |     Foo(u8),
+LL |     Bar,
+   |     ^^^ not covered
+LL |     Baz
+   |     ^^^ not covered
    = note: the matched value is of type `Thing`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
diff --git a/src/test/ui/pattern/usefulness/issue-35609.stderr b/src/test/ui/pattern/usefulness/issue-35609.stderr
index 0598c8d6f38c5..717bb53c32750 100644
--- a/src/test/ui/pattern/usefulness/issue-35609.stderr
+++ b/src/test/ui/pattern/usefulness/issue-35609.stderr
@@ -4,8 +4,12 @@ error[E0004]: non-exhaustive patterns: `(B, _)`, `(C, _)`, `(D, _)` and 2 more n
 LL |     match (A, ()) {
    |           ^^^^^^^ patterns `(B, _)`, `(C, _)`, `(D, _)` and 2 more not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `(Enum, ())`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
+   |
+LL ~         (A, _) => {}
+LL +         _ => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `(_, B)`, `(_, C)`, `(_, D)` and 2 more not covered
   --> $DIR/issue-35609.rs:14:11
@@ -13,8 +17,12 @@ error[E0004]: non-exhaustive patterns: `(_, B)`, `(_, C)`, `(_, D)` and 2 more n
 LL |     match (A, A) {
    |           ^^^^^^ patterns `(_, B)`, `(_, C)`, `(_, D)` and 2 more not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `(Enum, Enum)`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
+   |
+LL ~         (_, A) => {}
+LL +         _ => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered
   --> $DIR/issue-35609.rs:18:11
@@ -22,8 +30,12 @@ error[E0004]: non-exhaustive patterns: `((B, _), _)`, `((C, _), _)`, `((D, _), _
 LL |     match ((A, ()), ()) {
    |           ^^^^^^^^^^^^^ patterns `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `((Enum, ()), ())`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
+   |
+LL ~         ((A, ()), _) => {}
+LL +         _ => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered
   --> $DIR/issue-35609.rs:22:11
@@ -31,8 +43,12 @@ error[E0004]: non-exhaustive patterns: `((B, _), _)`, `((C, _), _)`, `((D, _), _
 LL |     match ((A, ()), A) {
    |           ^^^^^^^^^^^^ patterns `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `((Enum, ()), Enum)`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
+   |
+LL ~         ((A, ()), _) => {}
+LL +         _ => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered
   --> $DIR/issue-35609.rs:26:11
@@ -40,32 +56,48 @@ error[E0004]: non-exhaustive patterns: `((B, _), _)`, `((C, _), _)`, `((D, _), _
 LL |     match ((A, ()), ()) {
    |           ^^^^^^^^^^^^^ patterns `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `((Enum, ()), ())`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
+   |
+LL ~         ((A, _), _) => {}
+LL +         _ => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `S(B, _)`, `S(C, _)`, `S(D, _)` and 2 more not covered
   --> $DIR/issue-35609.rs:31:11
    |
-LL | struct S(Enum, ());
-   | ------------------- `S` defined here
-...
 LL |     match S(A, ()) {
    |           ^^^^^^^^ patterns `S(B, _)`, `S(C, _)`, `S(D, _)` and 2 more not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `S` defined here
+  --> $DIR/issue-35609.rs:6:8
+   |
+LL | struct S(Enum, ());
+   |        ^
    = note: the matched value is of type `S`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
+   |
+LL ~         S(A, _) => {}
+LL +         _ => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `Sd { x: B, .. }`, `Sd { x: C, .. }`, `Sd { x: D, .. }` and 2 more not covered
   --> $DIR/issue-35609.rs:35:11
    |
-LL | struct Sd { x: Enum, y: () }
-   | ---------------------------- `Sd` defined here
-...
 LL |     match (Sd { x: A, y: () }) {
    |           ^^^^^^^^^^^^^^^^^^^^ patterns `Sd { x: B, .. }`, `Sd { x: C, .. }`, `Sd { x: D, .. }` and 2 more not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `Sd` defined here
+  --> $DIR/issue-35609.rs:7:8
+   |
+LL | struct Sd { x: Enum, y: () }
+   |        ^^
    = note: the matched value is of type `Sd`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
+   |
+LL ~         Sd { x: A, y: _ } => {}
+LL +         _ => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `Some(B)`, `Some(C)`, `Some(D)` and 2 more not covered
   --> $DIR/issue-35609.rs:39:11
@@ -73,8 +105,23 @@ error[E0004]: non-exhaustive patterns: `Some(B)`, `Some(C)`, `Some(D)` and 2 mor
 LL |     match Some(A) {
    |           ^^^^^^^ patterns `Some(B)`, `Some(C)`, `Some(D)` and 2 more not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `Option<Enum>` defined here
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+   |
+LL | / pub enum Option<T> {
+LL | |     /// No value.
+LL | |     #[lang = "None"]
+LL | |     #[stable(feature = "rust1", since = "1.0.0")]
+...  |
+LL | |     Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+LL | | }
+   | |_^
    = note: the matched value is of type `Option<Enum>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
+   |
+LL ~         None => (),
+LL +         _ => todo!()
+   |
 
 error: aborting due to 8 previous errors
 
diff --git a/src/test/ui/pattern/usefulness/issue-3601.stderr b/src/test/ui/pattern/usefulness/issue-3601.stderr
index 48ed14915084a..4e0adcc1ba2a5 100644
--- a/src/test/ui/pattern/usefulness/issue-3601.stderr
+++ b/src/test/ui/pattern/usefulness/issue-3601.stderr
@@ -4,8 +4,20 @@ error[E0004]: non-exhaustive patterns: `box _` not covered
 LL |         box NodeKind::Element(ed) => match ed.kind {
    |                                            ^^^^^^^ pattern `box _` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `Box<ElementKind>` defined here
+  --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+   |
+LL | / pub struct Box<
+LL | |     T: ?Sized,
+LL | |     #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
+LL | | >(Unique<T>, A);
+   | |________________^
    = note: the matched value is of type `Box<ElementKind>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~             box ElementKind::HTMLImageElement(ref d) if d.image.is_some() => { true }
+LL +             box _ => todo!()
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/pattern/usefulness/issue-39362.stderr b/src/test/ui/pattern/usefulness/issue-39362.stderr
index 8c162e55619e0..ca37af6fb8095 100644
--- a/src/test/ui/pattern/usefulness/issue-39362.stderr
+++ b/src/test/ui/pattern/usefulness/issue-39362.stderr
@@ -1,16 +1,22 @@
 error[E0004]: non-exhaustive patterns: `Bar { bar: C, .. }`, `Bar { bar: D, .. }`, `Bar { bar: E, .. }` and 1 more not covered
   --> $DIR/issue-39362.rs:10:11
    |
-LL | / enum Foo {
-LL | |     Bar { bar: Bar, id: usize }
-LL | | }
-   | |_- `Foo` defined here
-...
-LL |       match f {
-   |             ^ patterns `Bar { bar: C, .. }`, `Bar { bar: D, .. }`, `Bar { bar: E, .. }` and 1 more not covered
+LL |     match f {
+   |           ^ patterns `Bar { bar: C, .. }`, `Bar { bar: D, .. }`, `Bar { bar: E, .. }` and 1 more not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `Foo` defined here
+  --> $DIR/issue-39362.rs:2:5
+   |
+LL | enum Foo {
+   |      ---
+LL |     Bar { bar: Bar, id: usize }
+   |     ^^^ not covered
    = note: the matched value is of type `Foo`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
+   |
+LL ~         Foo::Bar { bar: Bar::B, .. } => (),
+LL ~         _ => todo!(),
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/pattern/usefulness/issue-40221.stderr b/src/test/ui/pattern/usefulness/issue-40221.stderr
index 98efe805a0b34..c477e43533504 100644
--- a/src/test/ui/pattern/usefulness/issue-40221.stderr
+++ b/src/test/ui/pattern/usefulness/issue-40221.stderr
@@ -1,17 +1,22 @@
 error[E0004]: non-exhaustive patterns: `C(QA)` not covered
   --> $DIR/issue-40221.rs:11:11
    |
-LL | / enum P {
-LL | |     C(PC),
-   | |     - not covered
-LL | | }
-   | |_- `P` defined here
-...
-LL |       match proto {
-   |             ^^^^^ pattern `C(QA)` not covered
+LL |     match proto {
+   |           ^^^^^ pattern `C(QA)` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `P` defined here
+  --> $DIR/issue-40221.rs:2:5
+   |
+LL | enum P {
+   |      -
+LL |     C(PC),
+   |     ^ not covered
    = note: the matched value is of type `P`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         P::C(PC::Q) => (),
+LL ~         C(QA) => todo!(),
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/pattern/usefulness/issue-4321.stderr b/src/test/ui/pattern/usefulness/issue-4321.stderr
index 1e8852556b161..2932731741016 100644
--- a/src/test/ui/pattern/usefulness/issue-4321.stderr
+++ b/src/test/ui/pattern/usefulness/issue-4321.stderr
@@ -4,8 +4,12 @@ error[E0004]: non-exhaustive patterns: `(true, false)` not covered
 LL |     println!("foo {:}", match tup {
    |                               ^^^ pattern `(true, false)` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `(bool, bool)`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         (true, true) => "baz",
+LL +         (true, false) => todo!()
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/pattern/usefulness/issue-50900.stderr b/src/test/ui/pattern/usefulness/issue-50900.stderr
index d378b6e8efe37..2bdbecabbbea0 100644
--- a/src/test/ui/pattern/usefulness/issue-50900.stderr
+++ b/src/test/ui/pattern/usefulness/issue-50900.stderr
@@ -1,14 +1,20 @@
 error[E0004]: non-exhaustive patterns: `Tag(Exif, _)` not covered
   --> $DIR/issue-50900.rs:15:11
    |
-LL | pub struct Tag(pub Context, pub u16);
-   | ------------------------------------- `Tag` defined here
-...
 LL |     match Tag::ExifIFDPointer {
    |           ^^^^^^^^^^^^^^^^^^^ pattern `Tag(Exif, _)` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `Tag` defined here
+  --> $DIR/issue-50900.rs:2:12
+   |
+LL | pub struct Tag(pub Context, pub u16);
+   |            ^^^
    = note: the matched value is of type `Tag`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         Tag::ExifIFDPointer => {}
+LL +         Tag(Exif, _) => todo!()
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/pattern/usefulness/issue-56379.stderr b/src/test/ui/pattern/usefulness/issue-56379.stderr
index 6a231b868c8c4..f6261001c5e09 100644
--- a/src/test/ui/pattern/usefulness/issue-56379.stderr
+++ b/src/test/ui/pattern/usefulness/issue-56379.stderr
@@ -1,21 +1,26 @@
 error[E0004]: non-exhaustive patterns: `A(false)`, `B(false)` and `C(false)` not covered
   --> $DIR/issue-56379.rs:8:11
    |
-LL | / enum Foo {
-LL | |     A(bool),
-   | |     - not covered
-LL | |     B(bool),
-   | |     - not covered
-LL | |     C(bool),
-   | |     - not covered
-LL | | }
-   | |_- `Foo` defined here
-...
-LL |       match Foo::A(true) {
-   |             ^^^^^^^^^^^^ patterns `A(false)`, `B(false)` and `C(false)` not covered
+LL |     match Foo::A(true) {
+   |           ^^^^^^^^^^^^ patterns `A(false)`, `B(false)` and `C(false)` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `Foo` defined here
+  --> $DIR/issue-56379.rs:2:5
+   |
+LL | enum Foo {
+   |      ---
+LL |     A(bool),
+   |     ^ not covered
+LL |     B(bool),
+   |     ^ not covered
+LL |     C(bool),
+   |     ^ not covered
    = note: the matched value is of type `Foo`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~         Foo::C(true) => {}
+LL +         A(false) | B(false) | C(false) => todo!()
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/pattern/usefulness/issue-72377.stderr b/src/test/ui/pattern/usefulness/issue-72377.stderr
index b4a68333967b3..20f002dd3db15 100644
--- a/src/test/ui/pattern/usefulness/issue-72377.stderr
+++ b/src/test/ui/pattern/usefulness/issue-72377.stderr
@@ -4,8 +4,12 @@ error[E0004]: non-exhaustive patterns: `(A, Some(A))`, `(A, Some(B))`, `(B, Some
 LL |     match (x, y) {
    |           ^^^^^^ patterns `(A, Some(A))`, `(A, Some(B))`, `(B, Some(B))` and 2 more not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `(X, Option<X>)`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
+   |
+LL ~         (X::A, Some(X::C)) | (X::C, Some(X::A)) => false,
+LL ~         _ => todo!(),
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.rs b/src/test/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.rs
index 6c5a331b4b564..cbfcf0eafd490 100644
--- a/src/test/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.rs
+++ b/src/test/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.rs
@@ -1,5 +1,6 @@
 enum A {}
     //~^ NOTE `A` defined here
+    //~| NOTE
 
 fn f(a: &A) {
     match a {}
diff --git a/src/test/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr b/src/test/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr
index e992632a91faf..bf05d616d6ed1 100644
--- a/src/test/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr
+++ b/src/test/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr
@@ -1,15 +1,22 @@
 error[E0004]: non-exhaustive patterns: type `&A` is non-empty
-  --> $DIR/issue-78123-non-exhaustive-reference.rs:5:11
+  --> $DIR/issue-78123-non-exhaustive-reference.rs:6:11
    |
-LL | enum A {}
-   | --------- `A` defined here
-...
 LL |     match a {}
    |           ^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `A` defined here
+  --> $DIR/issue-78123-non-exhaustive-reference.rs:1:6
+   |
+LL | enum A {}
+   |      ^
    = note: the matched value is of type `&A`
    = note: references are always considered inhabited
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match a {
+LL +         _ => todo!(),
+LL +     }
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr b/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr
index 4a987cb6c0311..3326e6b85a471 100644
--- a/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr
+++ b/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr
@@ -4,8 +4,12 @@ error[E0004]: non-exhaustive patterns: `(true, false)` not covered
 LL |     match (true, false) {
    |           ^^^^^^^^^^^^^ pattern `(true, false)` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `(bool, bool)`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         (false, true) => (),
+LL +         (true, false) => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `Some(Some(West))` not covered
   --> $DIR/match-arm-statics-2.rs:29:11
@@ -13,31 +17,45 @@ error[E0004]: non-exhaustive patterns: `Some(Some(West))` not covered
 LL |     match Some(Some(North)) {
    |           ^^^^^^^^^^^^^^^^^ pattern `Some(Some(West))` not covered
    |
-  ::: $SRC_DIR/core/src/option.rs:LL:COL
+note: `Option<Option<Direction>>` defined here
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+   |
+LL | / pub enum Option<T> {
+LL | |     /// No value.
+LL | |     #[lang = "None"]
+LL | |     #[stable(feature = "rust1", since = "1.0.0")]
+...  |
+LL | |     Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+   | |     ^^^^
+   | |     |
+   | |     not covered
+   | |     not covered
+LL | | }
+   | |_-
+   = note: the matched value is of type `Option<Option<Direction>>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL |     Some(#[stable(feature = "rust1", since = "1.0.0")] T),
-   |     ----
-   |     |
-   |     not covered
-   |     not covered
+LL ~         None => (),
+LL +         Some(Some(West)) => todo!()
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
-   = note: the matched value is of type `Option<Option<Direction>>`
 
 error[E0004]: non-exhaustive patterns: `Foo { bar: Some(North), baz: NewBool(true) }` not covered
   --> $DIR/match-arm-statics-2.rs:48:11
    |
-LL | / struct Foo {
-LL | |     bar: Option<Direction>,
-LL | |     baz: NewBool
-LL | | }
-   | |_- `Foo` defined here
-...
-LL |       match (Foo { bar: Some(North), baz: NewBool(true) }) {
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo { bar: Some(North), baz: NewBool(true) }` not covered
+LL |     match (Foo { bar: Some(North), baz: NewBool(true) }) {
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo { bar: Some(North), baz: NewBool(true) }` not covered
+   |
+note: `Foo` defined here
+  --> $DIR/match-arm-statics-2.rs:40:8
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | struct Foo {
+   |        ^^^
    = note: the matched value is of type `Foo`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         Foo { bar: Some(EAST), .. } => (),
+LL +         Foo { bar: Some(North), baz: NewBool(true) } => todo!()
+   |
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/pattern/usefulness/match-byte-array-patterns-2.stderr b/src/test/ui/pattern/usefulness/match-byte-array-patterns-2.stderr
index ffc8433403fd5..a90f32f7aebf3 100644
--- a/src/test/ui/pattern/usefulness/match-byte-array-patterns-2.stderr
+++ b/src/test/ui/pattern/usefulness/match-byte-array-patterns-2.stderr
@@ -4,8 +4,12 @@ error[E0004]: non-exhaustive patterns: `&[0_u8..=64_u8, _, _, _]` and `&[66_u8..
 LL |     match buf {
    |           ^^^ patterns `&[0_u8..=64_u8, _, _, _]` and `&[66_u8..=u8::MAX, _, _, _]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[u8; 4]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~         b"AAAA" => {}
+LL +         &[0_u8..=64_u8, _, _, _] | &[66_u8..=u8::MAX, _, _, _] => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `&[]`, `&[_]`, `&[_, _]` and 2 more not covered
   --> $DIR/match-byte-array-patterns-2.rs:10:11
@@ -13,8 +17,12 @@ error[E0004]: non-exhaustive patterns: `&[]`, `&[_]`, `&[_, _]` and 2 more not c
 LL |     match buf {
    |           ^^^ patterns `&[]`, `&[_]`, `&[_, _]` and 2 more not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[u8]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
+   |
+LL ~         b"AAAA" => {}
+LL +         _ => todo!()
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/pattern/usefulness/match-non-exhaustive.stderr b/src/test/ui/pattern/usefulness/match-non-exhaustive.stderr
index a35d61e4b710b..08dde523a15fb 100644
--- a/src/test/ui/pattern/usefulness/match-non-exhaustive.stderr
+++ b/src/test/ui/pattern/usefulness/match-non-exhaustive.stderr
@@ -4,8 +4,11 @@ error[E0004]: non-exhaustive patterns: `i32::MIN..=0_i32` and `2_i32..=i32::MAX`
 LL |     match 0 { 1 => () }
    |           ^ patterns `i32::MIN..=0_i32` and `2_i32..=i32::MAX` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i32`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL |     match 0 { 1 => (), i32::MIN..=0_i32 | 2_i32..=i32::MAX => todo!() }
+   |                      ++++++++++++++++++++++++++++++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/match-non-exhaustive.rs:3:11
@@ -13,8 +16,11 @@ error[E0004]: non-exhaustive patterns: `_` not covered
 LL |     match 0 { 0 if false => () }
    |           ^ pattern `_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `i32`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL |     match 0 { 0 if false => (), _ => todo!() }
+   |                               ++++++++++++++
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/pattern/usefulness/match-privately-empty.stderr b/src/test/ui/pattern/usefulness/match-privately-empty.stderr
index 4efb41978a241..88178d6429197 100644
--- a/src/test/ui/pattern/usefulness/match-privately-empty.stderr
+++ b/src/test/ui/pattern/usefulness/match-privately-empty.stderr
@@ -4,13 +4,24 @@ error[E0004]: non-exhaustive patterns: `Some(Private { misc: true, .. })` not co
 LL |     match private::DATA {
    |           ^^^^^^^^^^^^^ pattern `Some(Private { misc: true, .. })` not covered
    |
-  ::: $SRC_DIR/core/src/option.rs:LL:COL
+note: `Option<Private>` defined here
+  --> $SRC_DIR/core/src/option.rs:LL:COL
    |
-LL |     Some(#[stable(feature = "rust1", since = "1.0.0")] T),
-   |     ---- not covered
-   |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | / pub enum Option<T> {
+LL | |     /// No value.
+LL | |     #[lang = "None"]
+LL | |     #[stable(feature = "rust1", since = "1.0.0")]
+...  |
+LL | |     Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+   | |     ^^^^ not covered
+LL | | }
+   | |_-
    = note: the matched value is of type `Option<Private>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         }) => {}
+LL +         Some(Private { misc: true, .. }) => todo!()
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/pattern/usefulness/match-slice-patterns.stderr b/src/test/ui/pattern/usefulness/match-slice-patterns.stderr
index 88f27be0412aa..961dd59011961 100644
--- a/src/test/ui/pattern/usefulness/match-slice-patterns.stderr
+++ b/src/test/ui/pattern/usefulness/match-slice-patterns.stderr
@@ -4,8 +4,12 @@ error[E0004]: non-exhaustive patterns: `&[_, Some(_), .., None, _]` not covered
 LL |     match list {
    |           ^^^^ pattern `&[_, Some(_), .., None, _]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[Option<()>]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         &[.., Some(_), _] => {}
+LL ~         &[_, Some(_), .., None, _] => todo!(),
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-defined-here.rs b/src/test/ui/pattern/usefulness/non-exhaustive-defined-here.rs
index 6f009acbdfe18..2e15bc2d2a5f5 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-defined-here.rs
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-defined-here.rs
@@ -4,20 +4,26 @@
 
 #[derive(Clone)]
 enum E {
-//~^ `E` defined here
-//~| `E` defined here
-//~| `E` defined here
-//~| `E` defined here
-//~| `E` defined here
-//~| `E` defined here
+    //~^ NOTE
+    //~| NOTE
+    //~| NOTE
+    //~| NOTE
+    //~| NOTE
+    //~| NOTE
     A,
     B,
-    //~^ not covered
-    //~| not covered
-    //~| not covered
-    //~| not covered
-    //~| not covered
-    //~| not covered
+    //~^ NOTE `E` defined here
+    //~| NOTE `E` defined here
+    //~| NOTE `E` defined here
+    //~| NOTE `E` defined here
+    //~| NOTE `E` defined here
+    //~| NOTE `E` defined here
+    //~| NOTE  not covered
+    //~| NOTE  not covered
+    //~| NOTE  not covered
+    //~| NOTE  not covered
+    //~| NOTE  not covered
+    //~| NOTE  not covered
     C
     //~^ not covered
     //~| not covered
@@ -30,43 +36,70 @@ enum E {
 fn by_val(e: E) {
     let e1 = e.clone();
     match e1 { //~ ERROR non-exhaustive patterns: `B` and `C` not covered
+        //~^ NOTE patterns `B` and `C` not covered
+        //~| NOTE the matched value is of type `E`
         E::A => {}
     }
 
     let E::A = e; //~ ERROR refutable pattern in local binding: `B` and `C` not covered
+    //~^ NOTE patterns `B` and `C` not covered
+    //~| NOTE `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with
+    //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+    //~| NOTE the matched value is of type `E`
 }
 
 fn by_ref_once(e: &E) {
     match e { //~ ERROR non-exhaustive patterns: `&B` and `&C` not covered
+    //~^ NOTE patterns `&B` and `&C` not covered
+    //~| NOTE the matched value is of type `&E`
         E::A => {}
     }
 
     let E::A = e; //~ ERROR refutable pattern in local binding: `&B` and `&C` not covered
+    //~^ NOTE patterns `&B` and `&C` not covered
+    //~| NOTE `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with
+    //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+    //~| NOTE the matched value is of type `&E`
 }
 
 fn by_ref_thrice(e: & &mut &E) {
     match e { //~ ERROR non-exhaustive patterns: `&&mut &B` and `&&mut &C` not covered
+    //~^ NOTE patterns `&&mut &B` and `&&mut &C` not covered
+    //~| NOTE the matched value is of type `&&mut &E`
         E::A => {}
     }
 
     let E::A = e;
     //~^ ERROR refutable pattern in local binding: `&&mut &B` and `&&mut &C` not covered
+    //~| NOTE patterns `&&mut &B` and `&&mut &C` not covered
+    //~| NOTE `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with
+    //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+    //~| NOTE the matched value is of type `&&mut &E`
 }
 
 enum Opt {
-//~^ `Opt` defined here
-//~| `Opt` defined here
+    //~^ NOTE
+    //~| NOTE
     Some(u8),
     None,
-    //~^ not covered
+    //~^ NOTE `Opt` defined here
+    //~| NOTE `Opt` defined here
+    //~| NOTE not covered
+    //~| NOTE not covered
 }
 
 fn ref_pat(e: Opt) {
     match e {//~ ERROR non-exhaustive patterns: `None` not covered
+        //~^ NOTE pattern `None` not covered
+        //~| NOTE the matched value is of type `Opt`
         Opt::Some(ref _x) => {}
     }
 
     let Opt::Some(ref _x) = e; //~ ERROR refutable pattern in local binding: `None` not covered
+    //~^ NOTE the matched value is of type `Opt`
+    //~| NOTE pattern `None` not covered
+    //~| NOTE `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with
+    //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
 }
 
 fn main() {}
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-defined-here.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-defined-here.stderr
index 02eff28015d17..8f5adccea806d 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-defined-here.stderr
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-defined-here.stderr
@@ -1,50 +1,46 @@
 error[E0004]: non-exhaustive patterns: `B` and `C` not covered
-  --> $DIR/non-exhaustive-defined-here.rs:32:11
-   |
-LL | / enum E {
-LL | |
-LL | |
-LL | |
-...  |
-LL | |     B,
-   | |     - not covered
-...  |
-LL | |     C
-   | |     - not covered
-...  |
-LL | |
-LL | | }
-   | |_- `E` defined here
-...
-LL |       match e1 {
-   |             ^^ patterns `B` and `C` not covered
+  --> $DIR/non-exhaustive-defined-here.rs:38:11
+   |
+LL |     match e1 {
+   |           ^^ patterns `B` and `C` not covered
+   |
+note: `E` defined here
+  --> $DIR/non-exhaustive-defined-here.rs:14:5
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | enum E {
+   |      -
+...
+LL |     B,
+   |     ^ not covered
+...
+LL |     C
+   |     ^ not covered
    = note: the matched value is of type `E`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~         E::A => {}
+LL +         B | C => todo!()
+   |
 
 error[E0005]: refutable pattern in local binding: `B` and `C` not covered
-  --> $DIR/non-exhaustive-defined-here.rs:36:9
-   |
-LL | / enum E {
-LL | |
-LL | |
-LL | |
-...  |
-LL | |     B,
-   | |     - not covered
-...  |
-LL | |     C
-   | |     - not covered
-...  |
-LL | |
-LL | | }
-   | |_- `E` defined here
-...
-LL |       let E::A = e;
-   |           ^^^^ patterns `B` and `C` not covered
+  --> $DIR/non-exhaustive-defined-here.rs:44:9
+   |
+LL |     let E::A = e;
+   |         ^^^^ patterns `B` and `C` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+note: `E` defined here
+  --> $DIR/non-exhaustive-defined-here.rs:14:5
+   |
+LL | enum E {
+   |      -
+...
+LL |     B,
+   |     ^ not covered
+...
+LL |     C
+   |     ^ not covered
    = note: the matched value is of type `E`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
@@ -52,52 +48,48 @@ LL |     if let E::A = e { /* */ }
    |     ~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0004]: non-exhaustive patterns: `&B` and `&C` not covered
-  --> $DIR/non-exhaustive-defined-here.rs:40:11
-   |
-LL | / enum E {
-LL | |
-LL | |
-LL | |
-...  |
-LL | |     B,
-   | |     - not covered
-...  |
-LL | |     C
-   | |     - not covered
-...  |
-LL | |
-LL | | }
-   | |_- `E` defined here
-...
-LL |       match e {
-   |             ^ patterns `&B` and `&C` not covered
+  --> $DIR/non-exhaustive-defined-here.rs:52:11
+   |
+LL |     match e {
+   |           ^ patterns `&B` and `&C` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `E` defined here
+  --> $DIR/non-exhaustive-defined-here.rs:14:5
+   |
+LL | enum E {
+   |      -
+...
+LL |     B,
+   |     ^ not covered
+...
+LL |     C
+   |     ^ not covered
    = note: the matched value is of type `&E`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~         E::A => {}
+LL +         &B | &C => todo!()
+   |
 
 error[E0005]: refutable pattern in local binding: `&B` and `&C` not covered
-  --> $DIR/non-exhaustive-defined-here.rs:44:9
+  --> $DIR/non-exhaustive-defined-here.rs:58:9
    |
-LL | / enum E {
-LL | |
-LL | |
-LL | |
-...  |
-LL | |     B,
-   | |     - not covered
-...  |
-LL | |     C
-   | |     - not covered
-...  |
-LL | |
-LL | | }
-   | |_- `E` defined here
-...
-LL |       let E::A = e;
-   |           ^^^^ patterns `&B` and `&C` not covered
+LL |     let E::A = e;
+   |         ^^^^ patterns `&B` and `&C` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+note: `E` defined here
+  --> $DIR/non-exhaustive-defined-here.rs:14:5
+   |
+LL | enum E {
+   |      -
+...
+LL |     B,
+   |     ^ not covered
+...
+LL |     C
+   |     ^ not covered
    = note: the matched value is of type `&E`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
@@ -105,52 +97,48 @@ LL |     if let E::A = e { /* */ }
    |     ~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0004]: non-exhaustive patterns: `&&mut &B` and `&&mut &C` not covered
-  --> $DIR/non-exhaustive-defined-here.rs:48:11
-   |
-LL | / enum E {
-LL | |
-LL | |
-LL | |
-...  |
-LL | |     B,
-   | |     - not covered
-...  |
-LL | |     C
-   | |     - not covered
-...  |
-LL | |
-LL | | }
-   | |_- `E` defined here
-...
-LL |       match e {
-   |             ^ patterns `&&mut &B` and `&&mut &C` not covered
+  --> $DIR/non-exhaustive-defined-here.rs:66:11
+   |
+LL |     match e {
+   |           ^ patterns `&&mut &B` and `&&mut &C` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `E` defined here
+  --> $DIR/non-exhaustive-defined-here.rs:14:5
+   |
+LL | enum E {
+   |      -
+...
+LL |     B,
+   |     ^ not covered
+...
+LL |     C
+   |     ^ not covered
    = note: the matched value is of type `&&mut &E`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~         E::A => {}
+LL +         &&mut &B | &&mut &C => todo!()
+   |
 
 error[E0005]: refutable pattern in local binding: `&&mut &B` and `&&mut &C` not covered
-  --> $DIR/non-exhaustive-defined-here.rs:52:9
-   |
-LL | / enum E {
-LL | |
-LL | |
-LL | |
-...  |
-LL | |     B,
-   | |     - not covered
-...  |
-LL | |     C
-   | |     - not covered
-...  |
-LL | |
-LL | | }
-   | |_- `E` defined here
-...
-LL |       let E::A = e;
-   |           ^^^^ patterns `&&mut &B` and `&&mut &C` not covered
+  --> $DIR/non-exhaustive-defined-here.rs:72:9
+   |
+LL |     let E::A = e;
+   |         ^^^^ patterns `&&mut &B` and `&&mut &C` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+note: `E` defined here
+  --> $DIR/non-exhaustive-defined-here.rs:14:5
+   |
+LL | enum E {
+   |      -
+...
+LL |     B,
+   |     ^ not covered
+...
+LL |     C
+   |     ^ not covered
    = note: the matched value is of type `&&mut &E`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
@@ -158,42 +146,42 @@ LL |     if let E::A = e { /* */ }
    |
 
 error[E0004]: non-exhaustive patterns: `None` not covered
-  --> $DIR/non-exhaustive-defined-here.rs:65:11
-   |
-LL | / enum Opt {
-LL | |
-LL | |
-LL | |     Some(u8),
-LL | |     None,
-   | |     ---- not covered
-LL | |
-LL | | }
-   | |_- `Opt` defined here
-...
-LL |       match e {
-   |             ^ pattern `None` not covered
+  --> $DIR/non-exhaustive-defined-here.rs:92:11
+   |
+LL |     match e {
+   |           ^ pattern `None` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `Opt` defined here
+  --> $DIR/non-exhaustive-defined-here.rs:84:5
+   |
+LL | enum Opt {
+   |      ---
+...
+LL |     None,
+   |     ^^^^ not covered
    = note: the matched value is of type `Opt`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         Opt::Some(ref _x) => {}
+LL +         None => todo!()
+   |
 
 error[E0005]: refutable pattern in local binding: `None` not covered
-  --> $DIR/non-exhaustive-defined-here.rs:69:9
-   |
-LL | / enum Opt {
-LL | |
-LL | |
-LL | |     Some(u8),
-LL | |     None,
-   | |     ---- not covered
-LL | |
-LL | | }
-   | |_- `Opt` defined here
-...
-LL |       let Opt::Some(ref _x) = e;
-   |           ^^^^^^^^^^^^^^^^^ pattern `None` not covered
+  --> $DIR/non-exhaustive-defined-here.rs:98:9
+   |
+LL |     let Opt::Some(ref _x) = e;
+   |         ^^^^^^^^^^^^^^^^^ pattern `None` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+note: `Opt` defined here
+  --> $DIR/non-exhaustive-defined-here.rs:84:5
+   |
+LL | enum Opt {
+   |      ---
+...
+LL |     None,
+   |     ^^^^ not covered
    = note: the matched value is of type `Opt`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.stderr
index 928e9068266cd..cbbd544f943ba 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.stderr
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.stderr
@@ -4,23 +4,30 @@ error[E0004]: non-exhaustive patterns: `(Some(&[]), Err(_))` not covered
 LL |     match (l1, l2) {
    |           ^^^^^^^^ pattern `(Some(&[]), Err(_))` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `(Option<&[T]>, Result<&[T], ()>)`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         (None, Ok(&[_, _, ..])) => "None, Ok(at least two elements)",
+LL +         (Some(&[]), Err(_)) => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `A(C)` not covered
   --> $DIR/non-exhaustive-match-nested.rs:15:11
    |
-LL | enum T { A(U), B }
-   | ------------------
-   | |        |
-   | |        not covered
-   | `T` defined here
-...
 LL |     match x {
    |           ^ pattern `A(C)` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `T` defined here
+  --> $DIR/non-exhaustive-match-nested.rs:1:10
+   |
+LL | enum T { A(U), B }
+   |      -   ^ not covered
    = note: the matched value is of type `T`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         T::B => { panic!("goodbye"); }
+LL +         A(C) => todo!()
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr
index 1ca0a33bf37d9..e7fa6a7814f85 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr
@@ -1,17 +1,19 @@
 error[E0004]: non-exhaustive patterns: `A` not covered
   --> $DIR/non-exhaustive-match.rs:7:11
    |
-LL | enum T { A, B }
-   | ---------------
-   | |        |
-   | |        not covered
-   | `T` defined here
-...
 LL |     match x { T::B => { } }
    |           ^ pattern `A` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `T` defined here
+  --> $DIR/non-exhaustive-match.rs:3:10
+   |
+LL | enum T { A, B }
+   |      -   ^ not covered
    = note: the matched value is of type `T`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL |     match x { T::B => { } A => todo!() }
+   |                           ++++++++++++
 
 error[E0004]: non-exhaustive patterns: `false` not covered
   --> $DIR/non-exhaustive-match.rs:8:11
@@ -19,8 +21,12 @@ error[E0004]: non-exhaustive patterns: `false` not covered
 LL |     match true {
    |           ^^^^ pattern `false` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `bool`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~       true => {}
+LL +       false => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `Some(_)` not covered
   --> $DIR/non-exhaustive-match.rs:11:11
@@ -28,13 +34,24 @@ error[E0004]: non-exhaustive patterns: `Some(_)` not covered
 LL |     match Some(10) {
    |           ^^^^^^^^ pattern `Some(_)` not covered
    |
-  ::: $SRC_DIR/core/src/option.rs:LL:COL
+note: `Option<i32>` defined here
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+   |
+LL | / pub enum Option<T> {
+LL | |     /// No value.
+LL | |     #[lang = "None"]
+LL | |     #[stable(feature = "rust1", since = "1.0.0")]
+...  |
+LL | |     Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+   | |     ^^^^ not covered
+LL | | }
+   | |_-
+   = note: the matched value is of type `Option<i32>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL |     Some(#[stable(feature = "rust1", since = "1.0.0")] T),
-   |     ---- not covered
+LL ~       None => {}
+LL +       Some(_) => todo!()
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
-   = note: the matched value is of type `Option<i32>`
 
 error[E0004]: non-exhaustive patterns: `(_, _, i32::MIN..=3_i32)` and `(_, _, 5_i32..=i32::MAX)` not covered
   --> $DIR/non-exhaustive-match.rs:14:11
@@ -42,8 +59,12 @@ error[E0004]: non-exhaustive patterns: `(_, _, i32::MIN..=3_i32)` and `(_, _, 5_
 LL |     match (2, 3, 4) {
    |           ^^^^^^^^^ patterns `(_, _, i32::MIN..=3_i32)` and `(_, _, 5_i32..=i32::MAX)` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `(i32, i32, i32)`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~       (_, _, 4) => {}
+LL +       (_, _, i32::MIN..=3_i32) | (_, _, 5_i32..=i32::MAX) => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `(A, A)` and `(B, B)` not covered
   --> $DIR/non-exhaustive-match.rs:18:11
@@ -51,23 +72,30 @@ error[E0004]: non-exhaustive patterns: `(A, A)` and `(B, B)` not covered
 LL |     match (T::A, T::A) {
    |           ^^^^^^^^^^^^ patterns `(A, A)` and `(B, B)` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `(T, T)`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~       (T::B, T::A) => {}
+LL +       (A, A) | (B, B) => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `B` not covered
   --> $DIR/non-exhaustive-match.rs:22:11
    |
-LL | enum T { A, B }
-   | ---------------
-   | |           |
-   | |           not covered
-   | `T` defined here
-...
 LL |     match T::A {
    |           ^^^^ pattern `B` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `T` defined here
+  --> $DIR/non-exhaustive-match.rs:3:13
+   |
+LL | enum T { A, B }
+   |      -      ^ not covered
    = note: the matched value is of type `T`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~       T::A => {}
+LL +       B => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `[]` not covered
   --> $DIR/non-exhaustive-match.rs:33:11
@@ -75,8 +103,12 @@ error[E0004]: non-exhaustive patterns: `[]` not covered
 LL |     match *vec {
    |           ^^^^ pattern `[]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `[Option<isize>]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         [None] => {}
+LL +         [] => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `[_, _, _, _, ..]` not covered
   --> $DIR/non-exhaustive-match.rs:46:11
@@ -84,8 +116,12 @@ error[E0004]: non-exhaustive patterns: `[_, _, _, _, ..]` not covered
 LL |     match *vec {
    |           ^^^^ pattern `[_, _, _, _, ..]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `[f32]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         [] => (),
+LL +         [_, _, _, _, ..] => todo!()
+   |
 
 error: aborting due to 8 previous errors
 
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr
index c9ed12aae5fbc..b0cfd631fb07e 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr
@@ -1,83 +1,102 @@
 error[E0004]: non-exhaustive patterns: `Foo { first: false, second: Some([_, _, _, _]) }` not covered
   --> $DIR/non-exhaustive-pattern-witness.rs:7:11
    |
-LL | / struct Foo {
-LL | |     first: bool,
-LL | |     second: Option<[usize; 4]>
-LL | | }
-   | |_- `Foo` defined here
-...
-LL |       match (Foo { first: true, second: None }) {
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo { first: false, second: Some([_, _, _, _]) }` not covered
+LL |     match (Foo { first: true, second: None }) {
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo { first: false, second: Some([_, _, _, _]) }` not covered
+   |
+note: `Foo` defined here
+  --> $DIR/non-exhaustive-pattern-witness.rs:1:8
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | struct Foo {
+   |        ^^^
    = note: the matched value is of type `Foo`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         Foo { first: false, second: Some([1, 2, 3, 4]) } => (),
+LL +         Foo { first: false, second: Some([_, _, _, _]) } => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `Red` not covered
   --> $DIR/non-exhaustive-pattern-witness.rs:23:11
    |
-LL | / enum Color {
-LL | |     Red,
-   | |     --- not covered
-LL | |     Green,
-LL | |     CustomRGBA { a: bool, r: u8, g: u8, b: u8 }
-LL | | }
-   | |_- `Color` defined here
-...
-LL |       match Color::Red {
-   |             ^^^^^^^^^^ pattern `Red` not covered
+LL |     match Color::Red {
+   |           ^^^^^^^^^^ pattern `Red` not covered
+   |
+note: `Color` defined here
+  --> $DIR/non-exhaustive-pattern-witness.rs:17:5
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | enum Color {
+   |      -----
+LL |     Red,
+   |     ^^^ not covered
    = note: the matched value is of type `Color`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         Color::Green => (),
+LL +         Red => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `East`, `South` and `West` not covered
   --> $DIR/non-exhaustive-pattern-witness.rs:35:11
    |
-LL | / enum Direction {
-LL | |     North, East, South, West
-   | |            ----  -----  ---- not covered
-   | |            |     |
-   | |            |     not covered
-   | |            not covered
-LL | | }
-   | |_- `Direction` defined here
-...
-LL |       match Direction::North {
-   |             ^^^^^^^^^^^^^^^^ patterns `East`, `South` and `West` not covered
+LL |     match Direction::North {
+   |           ^^^^^^^^^^^^^^^^ patterns `East`, `South` and `West` not covered
+   |
+note: `Direction` defined here
+  --> $DIR/non-exhaustive-pattern-witness.rs:31:12
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | enum Direction {
+   |      ---------
+LL |     North, East, South, West
+   |            ^^^^  ^^^^^  ^^^^ not covered
+   |            |     |
+   |            |     not covered
+   |            not covered
    = note: the matched value is of type `Direction`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~         Direction::North => (),
+LL +         East | South | West => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `Second`, `Third`, `Fourth` and 8 more not covered
   --> $DIR/non-exhaustive-pattern-witness.rs:46:11
    |
-LL | / enum ExcessiveEnum {
-LL | |     First, Second, Third, Fourth, Fifth, Sixth, Seventh, Eighth, Ninth, Tenth, Eleventh, Twelfth
-LL | | }
-   | |_- `ExcessiveEnum` defined here
-...
-LL |       match ExcessiveEnum::First {
-   |             ^^^^^^^^^^^^^^^^^^^^ patterns `Second`, `Third`, `Fourth` and 8 more not covered
+LL |     match ExcessiveEnum::First {
+   |           ^^^^^^^^^^^^^^^^^^^^ patterns `Second`, `Third`, `Fourth` and 8 more not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `ExcessiveEnum` defined here
+  --> $DIR/non-exhaustive-pattern-witness.rs:41:6
+   |
+LL | enum ExcessiveEnum {
+   |      ^^^^^^^^^^^^^
    = note: the matched value is of type `ExcessiveEnum`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
+   |
+LL ~         ExcessiveEnum::First => (),
+LL +         _ => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `CustomRGBA { a: true, .. }` not covered
   --> $DIR/non-exhaustive-pattern-witness.rs:54:11
    |
-LL | / enum Color {
-LL | |     Red,
-LL | |     Green,
-LL | |     CustomRGBA { a: bool, r: u8, g: u8, b: u8 }
-   | |     ---------- not covered
-LL | | }
-   | |_- `Color` defined here
-...
-LL |       match Color::Red {
-   |             ^^^^^^^^^^ pattern `CustomRGBA { a: true, .. }` not covered
+LL |     match Color::Red {
+   |           ^^^^^^^^^^ pattern `CustomRGBA { a: true, .. }` not covered
+   |
+note: `Color` defined here
+  --> $DIR/non-exhaustive-pattern-witness.rs:19:5
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | enum Color {
+   |      -----
+...
+LL |     CustomRGBA { a: bool, r: u8, g: u8, b: u8 }
+   |     ^^^^^^^^^^ not covered
    = note: the matched value is of type `Color`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         Color::CustomRGBA { a: false, r: _, g: _, b: _ } => (),
+LL +         CustomRGBA { a: true, .. } => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `[Second(true), Second(false)]` not covered
   --> $DIR/non-exhaustive-pattern-witness.rs:70:11
@@ -85,8 +104,12 @@ error[E0004]: non-exhaustive patterns: `[Second(true), Second(false)]` not cover
 LL |     match *x {
    |           ^^ pattern `[Second(true), Second(false)]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `[Enum]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         [_, _, ref tail @ .., _] => (),
+LL +         [Second(true), Second(false)] => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `((), false)` not covered
   --> $DIR/non-exhaustive-pattern-witness.rs:83:11
@@ -94,8 +117,12 @@ error[E0004]: non-exhaustive patterns: `((), false)` not covered
 LL |     match ((), false) {
    |           ^^^^^^^^^^^ pattern `((), false)` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `((), bool)`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         ((), true) => (),
+LL +         ((), false) => todo!()
+   |
 
 error: aborting due to 7 previous errors
 
diff --git a/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr b/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr
index e34770fb912e7..5d1e170ae6c2b 100644
--- a/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr
+++ b/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr
@@ -4,8 +4,12 @@ error[E0004]: non-exhaustive patterns: `&[false, _]` not covered
 LL |     match s2 {
    |           ^^ pattern `&[false, _]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[bool; 2]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         [true, .., true] => {}
+LL +         &[false, _] => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `&[false, ..]` not covered
   --> $DIR/slice-patterns-exhaustiveness.rs:12:11
@@ -13,8 +17,12 @@ error[E0004]: non-exhaustive patterns: `&[false, ..]` not covered
 LL |     match s3 {
    |           ^^ pattern `&[false, ..]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[bool; 3]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         [true, .., true] => {}
+LL +         &[false, ..] => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `&[false, ..]` not covered
   --> $DIR/slice-patterns-exhaustiveness.rs:16:11
@@ -22,8 +30,12 @@ error[E0004]: non-exhaustive patterns: `&[false, ..]` not covered
 LL |     match s10 {
    |           ^^^ pattern `&[false, ..]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[bool; 10]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         [true, .., true] => {}
+LL +         &[false, ..] => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `&[false, true]` not covered
   --> $DIR/slice-patterns-exhaustiveness.rs:25:11
@@ -31,8 +43,12 @@ error[E0004]: non-exhaustive patterns: `&[false, true]` not covered
 LL |     match s2 {
    |           ^^ pattern `&[false, true]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[bool; 2]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         [.., false] => {}
+LL +         &[false, true] => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `&[false, .., true]` not covered
   --> $DIR/slice-patterns-exhaustiveness.rs:30:11
@@ -40,8 +56,12 @@ error[E0004]: non-exhaustive patterns: `&[false, .., true]` not covered
 LL |     match s3 {
    |           ^^ pattern `&[false, .., true]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[bool; 3]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         [.., false] => {}
+LL +         &[false, .., true] => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `&[false, .., true]` not covered
   --> $DIR/slice-patterns-exhaustiveness.rs:35:11
@@ -49,8 +69,12 @@ error[E0004]: non-exhaustive patterns: `&[false, .., true]` not covered
 LL |     match s {
    |           ^ pattern `&[false, .., true]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[bool]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         [.., false] => {}
+LL +         &[false, .., true] => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
   --> $DIR/slice-patterns-exhaustiveness.rs:42:11
@@ -58,8 +82,12 @@ error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
 LL |     match s {
    |           ^ pattern `&[_, ..]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[bool]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         [] => {}
+LL +         &[_, ..] => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `&[_, _, ..]` not covered
   --> $DIR/slice-patterns-exhaustiveness.rs:46:11
@@ -67,8 +95,12 @@ error[E0004]: non-exhaustive patterns: `&[_, _, ..]` not covered
 LL |     match s {
    |           ^ pattern `&[_, _, ..]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[bool]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         [_] => {}
+LL +         &[_, _, ..] => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `&[false, ..]` not covered
   --> $DIR/slice-patterns-exhaustiveness.rs:51:11
@@ -76,8 +108,12 @@ error[E0004]: non-exhaustive patterns: `&[false, ..]` not covered
 LL |     match s {
    |           ^ pattern `&[false, ..]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[bool]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         [true, ..] => {}
+LL +         &[false, ..] => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `&[false, _, ..]` not covered
   --> $DIR/slice-patterns-exhaustiveness.rs:56:11
@@ -85,8 +121,12 @@ error[E0004]: non-exhaustive patterns: `&[false, _, ..]` not covered
 LL |     match s {
    |           ^ pattern `&[false, _, ..]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[bool]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         [true, ..] => {}
+LL +         &[false, _, ..] => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `&[_, .., false]` not covered
   --> $DIR/slice-patterns-exhaustiveness.rs:62:11
@@ -94,8 +134,12 @@ error[E0004]: non-exhaustive patterns: `&[_, .., false]` not covered
 LL |     match s {
    |           ^ pattern `&[_, .., false]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[bool]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         [.., true] => {}
+LL +         &[_, .., false] => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `&[_, _, .., true]` not covered
   --> $DIR/slice-patterns-exhaustiveness.rs:69:11
@@ -103,8 +147,12 @@ error[E0004]: non-exhaustive patterns: `&[_, _, .., true]` not covered
 LL |     match s {
    |           ^ pattern `&[_, _, .., true]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[bool]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         [.., false] => {}
+LL +         &[_, _, .., true] => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `&[true, _, .., _]` not covered
   --> $DIR/slice-patterns-exhaustiveness.rs:76:11
@@ -112,8 +160,12 @@ error[E0004]: non-exhaustive patterns: `&[true, _, .., _]` not covered
 LL |     match s {
    |           ^ pattern `&[true, _, .., _]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[bool]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         [false, .., false] => {}
+LL +         &[true, _, .., _] => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `&[]` and `&[_, _, ..]` not covered
   --> $DIR/slice-patterns-exhaustiveness.rs:85:11
@@ -121,8 +173,12 @@ error[E0004]: non-exhaustive patterns: `&[]` and `&[_, _, ..]` not covered
 LL |     match s {
    |           ^ patterns `&[]` and `&[_, _, ..]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[bool]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~         &[true] => {}
+LL +         &[] | &[_, _, ..] => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `&[]` and `&[_, _, ..]` not covered
   --> $DIR/slice-patterns-exhaustiveness.rs:89:11
@@ -130,8 +186,12 @@ error[E0004]: non-exhaustive patterns: `&[]` and `&[_, _, ..]` not covered
 LL |     match s {
    |           ^ patterns `&[]` and `&[_, _, ..]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[bool]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~         CONST => {}
+LL +         &[] | &[_, _, ..] => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `&[]` and `&[_, _, ..]` not covered
   --> $DIR/slice-patterns-exhaustiveness.rs:93:11
@@ -139,8 +199,12 @@ error[E0004]: non-exhaustive patterns: `&[]` and `&[_, _, ..]` not covered
 LL |     match s {
    |           ^ patterns `&[]` and `&[_, _, ..]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[bool]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~         &[false] => {}
+LL +         &[] | &[_, _, ..] => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `&[]` and `&[_, _, ..]` not covered
   --> $DIR/slice-patterns-exhaustiveness.rs:98:11
@@ -148,8 +212,12 @@ error[E0004]: non-exhaustive patterns: `&[]` and `&[_, _, ..]` not covered
 LL |     match s {
    |           ^ patterns `&[]` and `&[_, _, ..]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[bool]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~         CONST => {}
+LL +         &[] | &[_, _, ..] => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `&[_, _, ..]` not covered
   --> $DIR/slice-patterns-exhaustiveness.rs:103:11
@@ -157,8 +225,12 @@ error[E0004]: non-exhaustive patterns: `&[_, _, ..]` not covered
 LL |     match s {
    |           ^ pattern `&[_, _, ..]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[bool]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         CONST => {}
+LL +         &[_, _, ..] => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `&[false]` not covered
   --> $DIR/slice-patterns-exhaustiveness.rs:108:11
@@ -166,8 +238,12 @@ error[E0004]: non-exhaustive patterns: `&[false]` not covered
 LL |     match s {
    |           ^ pattern `&[false]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[bool]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         &[_, _, ..] => {}
+LL +         &[false] => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `&[false]` not covered
   --> $DIR/slice-patterns-exhaustiveness.rs:121:11
@@ -175,8 +251,12 @@ error[E0004]: non-exhaustive patterns: `&[false]` not covered
 LL |     match s1 {
    |           ^^ pattern `&[false]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[bool; 1]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         CONST1 => {}
+LL +         &[false] => todo!()
+   |
 
 error: aborting due to 20 previous errors
 
diff --git a/src/test/ui/pattern/usefulness/stable-gated-patterns.stderr b/src/test/ui/pattern/usefulness/stable-gated-patterns.stderr
index 9b42565ac7342..696ef9d8de936 100644
--- a/src/test/ui/pattern/usefulness/stable-gated-patterns.stderr
+++ b/src/test/ui/pattern/usefulness/stable-gated-patterns.stderr
@@ -4,13 +4,25 @@ error[E0004]: non-exhaustive patterns: `Stable2` and `_` not covered
 LL |     match Foo::Stable {
    |           ^^^^^^^^^^^ patterns `Stable2` and `_` not covered
    |
-  ::: $DIR/auxiliary/unstable.rs:9:5
+note: `Foo` defined here
+  --> $DIR/auxiliary/unstable.rs:9:5
    |
-LL |     Stable2,
-   |     ------- not covered
-   |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | / pub enum Foo {
+LL | |     #[stable(feature = "stable_test_feature", since = "1.0.0")]
+LL | |     Stable,
+LL | |     #[stable(feature = "stable_test_feature", since = "1.0.0")]
+LL | |     Stable2,
+   | |     ^^^^^^^ not covered
+LL | |     #[unstable(feature = "unstable_test_feature", issue = "none")]
+LL | |     Unstable,
+LL | | }
+   | |_-
    = note: the matched value is of type `Foo`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~         Foo::Stable => {}
+LL +         Stable2 | _ => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/stable-gated-patterns.rs:13:11
@@ -18,8 +30,23 @@ error[E0004]: non-exhaustive patterns: `_` not covered
 LL |     match Foo::Stable {
    |           ^^^^^^^^^^^ pattern `_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `Foo` defined here
+  --> $DIR/auxiliary/unstable.rs:5:1
+   |
+LL | / pub enum Foo {
+LL | |     #[stable(feature = "stable_test_feature", since = "1.0.0")]
+LL | |     Stable,
+LL | |     #[stable(feature = "stable_test_feature", since = "1.0.0")]
+...  |
+LL | |     Unstable,
+LL | | }
+   | |_^
    = note: the matched value is of type `Foo`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         Foo::Stable2 => {}
+LL +         _ => todo!()
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/pattern/usefulness/struct-like-enum-nonexhaustive.stderr b/src/test/ui/pattern/usefulness/struct-like-enum-nonexhaustive.stderr
index 23ff6c626f759..6127fad3f7d54 100644
--- a/src/test/ui/pattern/usefulness/struct-like-enum-nonexhaustive.stderr
+++ b/src/test/ui/pattern/usefulness/struct-like-enum-nonexhaustive.stderr
@@ -1,18 +1,22 @@
 error[E0004]: non-exhaustive patterns: `B { x: Some(_) }` not covered
   --> $DIR/struct-like-enum-nonexhaustive.rs:8:11
    |
-LL | / enum A {
-LL | |     B { x: Option<isize> },
-   | |     - not covered
-LL | |     C
-LL | | }
-   | |_- `A` defined here
-...
-LL |       match x {
-   |             ^ pattern `B { x: Some(_) }` not covered
+LL |     match x {
+   |           ^ pattern `B { x: Some(_) }` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `A` defined here
+  --> $DIR/struct-like-enum-nonexhaustive.rs:2:5
+   |
+LL | enum A {
+   |      -
+LL |     B { x: Option<isize> },
+   |     ^ not covered
    = note: the matched value is of type `A`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         A::B { x: None } => {}
+LL +         B { x: Some(_) } => todo!()
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/pattern/usefulness/tuple-struct-nonexhaustive.stderr b/src/test/ui/pattern/usefulness/tuple-struct-nonexhaustive.stderr
index ca8f67f3c8df2..fc0430d06fa1c 100644
--- a/src/test/ui/pattern/usefulness/tuple-struct-nonexhaustive.stderr
+++ b/src/test/ui/pattern/usefulness/tuple-struct-nonexhaustive.stderr
@@ -1,14 +1,20 @@
 error[E0004]: non-exhaustive patterns: `Foo(_, _)` not covered
   --> $DIR/tuple-struct-nonexhaustive.rs:5:11
    |
-LL | struct Foo(isize, isize);
-   | ------------------------- `Foo` defined here
-...
 LL |     match x {
    |           ^ pattern `Foo(_, _)` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `Foo` defined here
+  --> $DIR/tuple-struct-nonexhaustive.rs:1:8
+   |
+LL | struct Foo(isize, isize);
+   |        ^^^
    = note: the matched value is of type `Foo`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         Foo(2, b) => println!("{}", b)
+LL +         Foo(_, _) => todo!()
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/pattern/usefulness/type_polymorphic_byte_str_literals.stderr b/src/test/ui/pattern/usefulness/type_polymorphic_byte_str_literals.stderr
index 6ce53a4f21ea2..acae605dae3a8 100644
--- a/src/test/ui/pattern/usefulness/type_polymorphic_byte_str_literals.stderr
+++ b/src/test/ui/pattern/usefulness/type_polymorphic_byte_str_literals.stderr
@@ -4,8 +4,12 @@ error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
 LL |     match data {
    |           ^^^^ pattern `&[_, ..]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[u8]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         b"" => 1,
+LL ~         &[_, ..] => todo!(),
+   |
 
 error[E0004]: non-exhaustive patterns: `&[]`, `&[_]`, `&[_, _]` and 1 more not covered
   --> $DIR/type_polymorphic_byte_str_literals.rs:23:11
@@ -13,8 +17,12 @@ error[E0004]: non-exhaustive patterns: `&[]`, `&[_]`, `&[_, _]` and 1 more not c
 LL |     match data {
    |           ^^^^ patterns `&[]`, `&[_]`, `&[_, _]` and 1 more not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[u8]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
+   |
+LL ~         [_, _, _] => 1,
+LL ~         _ => todo!(),
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/pattern/usefulness/unstable-gated-patterns.stderr b/src/test/ui/pattern/usefulness/unstable-gated-patterns.stderr
index f9c0196b76598..8487c9725da83 100644
--- a/src/test/ui/pattern/usefulness/unstable-gated-patterns.stderr
+++ b/src/test/ui/pattern/usefulness/unstable-gated-patterns.stderr
@@ -4,13 +4,24 @@ error[E0004]: non-exhaustive patterns: `Unstable` not covered
 LL |     match Foo::Stable {
    |           ^^^^^^^^^^^ pattern `Unstable` not covered
    |
-  ::: $DIR/auxiliary/unstable.rs:11:5
+note: `Foo` defined here
+  --> $DIR/auxiliary/unstable.rs:11:5
    |
-LL |     Unstable,
-   |     -------- not covered
-   |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | / pub enum Foo {
+LL | |     #[stable(feature = "stable_test_feature", since = "1.0.0")]
+LL | |     Stable,
+LL | |     #[stable(feature = "stable_test_feature", since = "1.0.0")]
+...  |
+LL | |     Unstable,
+   | |     ^^^^^^^^ not covered
+LL | | }
+   | |_-
    = note: the matched value is of type `Foo`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         Foo::Stable2 => {}
+LL +         Unstable => todo!()
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr
index f904a0ecd11cd..ded3cf3ad1d44 100644
--- a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr
+++ b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr
@@ -4,13 +4,20 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered
 LL |     let Ok(x) = res;
    |         ^^^^^ pattern `Err(_)` not covered
    |
-  ::: $SRC_DIR/core/src/result.rs:LL:COL
-   |
-LL |     Err(#[stable(feature = "rust1", since = "1.0.0")] E),
-   |     --- not covered
-   |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+note: `Result<u32, &R>` defined here
+  --> $SRC_DIR/core/src/result.rs:LL:COL
+   |
+LL | / pub enum Result<T, E> {
+LL | |     /// Contains the success value
+LL | |     #[lang = "Ok"]
+LL | |     #[stable(feature = "rust1", since = "1.0.0")]
+...  |
+LL | |     Err(#[stable(feature = "rust1", since = "1.0.0")] E),
+   | |     ^^^ not covered
+LL | | }
+   | |_-
    = note: the matched value is of type `Result<u32, &R>`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
diff --git a/src/test/ui/rfc-2005-default-binding-mode/slice.stderr b/src/test/ui/rfc-2005-default-binding-mode/slice.stderr
index 18d8f5481c9fb..60c1f5420f62c 100644
--- a/src/test/ui/rfc-2005-default-binding-mode/slice.stderr
+++ b/src/test/ui/rfc-2005-default-binding-mode/slice.stderr
@@ -4,8 +4,12 @@ error[E0004]: non-exhaustive patterns: `&[]` not covered
 LL |     match sl {
    |           ^^ pattern `&[]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[u8]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         [first, remainder @ ..] => {}
+LL ~         &[] => todo!(),
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rfc-2008-non-exhaustive/enum.stderr b/src/test/ui/rfc-2008-non-exhaustive/enum.stderr
index cd9ded81e6a09..5ef078c20057d 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/enum.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/enum.stderr
@@ -4,8 +4,18 @@ error[E0004]: non-exhaustive patterns: type `EmptyNonExhaustiveEnum` is non-empt
 LL |     match x {}
    |           ^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `EmptyNonExhaustiveEnum` defined here
+  --> $DIR/auxiliary/enums.rs:18:1
+   |
+LL | pub enum EmptyNonExhaustiveEnum {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: the matched value is of type `EmptyNonExhaustiveEnum`, which is marked as non-exhaustive
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match x {
+LL +         _ => todo!(),
+LL ~     }
+   |
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/enum.rs:16:11
@@ -13,8 +23,21 @@ error[E0004]: non-exhaustive patterns: `_` not covered
 LL |     match enum_unit {
    |           ^^^^^^^^^ pattern `_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `NonExhaustiveEnum` defined here
+  --> $DIR/auxiliary/enums.rs:4:1
+   |
+LL | / pub enum NonExhaustiveEnum {
+LL | |     Unit,
+LL | |     Tuple(u32),
+LL | |     Struct { field: u32 },
+LL | | }
+   | |_^
    = note: the matched value is of type `NonExhaustiveEnum`, which is marked as non-exhaustive
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         NonExhaustiveEnum::Struct { .. } => "third",
+LL +         _ => todo!()
+   |
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/enum.rs:23:11
@@ -22,8 +45,22 @@ error[E0004]: non-exhaustive patterns: `_` not covered
 LL |     match enum_unit {};
    |           ^^^^^^^^^ pattern `_` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `NonExhaustiveEnum` defined here
+  --> $DIR/auxiliary/enums.rs:4:1
+   |
+LL | / pub enum NonExhaustiveEnum {
+LL | |     Unit,
+LL | |     Tuple(u32),
+LL | |     Struct { field: u32 },
+LL | | }
+   | |_^
    = note: the matched value is of type `NonExhaustiveEnum`, which is marked as non-exhaustive
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~     match enum_unit {
+LL +         _ => todo!(),
+LL ~     };
+   |
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr b/src/test/ui/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr
index 966f3a2e41485..1f20904483fe7 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr
@@ -13,46 +13,56 @@ LL | #![deny(unreachable_patterns)]
 error[E0004]: non-exhaustive patterns: `Unit`, `Tuple(_)` and `Struct { .. }` not covered
   --> $DIR/enum_same_crate_empty_match.rs:33:11
    |
-LL | / pub enum NonExhaustiveEnum {
-LL | |     Unit,
-   | |     ---- not covered
-LL | |
-LL | |     Tuple(u32),
-   | |     ----- not covered
-LL | |
-LL | |     Struct { field: u32 }
-   | |     ------ not covered
-LL | |
-LL | | }
-   | |_- `NonExhaustiveEnum` defined here
-...
-LL |       match NonExhaustiveEnum::Unit {}
-   |             ^^^^^^^^^^^^^^^^^^^^^^^ patterns `Unit`, `Tuple(_)` and `Struct { .. }` not covered
-   |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL |     match NonExhaustiveEnum::Unit {}
+   |           ^^^^^^^^^^^^^^^^^^^^^^^ patterns `Unit`, `Tuple(_)` and `Struct { .. }` not covered
+   |
+note: `NonExhaustiveEnum` defined here
+  --> $DIR/enum_same_crate_empty_match.rs:5:5
+   |
+LL | pub enum NonExhaustiveEnum {
+   |          -----------------
+LL |     Unit,
+   |     ^^^^ not covered
+LL |
+LL |     Tuple(u32),
+   |     ^^^^^ not covered
+LL |
+LL |     Struct { field: u32 }
+   |     ^^^^^^ not covered
    = note: the matched value is of type `NonExhaustiveEnum`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~     match NonExhaustiveEnum::Unit {
+LL +         Unit | Tuple(_) | Struct { .. } => todo!(),
+LL +     }
+   |
 
 error[E0004]: non-exhaustive patterns: `Unit`, `Tuple(_)` and `Struct { .. }` not covered
   --> $DIR/enum_same_crate_empty_match.rs:35:11
    |
-LL | / pub enum NormalEnum {
-LL | |     Unit,
-   | |     ---- not covered
-LL | |
-LL | |     Tuple(u32),
-   | |     ----- not covered
-LL | |
-LL | |     Struct { field: u32 }
-   | |     ------ not covered
-LL | |
-LL | | }
-   | |_- `NormalEnum` defined here
-...
-LL |       match NormalEnum::Unit {}
-   |             ^^^^^^^^^^^^^^^^ patterns `Unit`, `Tuple(_)` and `Struct { .. }` not covered
-   |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL |     match NormalEnum::Unit {}
+   |           ^^^^^^^^^^^^^^^^ patterns `Unit`, `Tuple(_)` and `Struct { .. }` not covered
+   |
+note: `NormalEnum` defined here
+  --> $DIR/enum_same_crate_empty_match.rs:14:5
+   |
+LL | pub enum NormalEnum {
+   |          ----------
+LL |     Unit,
+   |     ^^^^ not covered
+LL |
+LL |     Tuple(u32),
+   |     ^^^^^ not covered
+LL |
+LL |     Struct { field: u32 }
+   |     ^^^^^^ not covered
    = note: the matched value is of type `NormalEnum`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~     match NormalEnum::Unit {
+LL +         Unit | Tuple(_) | Struct { .. } => todo!(),
+LL +     }
+   |
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.stderr
index c461302a366bd..2dc4eabb8630a 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.stderr
@@ -4,8 +4,18 @@ error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedEnum` is non-emp
 LL |     match x {}
    |           ^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `IndirectUninhabitedEnum` defined here
+  --> $DIR/auxiliary/uninhabited.rs:26:1
+   |
+LL | pub struct IndirectUninhabitedEnum(UninhabitedEnum);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: the matched value is of type `IndirectUninhabitedEnum`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match x {
+LL +         _ => todo!(),
+LL ~     }
+   |
 
 error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedStruct` is non-empty
   --> $DIR/indirect_match.rs:23:11
@@ -13,8 +23,18 @@ error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedStruct` is non-e
 LL |     match x {}
    |           ^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `IndirectUninhabitedStruct` defined here
+  --> $DIR/auxiliary/uninhabited.rs:28:1
+   |
+LL | pub struct IndirectUninhabitedStruct(UninhabitedStruct);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: the matched value is of type `IndirectUninhabitedStruct`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match x {
+LL +         _ => todo!(),
+LL ~     }
+   |
 
 error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedTupleStruct` is non-empty
   --> $DIR/indirect_match.rs:27:11
@@ -22,8 +42,18 @@ error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedTupleStruct` is
 LL |     match x {}
    |           ^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `IndirectUninhabitedTupleStruct` defined here
+  --> $DIR/auxiliary/uninhabited.rs:30:1
+   |
+LL | pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: the matched value is of type `IndirectUninhabitedTupleStruct`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match x {
+LL +         _ => todo!(),
+LL ~     }
+   |
 
 error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedVariants` is non-empty
   --> $DIR/indirect_match.rs:33:11
@@ -31,8 +61,18 @@ error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedVariants` is non
 LL |     match x {}
    |           ^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `IndirectUninhabitedVariants` defined here
+  --> $DIR/auxiliary/uninhabited.rs:32:1
+   |
+LL | pub struct IndirectUninhabitedVariants(UninhabitedVariants);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: the matched value is of type `IndirectUninhabitedVariants`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match x {
+LL +         _ => todo!(),
+LL ~     }
+   |
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.stderr
index 42bf67c0a45df..c121905414035 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.stderr
@@ -1,50 +1,78 @@
 error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedEnum` is non-empty
   --> $DIR/indirect_match_same_crate.rs:34:11
    |
-LL | pub struct IndirectUninhabitedEnum(UninhabitedEnum);
-   | ---------------------------------------------------- `IndirectUninhabitedEnum` defined here
-...
 LL |     match x {}
    |           ^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `IndirectUninhabitedEnum` defined here
+  --> $DIR/indirect_match_same_crate.rs:20:12
+   |
+LL | pub struct IndirectUninhabitedEnum(UninhabitedEnum);
+   |            ^^^^^^^^^^^^^^^^^^^^^^^
    = note: the matched value is of type `IndirectUninhabitedEnum`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match x {
+LL +         _ => todo!(),
+LL ~     }
+   |
 
 error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedStruct` is non-empty
   --> $DIR/indirect_match_same_crate.rs:38:11
    |
-LL | pub struct IndirectUninhabitedStruct(UninhabitedStruct);
-   | -------------------------------------------------------- `IndirectUninhabitedStruct` defined here
-...
 LL |     match x {}
    |           ^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `IndirectUninhabitedStruct` defined here
+  --> $DIR/indirect_match_same_crate.rs:22:12
+   |
+LL | pub struct IndirectUninhabitedStruct(UninhabitedStruct);
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: the matched value is of type `IndirectUninhabitedStruct`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match x {
+LL +         _ => todo!(),
+LL ~     }
+   |
 
 error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedTupleStruct` is non-empty
   --> $DIR/indirect_match_same_crate.rs:42:11
    |
-LL | pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct);
-   | ------------------------------------------------------------------ `IndirectUninhabitedTupleStruct` defined here
-...
 LL |     match x {}
    |           ^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `IndirectUninhabitedTupleStruct` defined here
+  --> $DIR/indirect_match_same_crate.rs:24:12
+   |
+LL | pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct);
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: the matched value is of type `IndirectUninhabitedTupleStruct`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match x {
+LL +         _ => todo!(),
+LL ~     }
+   |
 
 error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedVariants` is non-empty
   --> $DIR/indirect_match_same_crate.rs:48:11
    |
-LL | pub struct IndirectUninhabitedVariants(UninhabitedVariants);
-   | ------------------------------------------------------------ `IndirectUninhabitedVariants` defined here
-...
 LL |     match x {}
    |           ^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `IndirectUninhabitedVariants` defined here
+  --> $DIR/indirect_match_same_crate.rs:26:12
+   |
+LL | pub struct IndirectUninhabitedVariants(UninhabitedVariants);
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: the matched value is of type `IndirectUninhabitedVariants`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match x {
+LL +         _ => todo!(),
+LL ~     }
+   |
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr
index c397158c02495..f0cb13de3f799 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr
@@ -4,8 +4,18 @@ error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedEnum` is non-emp
 LL |     match x {}
    |           ^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `IndirectUninhabitedEnum` defined here
+  --> $DIR/auxiliary/uninhabited.rs:26:1
+   |
+LL | pub struct IndirectUninhabitedEnum(UninhabitedEnum);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: the matched value is of type `IndirectUninhabitedEnum`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match x {
+LL +         _ => todo!(),
+LL ~     }
+   |
 
 error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedStruct` is non-empty
   --> $DIR/indirect_match_with_exhaustive_patterns.rs:27:11
@@ -13,8 +23,18 @@ error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedStruct` is non-e
 LL |     match x {}
    |           ^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `IndirectUninhabitedStruct` defined here
+  --> $DIR/auxiliary/uninhabited.rs:28:1
+   |
+LL | pub struct IndirectUninhabitedStruct(UninhabitedStruct);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: the matched value is of type `IndirectUninhabitedStruct`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match x {
+LL +         _ => todo!(),
+LL ~     }
+   |
 
 error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedTupleStruct` is non-empty
   --> $DIR/indirect_match_with_exhaustive_patterns.rs:31:11
@@ -22,8 +42,18 @@ error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedTupleStruct` is
 LL |     match x {}
    |           ^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `IndirectUninhabitedTupleStruct` defined here
+  --> $DIR/auxiliary/uninhabited.rs:30:1
+   |
+LL | pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: the matched value is of type `IndirectUninhabitedTupleStruct`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match x {
+LL +         _ => todo!(),
+LL ~     }
+   |
 
 error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedVariants` is non-empty
   --> $DIR/indirect_match_with_exhaustive_patterns.rs:37:11
@@ -31,8 +61,18 @@ error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedVariants` is non
 LL |     match x {}
    |           ^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `IndirectUninhabitedVariants` defined here
+  --> $DIR/auxiliary/uninhabited.rs:32:1
+   |
+LL | pub struct IndirectUninhabitedVariants(UninhabitedVariants);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: the matched value is of type `IndirectUninhabitedVariants`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match x {
+LL +         _ => todo!(),
+LL ~     }
+   |
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr
index d21a94a0d6498..49febd9241dc6 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr
@@ -4,8 +4,19 @@ error[E0004]: non-exhaustive patterns: type `UninhabitedEnum` is non-empty
 LL |     match x {}
    |           ^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `UninhabitedEnum` defined here
+  --> $DIR/auxiliary/uninhabited.rs:5:1
+   |
+LL | / pub enum UninhabitedEnum {
+LL | | }
+   | |_^
    = note: the matched value is of type `UninhabitedEnum`, which is marked as non-exhaustive
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match x {
+LL +         _ => todo!(),
+LL ~     }
+   |
 
 error[E0004]: non-exhaustive patterns: type `UninhabitedStruct` is non-empty
   --> $DIR/match.rs:23:11
@@ -13,8 +24,20 @@ error[E0004]: non-exhaustive patterns: type `UninhabitedStruct` is non-empty
 LL |     match x {}
    |           ^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `UninhabitedStruct` defined here
+  --> $DIR/auxiliary/uninhabited.rs:9:1
+   |
+LL | / pub struct UninhabitedStruct {
+LL | |     _priv: !,
+LL | | }
+   | |_^
    = note: the matched value is of type `UninhabitedStruct`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match x {
+LL +         _ => todo!(),
+LL ~     }
+   |
 
 error[E0004]: non-exhaustive patterns: type `UninhabitedTupleStruct` is non-empty
   --> $DIR/match.rs:27:11
@@ -22,8 +45,18 @@ error[E0004]: non-exhaustive patterns: type `UninhabitedTupleStruct` is non-empt
 LL |     match x {}
    |           ^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `UninhabitedTupleStruct` defined here
+  --> $DIR/auxiliary/uninhabited.rs:14:1
+   |
+LL | pub struct UninhabitedTupleStruct(!);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: the matched value is of type `UninhabitedTupleStruct`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match x {
+LL +         _ => todo!(),
+LL ~     }
+   |
 
 error[E0004]: non-exhaustive patterns: `Tuple(_)` and `Struct { .. }` not covered
   --> $DIR/match.rs:31:11
@@ -31,15 +64,23 @@ error[E0004]: non-exhaustive patterns: `Tuple(_)` and `Struct { .. }` not covere
 LL |     match x {}
    |           ^ patterns `Tuple(_)` and `Struct { .. }` not covered
    |
-  ::: $DIR/auxiliary/uninhabited.rs:17:23
+note: `UninhabitedVariants` defined here
+  --> $DIR/auxiliary/uninhabited.rs:17:23
    |
-LL |     #[non_exhaustive] Tuple(!),
-   |                       ----- not covered
-LL |     #[non_exhaustive] Struct { x: ! }
-   |                       ------ not covered
-   |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | / pub enum UninhabitedVariants {
+LL | |     #[non_exhaustive] Tuple(!),
+   | |                       ^^^^^ not covered
+LL | |     #[non_exhaustive] Struct { x: ! }
+   | |                       ^^^^^^ not covered
+LL | | }
+   | |_-
    = note: the matched value is of type `UninhabitedVariants`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~     match x {
+LL +         Tuple(_) | Struct { .. } => todo!(),
+LL ~     }
+   |
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr
index e4d0c7022f3b4..c89c70ae6cc1f 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr
@@ -1,45 +1,63 @@
 error[E0004]: non-exhaustive patterns: type `UninhabitedStruct` is non-empty
   --> $DIR/match_same_crate.rs:30:11
    |
-LL | / pub struct UninhabitedStruct {
-LL | |     _priv: !,
-LL | | }
-   | |_- `UninhabitedStruct` defined here
-...
-LL |       match x {}
-   |             ^
-   |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL |     match x {}
+   |           ^
+   |
+note: `UninhabitedStruct` defined here
+  --> $DIR/match_same_crate.rs:8:12
+   |
+LL | pub struct UninhabitedStruct {
+   |            ^^^^^^^^^^^^^^^^^
    = note: the matched value is of type `UninhabitedStruct`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match x {
+LL +         _ => todo!(),
+LL ~     }
+   |
 
 error[E0004]: non-exhaustive patterns: type `UninhabitedTupleStruct` is non-empty
   --> $DIR/match_same_crate.rs:34:11
    |
-LL | pub struct UninhabitedTupleStruct(!);
-   | ------------------------------------- `UninhabitedTupleStruct` defined here
-...
 LL |     match x {}
    |           ^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `UninhabitedTupleStruct` defined here
+  --> $DIR/match_same_crate.rs:13:12
+   |
+LL | pub struct UninhabitedTupleStruct(!);
+   |            ^^^^^^^^^^^^^^^^^^^^^^
    = note: the matched value is of type `UninhabitedTupleStruct`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match x {
+LL +         _ => todo!(),
+LL ~     }
+   |
 
 error[E0004]: non-exhaustive patterns: `Tuple(_)` and `Struct { .. }` not covered
   --> $DIR/match_same_crate.rs:38:11
    |
-LL | / pub enum UninhabitedVariants {
-LL | |     #[non_exhaustive] Tuple(!),
-   | |                       ----- not covered
-LL | |     #[non_exhaustive] Struct { x: ! }
-   | |                       ------ not covered
-LL | | }
-   | |_- `UninhabitedVariants` defined here
-...
-LL |       match x {}
-   |             ^ patterns `Tuple(_)` and `Struct { .. }` not covered
-   |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL |     match x {}
+   |           ^ patterns `Tuple(_)` and `Struct { .. }` not covered
+   |
+note: `UninhabitedVariants` defined here
+  --> $DIR/match_same_crate.rs:16:23
+   |
+LL | pub enum UninhabitedVariants {
+   |          -------------------
+LL |     #[non_exhaustive] Tuple(!),
+   |                       ^^^^^ not covered
+LL |     #[non_exhaustive] Struct { x: ! }
+   |                       ^^^^^^ not covered
    = note: the matched value is of type `UninhabitedVariants`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~     match x {
+LL +         Tuple(_) | Struct { .. } => todo!(),
+LL ~     }
+   |
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr
index cc3dc6c29b904..e18c2678d323c 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr
@@ -4,8 +4,19 @@ error[E0004]: non-exhaustive patterns: type `UninhabitedEnum` is non-empty
 LL |     match x {}
    |           ^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `UninhabitedEnum` defined here
+  --> $DIR/auxiliary/uninhabited.rs:5:1
+   |
+LL | / pub enum UninhabitedEnum {
+LL | | }
+   | |_^
    = note: the matched value is of type `UninhabitedEnum`, which is marked as non-exhaustive
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match x {
+LL +         _ => todo!(),
+LL ~     }
+   |
 
 error[E0004]: non-exhaustive patterns: type `UninhabitedStruct` is non-empty
   --> $DIR/match_with_exhaustive_patterns.rs:26:11
@@ -13,8 +24,20 @@ error[E0004]: non-exhaustive patterns: type `UninhabitedStruct` is non-empty
 LL |     match x {}
    |           ^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `UninhabitedStruct` defined here
+  --> $DIR/auxiliary/uninhabited.rs:9:1
+   |
+LL | / pub struct UninhabitedStruct {
+LL | |     _priv: !,
+LL | | }
+   | |_^
    = note: the matched value is of type `UninhabitedStruct`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match x {
+LL +         _ => todo!(),
+LL ~     }
+   |
 
 error[E0004]: non-exhaustive patterns: type `UninhabitedTupleStruct` is non-empty
   --> $DIR/match_with_exhaustive_patterns.rs:30:11
@@ -22,8 +45,18 @@ error[E0004]: non-exhaustive patterns: type `UninhabitedTupleStruct` is non-empt
 LL |     match x {}
    |           ^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `UninhabitedTupleStruct` defined here
+  --> $DIR/auxiliary/uninhabited.rs:14:1
+   |
+LL | pub struct UninhabitedTupleStruct(!);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: the matched value is of type `UninhabitedTupleStruct`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match x {
+LL +         _ => todo!(),
+LL ~     }
+   |
 
 error[E0004]: non-exhaustive patterns: `Tuple(_)` and `Struct { .. }` not covered
   --> $DIR/match_with_exhaustive_patterns.rs:34:11
@@ -31,15 +64,23 @@ error[E0004]: non-exhaustive patterns: `Tuple(_)` and `Struct { .. }` not covere
 LL |     match x {}
    |           ^ patterns `Tuple(_)` and `Struct { .. }` not covered
    |
-  ::: $DIR/auxiliary/uninhabited.rs:17:23
+note: `UninhabitedVariants` defined here
+  --> $DIR/auxiliary/uninhabited.rs:17:23
    |
-LL |     #[non_exhaustive] Tuple(!),
-   |                       ----- not covered
-LL |     #[non_exhaustive] Struct { x: ! }
-   |                       ------ not covered
-   |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+LL | / pub enum UninhabitedVariants {
+LL | |     #[non_exhaustive] Tuple(!),
+   | |                       ^^^^^ not covered
+LL | |     #[non_exhaustive] Struct { x: ! }
+   | |                       ^^^^^^ not covered
+LL | | }
+   | |_-
    = note: the matched value is of type `UninhabitedVariants`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~     match x {
+LL +         Tuple(_) | Struct { .. } => todo!(),
+LL ~     }
+   |
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/uninhabited/uninhabited-irrefutable.stderr b/src/test/ui/uninhabited/uninhabited-irrefutable.stderr
index 3cb9955674800..ad19c34a40a11 100644
--- a/src/test/ui/uninhabited/uninhabited-irrefutable.stderr
+++ b/src/test/ui/uninhabited/uninhabited-irrefutable.stderr
@@ -1,20 +1,18 @@
 error[E0005]: refutable pattern in local binding: `A(_)` not covered
   --> $DIR/uninhabited-irrefutable.rs:27:9
    |
-LL | / enum Foo {
-LL | |     A(foo::SecretlyEmpty),
-   | |     - not covered
-LL | |     B(foo::NotSoSecretlyEmpty),
-LL | |     C(NotSoSecretlyEmpty),
-LL | |     D(u32),
-LL | | }
-   | |_- `Foo` defined here
-...
-LL |       let Foo::D(_y) = x;
-   |           ^^^^^^^^^^ pattern `A(_)` not covered
+LL |     let Foo::D(_y) = x;
+   |         ^^^^^^^^^^ pattern `A(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+note: `Foo` defined here
+  --> $DIR/uninhabited-irrefutable.rs:19:5
+   |
+LL | enum Foo {
+   |      ---
+LL |     A(foo::SecretlyEmpty),
+   |     ^ not covered
    = note: the matched value is of type `Foo`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
diff --git a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr
index b92ceb479bd3b..d90075d82f47b 100644
--- a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr
+++ b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr
@@ -4,26 +4,44 @@ error[E0004]: non-exhaustive patterns: `Err(_)` not covered
 LL |     let _ = match x {
    |                   ^ pattern `Err(_)` not covered
    |
-  ::: $SRC_DIR/core/src/result.rs:LL:COL
+note: `Result<u32, &Void>` defined here
+  --> $SRC_DIR/core/src/result.rs:LL:COL
+   |
+LL | / pub enum Result<T, E> {
+LL | |     /// Contains the success value
+LL | |     #[lang = "Ok"]
+LL | |     #[stable(feature = "rust1", since = "1.0.0")]
+...  |
+LL | |     Err(#[stable(feature = "rust1", since = "1.0.0")] E),
+   | |     ^^^ not covered
+LL | | }
+   | |_-
+   = note: the matched value is of type `Result<u32, &Void>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL |     Err(#[stable(feature = "rust1", since = "1.0.0")] E),
-   |     --- not covered
+LL ~         Ok(n) => n,
+LL ~         Err(_) => todo!(),
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
-   = note: the matched value is of type `Result<u32, &Void>`
 
 error[E0004]: non-exhaustive patterns: type `&Void` is non-empty
   --> $DIR/uninhabited-matches-feature-gated.rs:15:19
    |
-LL | enum Void {}
-   | ------------ `Void` defined here
-...
 LL |     let _ = match x {};
    |                   ^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+note: `Void` defined here
+  --> $DIR/uninhabited-matches-feature-gated.rs:2:6
+   |
+LL | enum Void {}
+   |      ^^^^
    = note: the matched value is of type `&Void`
    = note: references are always considered inhabited
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     let _ = match x {
+LL +         _ => todo!(),
+LL ~     };
+   |
 
 error[E0004]: non-exhaustive patterns: type `(Void,)` is non-empty
   --> $DIR/uninhabited-matches-feature-gated.rs:18:19
@@ -31,8 +49,13 @@ error[E0004]: non-exhaustive patterns: type `(Void,)` is non-empty
 LL |     let _ = match x {};
    |                   ^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `(Void,)`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     let _ = match x {
+LL +         _ => todo!(),
+LL ~     };
+   |
 
 error[E0004]: non-exhaustive patterns: type `[Void; 1]` is non-empty
   --> $DIR/uninhabited-matches-feature-gated.rs:21:19
@@ -40,8 +63,13 @@ error[E0004]: non-exhaustive patterns: type `[Void; 1]` is non-empty
 LL |     let _ = match x {};
    |                   ^
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `[Void; 1]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     let _ = match x {
+LL +         _ => todo!(),
+LL ~     };
+   |
 
 error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
   --> $DIR/uninhabited-matches-feature-gated.rs:24:19
@@ -49,8 +77,12 @@ error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
 LL |     let _ = match x {
    |                   ^ pattern `&[_, ..]` not covered
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `&[Void]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         &[] => (),
+LL ~         &[_, ..] => todo!(),
+   |
 
 error[E0004]: non-exhaustive patterns: `Err(_)` not covered
   --> $DIR/uninhabited-matches-feature-gated.rs:32:19
@@ -58,13 +90,24 @@ error[E0004]: non-exhaustive patterns: `Err(_)` not covered
 LL |     let _ = match x {
    |                   ^ pattern `Err(_)` not covered
    |
-  ::: $SRC_DIR/core/src/result.rs:LL:COL
+note: `Result<u32, Void>` defined here
+  --> $SRC_DIR/core/src/result.rs:LL:COL
+   |
+LL | / pub enum Result<T, E> {
+LL | |     /// Contains the success value
+LL | |     #[lang = "Ok"]
+LL | |     #[stable(feature = "rust1", since = "1.0.0")]
+...  |
+LL | |     Err(#[stable(feature = "rust1", since = "1.0.0")] E),
+   | |     ^^^ not covered
+LL | | }
+   | |_-
+   = note: the matched value is of type `Result<u32, Void>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL |     Err(#[stable(feature = "rust1", since = "1.0.0")] E),
-   |     --- not covered
+LL ~         Ok(x) => x,
+LL ~         Err(_) => todo!(),
    |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
-   = note: the matched value is of type `Result<u32, Void>`
 
 error[E0005]: refutable pattern in local binding: `Err(_)` not covered
   --> $DIR/uninhabited-matches-feature-gated.rs:37:9
@@ -72,13 +115,20 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered
 LL |     let Ok(x) = x;
    |         ^^^^^ pattern `Err(_)` not covered
    |
-  ::: $SRC_DIR/core/src/result.rs:LL:COL
-   |
-LL |     Err(#[stable(feature = "rust1", since = "1.0.0")] E),
-   |     --- not covered
-   |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+note: `Result<u32, Void>` defined here
+  --> $SRC_DIR/core/src/result.rs:LL:COL
+   |
+LL | / pub enum Result<T, E> {
+LL | |     /// Contains the success value
+LL | |     #[lang = "Ok"]
+LL | |     #[stable(feature = "rust1", since = "1.0.0")]
+...  |
+LL | |     Err(#[stable(feature = "rust1", since = "1.0.0")] E),
+   | |     ^^^ not covered
+LL | | }
+   | |_-
    = note: the matched value is of type `Result<u32, Void>`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer
index 4e72700e38421..5fae65dd28b45 160000
--- a/src/tools/rust-analyzer
+++ b/src/tools/rust-analyzer
@@ -1 +1 @@
-Subproject commit 4e72700e38421a12993fe5fa5c33d712652bc6c8
+Subproject commit 5fae65dd28b450a437ebc800a410164c3af1d516