about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-07-04 16:37:39 +0000
committerbors <bors@rust-lang.org>2024-07-04 16:37:39 +0000
commit8a9cccb1004e9fa8a189e3288a92e998cefdd3c6 (patch)
tree047e49067e968e998874d688b4edbd8fe57772a6
parent9f877c9cd2c3f8f2f64df1e0c1804ad0682416d0 (diff)
parentdd42f7a0a6158738e7321ac489591d9694a71fcc (diff)
downloadrust-8a9cccb1004e9fa8a189e3288a92e998cefdd3c6.tar.gz
rust-8a9cccb1004e9fa8a189e3288a92e998cefdd3c6.zip
Auto merge of #127326 - matthiaskrgr:rollup-kz7vd3w, r=matthiaskrgr
Rollup of 9 pull requests

Successful merges:

 - #123043 (Disable dead variant removal for `#[repr(C)]` enums.)
 - #126405 (Migrate some rustc_builtin_macros to SessionDiagnostic)
 - #127037 (Remove some duplicated tests)
 - #127283 (Reject SmartPointer constructions not serving the purpose)
 - #127301 (Tweak some structured suggestions to be more verbose and accurate)
 - #127307 (Allow to have different types for arguments of `Rustc::remap_path_prefix`)
 - #127309 (jsondocck: add `$FILE` built-in variable)
 - #127314 (Trivial update on tidy bless note)
 - #127319 (Remove a use of `StructuredDiag`, which is incompatible with automatic error tainting and error translations)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_abi/src/layout.rs4
-rw-r--r--compiler/rustc_abi/src/lib.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs25
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs29
-rw-r--r--compiler/rustc_builtin_macros/messages.ftl11
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs13
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs39
-rw-r--r--compiler/rustc_builtin_macros/src/errors.rs40
-rw-r--r--compiler/rustc_builtin_macros/src/proc_macro_harness.rs24
-rw-r--r--compiler/rustc_builtin_macros/src/source_util.rs11
-rw-r--r--compiler/rustc_errors/src/emitter.rs23
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl2
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/structured_errors.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs56
-rw-r--r--compiler/rustc_hir_typeck/messages.ftl15
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs10
-rw-r--r--compiler/rustc_hir_typeck/src/errors.rs11
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs44
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs13
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs6
-rw-r--r--src/librustdoc/passes/lint/bare_urls.rs36
-rw-r--r--src/tools/clippy/tests/ui/dbg_macro/dbg_macro.stderr2
-rw-r--r--src/tools/clippy/tests/ui/dbg_macro/dbg_macro_unfixable.stderr1
-rw-r--r--src/tools/clippy/tests/ui/manual_split_once.stderr10
-rw-r--r--src/tools/clippy/tests/ui/significant_drop_tightening.stderr2
-rw-r--r--src/tools/jsondocck/src/cache.rs2
-rw-r--r--src/tools/run-make-support/src/rustc.rs6
-rw-r--r--src/tools/tidy/src/run_make_tests.rs2
-rw-r--r--tests/rustdoc-ui/diagnostic-width.stderr6
-rw-r--r--tests/rustdoc-ui/include-str-bare-urls.stderr6
-rw-r--r--tests/rustdoc-ui/lints/bare-urls.stderr102
-rw-r--r--tests/rustdoc-ui/lints/renamed-lint-still-applies.stderr6
-rw-r--r--tests/ui/abi/compatibility.rs5
-rw-r--r--tests/ui/assign-imm-local-twice.rs2
-rw-r--r--tests/ui/assign-imm-local-twice.stderr8
-rw-r--r--tests/ui/associated-types/issue-22560.stderr12
-rw-r--r--tests/ui/async-await/issue-61452.stderr10
-rw-r--r--tests/ui/borrowck/borrow-raw-address-of-mutability.stderr8
-rw-r--r--tests/ui/borrowck/borrowck-closures-unique.stderr7
-rw-r--r--tests/ui/borrowck/borrowck-match-binding-is-assignment.stderr20
-rw-r--r--tests/ui/borrowck/immutable-arg.stderr7
-rw-r--r--tests/ui/borrowck/issue-111554.stderr7
-rw-r--r--tests/ui/borrowck/issue-33819.stderr11
-rw-r--r--tests/ui/borrowck/issue-45199.rs6
-rw-r--r--tests/ui/borrowck/issue-45199.stderr26
-rw-r--r--tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.stderr48
-rw-r--r--tests/ui/borrowck/mutability-errors.stderr64
-rw-r--r--tests/ui/borrowck/suggest-ref-mut-issue-118596.stderr8
-rw-r--r--tests/ui/borrowck/tainted-promoteds.stderr10
-rw-r--r--tests/ui/cannot-mutate-captured-non-mut-var.stderr14
-rw-r--r--tests/ui/closures/2229_closure_analysis/array_subslice.stderr8
-rw-r--r--tests/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.stderr16
-rw-r--r--tests/ui/closures/closure-immutable-outer-variable.stderr7
-rw-r--r--tests/ui/command-line-diagnostics.stderr10
-rw-r--r--tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr12
-rw-r--r--tests/ui/consts/issue-39974.stderr10
-rw-r--r--tests/ui/consts/slice_elem_ty_mismatch_in_unsizing_cast.rs4
-rw-r--r--tests/ui/consts/slice_elem_ty_mismatch_in_unsizing_cast.stderr9
-rw-r--r--tests/ui/deriving/deriving-smart-pointer-neg.rs45
-rw-r--r--tests/ui/deriving/deriving-smart-pointer-neg.stderr75
-rw-r--r--tests/ui/deriving/deriving-smart-pointer.rs1
-rw-r--r--tests/ui/did_you_mean/issue-34337.stderr11
-rw-r--r--tests/ui/did_you_mean/issue-37139.stderr11
-rw-r--r--tests/ui/did_you_mean/issue-53280-expected-float-found-integer-literal.stderr33
-rw-r--r--tests/ui/error-codes/E0393.stderr6
-rw-r--r--tests/ui/feature-gates/feature-gate-derive-smart-pointer.rs1
-rw-r--r--tests/ui/feature-gates/feature-gate-derive-smart-pointer.stderr2
-rw-r--r--tests/ui/fn/suggest-return-closure.stderr8
-rw-r--r--tests/ui/issues/issue-11004.stderr20
-rw-r--r--tests/ui/issues/issue-21950.stderr6
-rw-r--r--tests/ui/issues/issue-22370.stderr6
-rw-r--r--tests/ui/let-else/let-else-slicing-error.stderr9
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr7
-rw-r--r--tests/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr32
-rw-r--r--tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.rs2
-rw-r--r--tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.stderr8
-rw-r--r--tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.rs2
-rw-r--r--tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.stderr8
-rw-r--r--tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.rs2
-rw-r--r--tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.stderr10
-rw-r--r--tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.rs2
-rw-r--r--tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.stderr10
-rw-r--r--tests/ui/mismatched_types/float-literal-inference-restrictions.stderr11
-rw-r--r--tests/ui/mut/mut-pattern-internal-mutability.stderr4
-rw-r--r--tests/ui/nll/closure-captures.stderr48
-rw-r--r--tests/ui/nll/coroutine-upvar-mutability.stderr8
-rw-r--r--tests/ui/nll/issue-46023.stderr8
-rw-r--r--tests/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr4
-rw-r--r--tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr8
-rw-r--r--tests/ui/pattern/mut-ref-mut-2021.stderr4
-rw-r--r--tests/ui/pattern/patkind-ref-binding-issue-114896.stderr7
-rw-r--r--tests/ui/pattern/patkind-ref-binding-issue-122415.stderr7
-rw-r--r--tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr288
-rw-r--r--tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr288
-rw-r--r--tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr288
-rw-r--r--tests/ui/repr/repr-c-dead-variants.rs63
-rw-r--r--tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr288
-rw-r--r--tests/ui/repr/repr-c-int-dead-variants.rs38
-rw-r--r--tests/ui/repr/repr-c-int-dead-variants.stderr288
-rw-r--r--tests/ui/structs/structure-constructor-type-mismatch.stderr80
-rw-r--r--tests/ui/suggestions/match-ergonomics.stderr14
-rw-r--r--tests/ui/suggestions/parenthesized-deref-suggestion.stderr14
-rw-r--r--tests/ui/suggestions/pattern-slice-vec.stderr44
-rw-r--r--tests/ui/suggestions/suppress-consider-slicing-issue-120605.stderr9
-rw-r--r--tests/ui/try-block/try-block-type-error.stderr10
-rw-r--r--tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903.rs29
-rw-r--r--tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903.stderr13
-rw-r--r--tests/ui/type/subtyping-opaque-type.rs19
-rw-r--r--tests/ui/type/type-parameter-defaults-referencing-Self.stderr6
-rw-r--r--tests/ui/typeck/issue-53712.rs2
-rw-r--r--tests/ui/typeck/issue-53712.stderr10
-rw-r--r--tests/ui/typeck/issue-91328.stderr32
-rw-r--r--tests/ui/unboxed-closures/unboxed-closure-immutable-capture.stderr63
-rw-r--r--tests/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.stderr7
-rw-r--r--tests/ui/unboxed-closures/unboxed-closures-mutate-upvar.stderr24
-rw-r--r--tests/ui/unsafe/unsafe-fn-autoderef.stderr10
117 files changed, 2642 insertions, 640 deletions
diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs
index 9165b4f2df3..197dd7f9c9e 100644
--- a/compiler/rustc_abi/src/layout.rs
+++ b/compiler/rustc_abi/src/layout.rs
@@ -186,7 +186,7 @@ pub trait LayoutCalculator {
         let (present_first, present_second) = {
             let mut present_variants = variants
                 .iter_enumerated()
-                .filter_map(|(i, v)| if absent(v) { None } else { Some(i) });
+                .filter_map(|(i, v)| if !repr.c() && absent(v) { None } else { Some(i) });
             (present_variants.next(), present_variants.next())
         };
         let present_first = match present_first {
@@ -621,7 +621,7 @@ where
     let discr_type = repr.discr_type();
     let bits = Integer::from_attr(dl, discr_type).size().bits();
     for (i, mut val) in discriminants {
-        if variants[i].iter().any(|f| f.abi.is_uninhabited()) {
+        if !repr.c() && variants[i].iter().any(|f| f.abi.is_uninhabited()) {
             continue;
         }
         if discr_type.is_signed() {
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index 31c66a56bea..78332d66f03 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -1429,7 +1429,7 @@ pub enum Variants<FieldIdx: Idx, VariantIdx: Idx> {
     /// Single enum variants, structs/tuples, unions, and all non-ADTs.
     Single { index: VariantIdx },
 
-    /// Enum-likes with more than one inhabited variant: each variant comes with
+    /// Enum-likes with more than one variant: each variant comes with
     /// a *discriminant* (usually the same as the variant index but the user can
     /// assign explicit discriminant values). That discriminant is encoded
     /// as a *tag* on the machine. The layout of each variant is
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 7ef53fa2078..e291ebd9bb8 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -3757,13 +3757,11 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
         assigned_span: Span,
         err_place: Place<'tcx>,
     ) {
-        let (from_arg, local_decl, local_name) = match err_place.as_local() {
-            Some(local) => (
-                self.body.local_kind(local) == LocalKind::Arg,
-                Some(&self.body.local_decls[local]),
-                self.local_names[local],
-            ),
-            None => (false, None, None),
+        let (from_arg, local_decl) = match err_place.as_local() {
+            Some(local) => {
+                (self.body.local_kind(local) == LocalKind::Arg, Some(&self.body.local_decls[local]))
+            }
+            None => (false, None),
         };
 
         // If root local is initialized immediately (everything apart from let
@@ -3795,13 +3793,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
             err.span_label(assigned_span, format!("first assignment to {place_description}"));
         }
         if let Some(decl) = local_decl
-            && let Some(name) = local_name
             && decl.can_be_made_mutable()
         {
-            err.span_suggestion(
-                decl.source_info.span,
+            err.span_suggestion_verbose(
+                decl.source_info.span.shrink_to_lo(),
                 "consider making this binding mutable",
-                format!("mut {name}"),
+                "mut ".to_string(),
                 Applicability::MachineApplicable,
             );
             if !from_arg
@@ -3813,10 +3810,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
                     }))
                 )
             {
-                err.span_suggestion(
-                    decl.source_info.span,
+                err.span_suggestion_verbose(
+                    decl.source_info.span.shrink_to_lo(),
                     "to modify the original value, take a borrow instead",
-                    format!("ref mut {name}"),
+                    "ref mut ".to_string(),
                     Applicability::MaybeIncorrect,
                 );
             }
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index 19a4df0cd7b..677029f9d3f 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -408,10 +408,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
                                     fn_decl.implicit_self,
                                     hir::ImplicitSelfKind::RefImm | hir::ImplicitSelfKind::RefMut
                                 ) {
-                                    err.span_suggestion(
-                                        upvar_ident.span,
+                                    err.span_suggestion_verbose(
+                                        upvar_ident.span.shrink_to_lo(),
                                         "consider changing this to be mutable",
-                                        format!("mut {}", upvar_ident.name),
+                                        "mut ",
                                         Applicability::MachineApplicable,
                                     );
                                     break;
@@ -419,10 +419,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
                             }
                         }
                     } else {
-                        err.span_suggestion(
-                            upvar_ident.span,
+                        err.span_suggestion_verbose(
+                            upvar_ident.span.shrink_to_lo(),
                             "consider changing this to be mutable",
-                            format!("mut {}", upvar_ident.name),
+                            "mut ",
                             Applicability::MachineApplicable,
                         );
                     }
@@ -449,8 +449,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
                     .is_ok_and(|snippet| snippet.starts_with("&mut ")) =>
             {
                 err.span_label(span, format!("cannot {act}"));
-                err.span_suggestion(
-                    span,
+                err.span_suggestion_verbose(
+                    span.with_hi(span.lo() + BytePos(5)),
                     "try removing `&mut` here",
                     "",
                     Applicability::MaybeIncorrect,
@@ -755,13 +755,16 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
                 pat: hir::Pat { kind: hir::PatKind::Ref(_, _), .. },
                 ..
             }) = node
-            && let Ok(name) =
-                self.infcx.tcx.sess.source_map().span_to_snippet(local_decl.source_info.span)
         {
-            err.span_suggestion(
-                pat_span,
+            err.multipart_suggestion(
                 "consider changing this to be mutable",
-                format!("&(mut {name})"),
+                vec![
+                    (pat_span.until(local_decl.source_info.span), "&(mut ".to_string()),
+                    (
+                        local_decl.source_info.span.shrink_to_hi().with_hi(pat_span.hi()),
+                        ")".to_string(),
+                    ),
+                ],
                 Applicability::MachineApplicable,
             );
             return;
diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl
index 2d1269e1b6a..b56bfa98357 100644
--- a/compiler/rustc_builtin_macros/messages.ftl
+++ b/compiler/rustc_builtin_macros/messages.ftl
@@ -17,6 +17,9 @@ builtin_macros_asm_expected_other = expected operand, {$is_global_asm ->
     *[false] clobber_abi, options
     }, or additional template string
 
+builtin_macros_asm_expected_string_literal = expected string literal
+    .label = not a string literal
+
 builtin_macros_asm_explicit_register_name = explicit register arguments cannot have names
 
 builtin_macros_asm_mayunwind = asm labels are not allowed with the `may_unwind` option
@@ -25,6 +28,8 @@ builtin_macros_asm_modifier_invalid = asm template modifier must be a single cha
 
 builtin_macros_asm_mutually_exclusive = the `{$opt1}` and `{$opt2}` options are mutually exclusive
 
+builtin_macros_asm_no_matched_argument_name = there is no argument named `{$name}`
+
 builtin_macros_asm_noreturn = asm outputs are not allowed with the `noreturn` option
 
 builtin_macros_asm_opt_already_provided = the `{$symbol}` option was already provided
@@ -228,10 +233,16 @@ builtin_macros_only_one_argument = {$name} takes 1 argument
 
 builtin_macros_proc_macro = `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]`
 
+builtin_macros_proc_macro_attribute_only_be_used_on_bare_functions = the `#[{$path}]` attribute may only be used on bare functions
+
+builtin_macros_proc_macro_attribute_only_usable_with_crate_type = the `#[{$path}]` attribute is only usable with crates of the `proc-macro` crate type
+
 builtin_macros_requires_cfg_pattern =
     macro requires a cfg-pattern as an argument
     .label = cfg-pattern required
 
+builtin_macros_source_uitls_expected_item = expected item, found `{$token}`
+
 builtin_macros_takes_no_arguments = {$name} takes no arguments
 
 builtin_macros_test_bad_fn = {$kind} functions cannot be used for tests
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index 64238e81b26..dd0f9aaf221 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -390,9 +390,7 @@ fn parse_clobber_abi<'a>(p: &mut Parser<'a>, args: &mut AsmArgs) -> PResult<'a,
             }
             Err(opt_lit) => {
                 let span = opt_lit.map_or(p.token.span, |lit| lit.span);
-                let mut err = p.dcx().struct_span_err(span, "expected string literal");
-                err.span_label(span, "not a string literal");
-                return Err(err);
+                return Err(p.dcx().create_err(errors::AsmExpectedStringLiteral { span }));
             }
         };
 
@@ -639,14 +637,13 @@ fn expand_preparsed_asm(
                             match args.named_args.get(&Symbol::intern(name)) {
                                 Some(&idx) => Some(idx),
                                 None => {
-                                    let msg = format!("there is no argument named `{name}`");
                                     let span = arg.position_span;
                                     ecx.dcx()
-                                        .struct_span_err(
-                                            template_span
+                                        .create_err(errors::AsmNoMatchedArgumentName {
+                                            name: name.to_owned(),
+                                            span: template_span
                                                 .from_inner(InnerSpan::new(span.start, span.end)),
-                                            msg,
-                                        )
+                                        })
                                         .emit();
                                     None
                                 }
diff --git a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs
index ea054a7e355..bbc7cd39627 100644
--- a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs
@@ -3,8 +3,9 @@ use std::mem::swap;
 use ast::HasAttrs;
 use rustc_ast::{
     self as ast, GenericArg, GenericBound, GenericParamKind, ItemKind, MetaItem,
-    TraitBoundModifiers,
+    TraitBoundModifiers, VariantData,
 };
+use rustc_attr as attr;
 use rustc_expand::base::{Annotatable, ExtCtxt};
 use rustc_span::symbol::{sym, Ident};
 use rustc_span::Span;
@@ -24,11 +25,43 @@ pub fn expand_deriving_smart_ptr(
     _is_const: bool,
 ) {
     let (name_ident, generics) = if let Annotatable::Item(aitem) = item
-        && let ItemKind::Struct(_, g) = &aitem.kind
+        && let ItemKind::Struct(struct_data, g) = &aitem.kind
     {
+        let is_transparent = aitem.attrs.iter().any(|attr| {
+            attr::find_repr_attrs(cx.sess, attr)
+                .into_iter()
+                .any(|r| matches!(r, attr::ReprTransparent))
+        });
+        if !is_transparent {
+            cx.dcx()
+                .struct_span_err(
+                    span,
+                    "`SmartPointer` can only be derived on `struct`s with `#[repr(transparent)]`",
+                )
+                .emit();
+            return;
+        }
+        if !matches!(
+            struct_data,
+            VariantData::Struct { fields, recovered: _ } | VariantData::Tuple(fields, _)
+                if !fields.is_empty())
+        {
+            cx.dcx()
+                .struct_span_err(
+                    span,
+                    "`SmartPointer` can only be derived on `struct`s with at least one field",
+                )
+                .emit();
+            return;
+        }
         (aitem.ident, g)
     } else {
-        cx.dcx().struct_span_err(span, "`SmartPointer` can only be derived on `struct`s").emit();
+        cx.dcx()
+            .struct_span_err(
+                span,
+                "`SmartPointer` can only be derived on `struct`s with `#[repr(transparent)]`",
+            )
+            .emit();
         return;
     };
 
diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs
index ed2f98f2a39..49d640436c2 100644
--- a/compiler/rustc_builtin_macros/src/errors.rs
+++ b/compiler/rustc_builtin_macros/src/errors.rs
@@ -729,6 +729,14 @@ pub(crate) struct AsmExpectedComma {
 }
 
 #[derive(Diagnostic)]
+#[diag(builtin_macros_asm_expected_string_literal)]
+pub(crate) struct AsmExpectedStringLiteral {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(builtin_macros_asm_underscore_input)]
 pub(crate) struct AsmUnderscoreInput {
     #[primary_span]
@@ -782,6 +790,14 @@ pub(crate) struct AsmNoReturn {
 }
 
 #[derive(Diagnostic)]
+#[diag(builtin_macros_asm_no_matched_argument_name)]
+pub(crate) struct AsmNoMatchedArgumentName {
+    pub(crate) name: String,
+    #[primary_span]
+    pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(builtin_macros_asm_mayunwind)]
 pub(crate) struct AsmMayUnwind {
     #[primary_span]
@@ -872,3 +888,27 @@ pub(crate) struct TakesNoArguments<'a> {
     pub span: Span,
     pub name: &'a str,
 }
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_proc_macro_attribute_only_be_used_on_bare_functions)]
+pub(crate) struct AttributeOnlyBeUsedOnBareFunctions<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub path: &'a str,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_proc_macro_attribute_only_usable_with_crate_type)]
+pub(crate) struct AttributeOnlyUsableWithCrateType<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub path: &'a str,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_source_uitls_expected_item)]
+pub(crate) struct ExpectedItem<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub token: &'a str,
+}
diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
index 99d0191958d..a8a595ea579 100644
--- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
+++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
@@ -214,12 +214,12 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
         };
 
         if !is_fn {
-            let msg = format!(
-                "the `#[{}]` attribute may only be used on bare functions",
-                pprust::path_to_string(&attr.get_normal_item().path),
-            );
-
-            self.dcx.span_err(attr.span, msg);
+            self.dcx
+                .create_err(errors::AttributeOnlyBeUsedOnBareFunctions {
+                    span: attr.span,
+                    path: &pprust::path_to_string(&attr.get_normal_item().path),
+                })
+                .emit();
             return;
         }
 
@@ -228,12 +228,12 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
         }
 
         if !self.is_proc_macro_crate {
-            let msg = format!(
-                "the `#[{}]` attribute is only usable with crates of the `proc-macro` crate type",
-                pprust::path_to_string(&attr.get_normal_item().path),
-            );
-
-            self.dcx.span_err(attr.span, msg);
+            self.dcx
+                .create_err(errors::AttributeOnlyUsableWithCrateType {
+                    span: attr.span,
+                    path: &pprust::path_to_string(&attr.get_normal_item().path),
+                })
+                .emit();
             return;
         }
 
diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs
index dc1d82df0c3..44db12cf695 100644
--- a/compiler/rustc_builtin_macros/src/source_util.rs
+++ b/compiler/rustc_builtin_macros/src/source_util.rs
@@ -1,3 +1,4 @@
+use crate::errors;
 use crate::util::{
     check_zero_tts, get_single_str_from_tts, get_single_str_spanned_from_tts, parse_expr,
 };
@@ -165,9 +166,13 @@ pub(crate) fn expand_include<'cx>(
                     Ok(Some(item)) => ret.push(item),
                     Ok(None) => {
                         if self.p.token != token::Eof {
-                            let token = pprust::token_to_string(&self.p.token);
-                            let msg = format!("expected item, found `{token}`");
-                            self.p.dcx().span_err(self.p.token.span, msg);
+                            self.p
+                                .dcx()
+                                .create_err(errors::ExpectedItem {
+                                    span: self.p.token.span,
+                                    token: &pprust::token_to_string(&self.p.token),
+                                })
+                                .emit();
                         }
 
                         break;
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 45118bcc58a..aa47ca16676 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -2273,9 +2273,26 @@ impl HumanEmitter {
                     &normalize_whitespace(last_line),
                     Style::NoStyle,
                 );
-                buffer.puts(*row_num, 0, &self.maybe_anonymized(line_num), Style::LineNumber);
-                buffer.puts(*row_num, max_line_num_len + 1, "+ ", Style::Addition);
-                buffer.append(*row_num, &normalize_whitespace(line_to_add), Style::NoStyle);
+                if !line_to_add.trim().is_empty() {
+                    // Check if after the removal, the line is left with only whitespace. If so, we
+                    // will not show an "addition" line, as removing the whole line is what the user
+                    // would really want.
+                    // For example, for the following:
+                    //   |
+                    // 2 -     .await
+                    // 2 +     (note the left over whitepsace)
+                    //   |
+                    // We really want
+                    //   |
+                    // 2 -     .await
+                    //   |
+                    // *row_num -= 1;
+                    buffer.puts(*row_num, 0, &self.maybe_anonymized(line_num), Style::LineNumber);
+                    buffer.puts(*row_num, max_line_num_len + 1, "+ ", Style::Addition);
+                    buffer.append(*row_num, &normalize_whitespace(line_to_add), Style::NoStyle);
+                } else {
+                    *row_num -= 1;
+                }
             } else {
                 *row_num -= 2;
             }
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 064d9c077b0..91b1506d1e4 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -55,8 +55,6 @@ hir_analysis_cannot_capture_late_bound_ty =
     cannot capture late-bound type parameter in {$what}
     .label = parameter defined here
 
-hir_analysis_cast_thin_pointer_to_fat_pointer = cannot cast thin pointer `{$expr_ty}` to fat pointer `{$cast_ty}`
-
 hir_analysis_closure_implicit_hrtb = implicit types in closure signatures are forbidden when `for<...>` is present
     .label = `for<...>` is here
 
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 3ffb51fa992..7d44ac458de 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -453,12 +453,11 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for MissingTypeParams {
             } else {
                 // The user wrote `Iterator`, so we don't have a type we can suggest, but at
                 // least we can clue them to the correct syntax `Iterator<Type>`.
-                err.span_suggestion(
-                    self.span,
+                err.span_suggestion_verbose(
+                    self.span.shrink_to_hi(),
                     fluent::hir_analysis_suggestion,
                     format!(
-                        "{}<{}>",
-                        snippet,
+                        "<{}>",
                         self.missing_type_params
                             .iter()
                             .map(|n| n.to_string())
@@ -708,15 +707,6 @@ pub(crate) struct PassToVariadicFunction<'tcx, 'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_cast_thin_pointer_to_fat_pointer, code = E0607)]
-pub(crate) struct CastThinPointerToFatPointer<'tcx> {
-    #[primary_span]
-    pub span: Span,
-    pub expr_ty: Ty<'tcx>,
-    pub cast_ty: String,
-}
-
-#[derive(Diagnostic)]
 #[diag(hir_analysis_invalid_union_field, code = E0740)]
 pub(crate) struct InvalidUnionField {
     #[primary_span]
diff --git a/compiler/rustc_hir_analysis/src/structured_errors.rs b/compiler/rustc_hir_analysis/src/structured_errors.rs
index 5abfd25dd95..61a2400f9e4 100644
--- a/compiler/rustc_hir_analysis/src/structured_errors.rs
+++ b/compiler/rustc_hir_analysis/src/structured_errors.rs
@@ -1,10 +1,7 @@
 mod missing_cast_for_variadic_arg;
-mod sized_unsized_cast;
 mod wrong_number_of_generic_args;
 
-pub use self::{
-    missing_cast_for_variadic_arg::*, sized_unsized_cast::*, wrong_number_of_generic_args::*,
-};
+pub use self::{missing_cast_for_variadic_arg::*, wrong_number_of_generic_args::*};
 
 use rustc_errors::{Diag, ErrCode};
 use rustc_session::Session;
diff --git a/compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs b/compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs
deleted file mode 100644
index 9e871ff9af0..00000000000
--- a/compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs
+++ /dev/null
@@ -1,56 +0,0 @@
-use crate::{errors, structured_errors::StructuredDiag};
-use rustc_errors::{codes::*, Diag};
-use rustc_middle::ty::{Ty, TypeVisitableExt};
-use rustc_session::Session;
-use rustc_span::Span;
-
-pub struct SizedUnsizedCast<'tcx> {
-    pub sess: &'tcx Session,
-    pub span: Span,
-    pub expr_ty: Ty<'tcx>,
-    pub cast_ty: String,
-}
-
-impl<'tcx> StructuredDiag<'tcx> for SizedUnsizedCast<'tcx> {
-    fn session(&self) -> &Session {
-        self.sess
-    }
-
-    fn code(&self) -> ErrCode {
-        E0607
-    }
-
-    fn diagnostic_common(&self) -> Diag<'tcx> {
-        let mut err = self.sess.dcx().create_err(errors::CastThinPointerToFatPointer {
-            span: self.span,
-            expr_ty: self.expr_ty,
-            cast_ty: self.cast_ty.to_owned(),
-        });
-
-        if self.expr_ty.references_error() {
-            err.downgrade_to_delayed_bug();
-        }
-
-        err
-    }
-
-    fn diagnostic_extended(&self, mut err: Diag<'tcx>) -> Diag<'tcx> {
-        err.help(
-            "Thin pointers are \"simple\" pointers: they are purely a reference to a
-memory address.
-
-Fat pointers are pointers referencing \"Dynamically Sized Types\" (also
-called DST). DST don't have a statically known size, therefore they can
-only exist behind some kind of pointers that contain additional
-information. Slices and trait objects are DSTs. In the case of slices,
-the additional information the fat pointer holds is their size.
-
-To fix this error, don't try to cast directly between thin and fat
-pointers.
-
-For more information about casts, take a look at The Book:
-https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions",
-        );
-        err
-    }
-}
diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl
index d6f3f4d640b..3c5070bd006 100644
--- a/compiler/rustc_hir_typeck/messages.ftl
+++ b/compiler/rustc_hir_typeck/messages.ftl
@@ -23,6 +23,21 @@ hir_typeck_cannot_cast_to_bool = cannot cast `{$expr_ty}` as `bool`
 
 hir_typeck_cast_enum_drop = cannot cast enum `{$expr_ty}` into integer `{$cast_ty}` because it implements `Drop`
 
+hir_typeck_cast_thin_pointer_to_fat_pointer = cannot cast thin pointer `{$expr_ty}` to fat pointer `{$cast_ty}`
+    .teach_help = Thin pointers are "simple" pointers: they are purely a reference to a
+        memory address.
+
+        Fat pointers are pointers referencing "Dynamically Sized Types" (also
+        called DST). DST don't have a statically known size, therefore they can
+        only exist behind some kind of pointers that contain additional
+        information. Slices and trait objects are DSTs. In the case of slices,
+        the additional information the fat pointer holds is their size.
+
+        To fix this error, don't try to cast directly between thin and fat
+        pointers.
+
+        For more information about casts, take a look at The Book:
+        https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions",
 hir_typeck_cast_unknown_pointer = cannot cast {$to ->
     [true] to
     *[false] from
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index cb1a412d17e..53e44d6bcae 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -500,16 +500,12 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                 err.emit();
             }
             CastError::SizedUnsizedCast => {
-                use rustc_hir_analysis::structured_errors::{SizedUnsizedCast, StructuredDiag};
-
-                SizedUnsizedCast {
-                    sess: fcx.tcx.sess,
+                fcx.dcx().emit_err(errors::CastThinPointerToFatPointer {
                     span: self.span,
                     expr_ty: self.expr_ty,
                     cast_ty: fcx.ty_to_string(self.cast_ty),
-                }
-                .diagnostic()
-                .emit();
+                    teach: fcx.tcx.sess.teach(E0607).then_some(()),
+                });
             }
             CastError::IntToFatCast(known_metadata) => {
                 let expr_if_nightly = fcx.tcx.sess.is_nightly_build().then_some(self.expr_span);
diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs
index 98add86252c..e49b921e63c 100644
--- a/compiler/rustc_hir_typeck/src/errors.rs
+++ b/compiler/rustc_hir_typeck/src/errors.rs
@@ -689,3 +689,14 @@ pub struct ReplaceWithName {
     pub span: Span,
     pub name: String,
 }
+
+#[derive(Diagnostic)]
+#[diag(hir_typeck_cast_thin_pointer_to_fat_pointer, code = E0607)]
+pub(crate) struct CastThinPointerToFatPointer<'tcx> {
+    #[primary_span]
+    pub span: Span,
+    pub expr_ty: Ty<'tcx>,
+    pub cast_ty: String,
+    #[note(hir_typeck_teach_help)]
+    pub(crate) teach: Option<()>,
+}
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index f3aece4e1d8..bd5e5294983 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -2551,10 +2551,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         match *base_ty.peel_refs().kind() {
             ty::Array(_, len) => {
-                self.maybe_suggest_array_indexing(&mut err, expr, base, ident, len);
+                self.maybe_suggest_array_indexing(&mut err, base, ident, len);
             }
             ty::RawPtr(..) => {
-                self.suggest_first_deref_field(&mut err, expr, base, ident);
+                self.suggest_first_deref_field(&mut err, base, ident);
             }
             ty::Param(param_ty) => {
                 err.span_label(ident.span, "unknown field");
@@ -2721,7 +2721,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn maybe_suggest_array_indexing(
         &self,
         err: &mut Diag<'_>,
-        expr: &hir::Expr<'_>,
         base: &hir::Expr<'_>,
         field: Ident,
         len: ty::Const<'tcx>,
@@ -2729,32 +2728,41 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         err.span_label(field.span, "unknown field");
         if let (Some(len), Ok(user_index)) =
             (len.try_eval_target_usize(self.tcx, self.param_env), field.as_str().parse::<u64>())
-            && let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span)
         {
             let help = "instead of using tuple indexing, use array indexing";
-            let suggestion = format!("{base}[{field}]");
             let applicability = if len < user_index {
                 Applicability::MachineApplicable
             } else {
                 Applicability::MaybeIncorrect
             };
-            err.span_suggestion(expr.span, help, suggestion, applicability);
+            err.multipart_suggestion(
+                help,
+                vec![
+                    (base.span.between(field.span), "[".to_string()),
+                    (field.span.shrink_to_hi(), "]".to_string()),
+                ],
+                applicability,
+            );
         }
     }
 
-    fn suggest_first_deref_field(
-        &self,
-        err: &mut Diag<'_>,
-        expr: &hir::Expr<'_>,
-        base: &hir::Expr<'_>,
-        field: Ident,
-    ) {
+    fn suggest_first_deref_field(&self, err: &mut Diag<'_>, base: &hir::Expr<'_>, field: Ident) {
         err.span_label(field.span, "unknown field");
-        if let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span) {
-            let msg = format!("`{base}` is a raw pointer; try dereferencing it");
-            let suggestion = format!("(*{base}).{field}");
-            err.span_suggestion(expr.span, msg, suggestion, Applicability::MaybeIncorrect);
-        }
+        let val = if let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span)
+            && base.len() < 20
+        {
+            format!("`{base}`")
+        } else {
+            "the value".to_string()
+        };
+        err.multipart_suggestion(
+            format!("{val} is a raw pointer; try dereferencing it"),
+            vec![
+                (base.span.shrink_to_lo(), "(*".to_string()),
+                (base.span.shrink_to_hi(), ")".to_string()),
+            ],
+            Applicability::MaybeIncorrect,
+        );
     }
 
     fn no_such_field_err(&self, field: Ident, expr_t: Ty<'tcx>, id: HirId) -> Diag<'_> {
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index f932a27e9a2..478bbc0ed98 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -2499,7 +2499,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             .any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..)))
             && let Some(span) = ti.span
             && let Some(_) = ti.origin_expr
-            && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
         {
             let resolved_ty = self.resolve_vars_if_possible(ti.expected);
             let (is_slice_or_array_or_vector, resolved_ty) =
@@ -2510,10 +2509,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         || self.tcx.is_diagnostic_item(sym::Result, adt_def.did()) =>
                 {
                     // Slicing won't work here, but `.as_deref()` might (issue #91328).
-                    err.span_suggestion(
-                        span,
+                    err.span_suggestion_verbose(
+                        span.shrink_to_hi(),
                         "consider using `as_deref` here",
-                        format!("{snippet}.as_deref()"),
+                        ".as_deref()",
                         Applicability::MaybeIncorrect,
                     );
                 }
@@ -2522,10 +2521,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             let is_top_level = current_depth <= 1;
             if is_slice_or_array_or_vector && is_top_level {
-                err.span_suggestion(
-                    span,
+                err.span_suggestion_verbose(
+                    span.shrink_to_hi(),
                     "consider slicing here",
-                    format!("{snippet}[..]"),
+                    "[..]",
                     Applicability::MachineApplicable,
                 );
             }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
index bc59b5e033b..fd50d1eb438 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
@@ -52,10 +52,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                         ) = tcx.sess.source_map().span_to_snippet(sp) =>
                     {
                         if snippet.chars().all(|c| c.is_digit(10) || c == '-' || c == '_') {
-                            diag.span_suggestion(
-                                sp,
+                            diag.span_suggestion_verbose(
+                                sp.shrink_to_hi(),
                                 "use a float literal",
-                                format!("{snippet}.0"),
+                                ".0",
                                 MachineApplicable,
                             );
                         }
diff --git a/src/librustdoc/passes/lint/bare_urls.rs b/src/librustdoc/passes/lint/bare_urls.rs
index 4b2d3092837..a4ba718789c 100644
--- a/src/librustdoc/passes/lint/bare_urls.rs
+++ b/src/librustdoc/passes/lint/bare_urls.rs
@@ -19,22 +19,22 @@ pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item) {
     };
     let dox = item.doc_value();
     if !dox.is_empty() {
-        let report_diag =
-            |cx: &DocContext<'_>, msg: &'static str, url: &str, range: Range<usize>| {
-                let sp =
-                    source_span_for_markdown_range(cx.tcx, &dox, &range, &item.attrs.doc_strings)
-                        .unwrap_or_else(|| item.attr_span(cx.tcx));
-                cx.tcx.node_span_lint(crate::lint::BARE_URLS, hir_id, sp, |lint| {
-                    lint.primary_message(msg)
-                        .note("bare URLs are not automatically turned into clickable links")
-                        .span_suggestion(
-                            sp,
-                            "use an automatic link instead",
-                            format!("<{url}>"),
-                            Applicability::MachineApplicable,
-                        );
-                });
-            };
+        let report_diag = |cx: &DocContext<'_>, msg: &'static str, range: Range<usize>| {
+            let sp = source_span_for_markdown_range(cx.tcx, &dox, &range, &item.attrs.doc_strings)
+                .unwrap_or_else(|| item.attr_span(cx.tcx));
+            cx.tcx.node_span_lint(crate::lint::BARE_URLS, hir_id, sp, |lint| {
+                lint.primary_message(msg)
+                    .note("bare URLs are not automatically turned into clickable links")
+                    .multipart_suggestion(
+                        "use an automatic link instead",
+                        vec![
+                            (sp.shrink_to_lo(), "<".to_string()),
+                            (sp.shrink_to_hi(), ">".to_string()),
+                        ],
+                        Applicability::MachineApplicable,
+                    );
+            });
+        };
 
         let mut p = Parser::new_ext(&dox, main_body_opts()).into_offset_iter();
 
@@ -74,17 +74,15 @@ fn find_raw_urls(
     cx: &DocContext<'_>,
     text: &str,
     range: Range<usize>,
-    f: &impl Fn(&DocContext<'_>, &'static str, &str, Range<usize>),
+    f: &impl Fn(&DocContext<'_>, &'static str, Range<usize>),
 ) {
     trace!("looking for raw urls in {text}");
     // For now, we only check "full" URLs (meaning, starting with "http://" or "https://").
     for match_ in URL_REGEX.find_iter(text) {
-        let url = match_.as_str();
         let url_range = match_.range();
         f(
             cx,
             "this URL is not a hyperlink",
-            url,
             Range { start: range.start + url_range.start, end: range.start + url_range.end },
         );
     }
diff --git a/src/tools/clippy/tests/ui/dbg_macro/dbg_macro.stderr b/src/tools/clippy/tests/ui/dbg_macro/dbg_macro.stderr
index 86667701da0..7d3c3f7c918 100644
--- a/src/tools/clippy/tests/ui/dbg_macro/dbg_macro.stderr
+++ b/src/tools/clippy/tests/ui/dbg_macro/dbg_macro.stderr
@@ -86,7 +86,6 @@ LL |     dbg!();
 help: remove the invocation before committing it to a version control system
    |
 LL -     dbg!();
-LL +     
    |
 
 error: the `dbg!` macro is intended as a debugging tool
@@ -146,7 +145,6 @@ LL |     expand_to_dbg!();
 help: remove the invocation before committing it to a version control system
    |
 LL -             dbg!();
-LL +             
    |
 
 error: the `dbg!` macro is intended as a debugging tool
diff --git a/src/tools/clippy/tests/ui/dbg_macro/dbg_macro_unfixable.stderr b/src/tools/clippy/tests/ui/dbg_macro/dbg_macro_unfixable.stderr
index d21595c2fcd..16e51f4742e 100644
--- a/src/tools/clippy/tests/ui/dbg_macro/dbg_macro_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/dbg_macro/dbg_macro_unfixable.stderr
@@ -9,7 +9,6 @@ LL |     dbg!();
 help: remove the invocation before committing it to a version control system
    |
 LL -     dbg!();
-LL +     
    |
 
 error: the `dbg!` macro is intended as a debugging tool
diff --git a/src/tools/clippy/tests/ui/manual_split_once.stderr b/src/tools/clippy/tests/ui/manual_split_once.stderr
index b4e51f473cf..c5c9be3ac63 100644
--- a/src/tools/clippy/tests/ui/manual_split_once.stderr
+++ b/src/tools/clippy/tests/ui/manual_split_once.stderr
@@ -96,12 +96,10 @@ LL |     let (l, r) = "a.b.c".split_once('.').unwrap();
 help: remove the `iter` usages
    |
 LL -     let l = iter.next().unwrap();
-LL +     
    |
 help: remove the `iter` usages
    |
 LL -     let r = iter.next().unwrap();
-LL +     
    |
 
 error: manual implementation of `split_once`
@@ -121,12 +119,10 @@ LL |     let (l, r) = "a.b.c".split_once('.')?;
 help: remove the `iter` usages
    |
 LL -     let l = iter.next()?;
-LL +     
    |
 help: remove the `iter` usages
    |
 LL -     let r = iter.next()?;
-LL +     
    |
 
 error: manual implementation of `rsplit_once`
@@ -146,12 +142,10 @@ LL |     let (l, r) = "a.b.c".rsplit_once('.').unwrap();
 help: remove the `iter` usages
    |
 LL -     let r = iter.next().unwrap();
-LL +     
    |
 help: remove the `iter` usages
    |
 LL -     let l = iter.next().unwrap();
-LL +     
    |
 
 error: manual implementation of `rsplit_once`
@@ -171,12 +165,10 @@ LL |     let (l, r) = "a.b.c".rsplit_once('.')?;
 help: remove the `iter` usages
    |
 LL -     let r = iter.next()?;
-LL +     
    |
 help: remove the `iter` usages
    |
 LL -     let l = iter.next()?;
-LL +     
    |
 
 error: manual implementation of `split_once`
@@ -202,12 +194,10 @@ LL |     let (a, b) = "a.b.c".split_once('.').unwrap();
 help: remove the `iter` usages
    |
 LL -     let a = iter.next().unwrap();
-LL +     
    |
 help: remove the `iter` usages
    |
 LL -     let b = iter.next().unwrap();
-LL +     
    |
 
 error: aborting due to 19 previous errors
diff --git a/src/tools/clippy/tests/ui/significant_drop_tightening.stderr b/src/tools/clippy/tests/ui/significant_drop_tightening.stderr
index f818a14cbe6..5fc66279f00 100644
--- a/src/tools/clippy/tests/ui/significant_drop_tightening.stderr
+++ b/src/tools/clippy/tests/ui/significant_drop_tightening.stderr
@@ -64,7 +64,6 @@ LL +         let rslt0 = mutex.lock().unwrap().abs();
 help: remove separated single usage
    |
 LL -         let rslt0 = lock.abs();
-LL +         
    |
 
 error: temporary with significant `Drop` can be early dropped
@@ -88,7 +87,6 @@ LL +         mutex.lock().unwrap().clear();
 help: remove separated single usage
    |
 LL -         lock.clear();
-LL +         
    |
 
 error: aborting due to 4 previous errors
diff --git a/src/tools/jsondocck/src/cache.rs b/src/tools/jsondocck/src/cache.rs
index 50697d46b8c..5f72bd171a1 100644
--- a/src/tools/jsondocck/src/cache.rs
+++ b/src/tools/jsondocck/src/cache.rs
@@ -23,7 +23,7 @@ impl Cache {
 
         Cache {
             value: serde_json::from_str::<Value>(&content).expect("failed to convert from JSON"),
-            variables: HashMap::new(),
+            variables: HashMap::from([("FILE".to_owned(), config.template.clone().into())]),
         }
     }
 
diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs
index 054836e87cf..885b361f72a 100644
--- a/src/tools/run-make-support/src/rustc.rs
+++ b/src/tools/run-make-support/src/rustc.rs
@@ -108,7 +108,11 @@ impl Rustc {
     }
 
     /// Remap source path prefixes in all output.
-    pub fn remap_path_prefix<P: AsRef<Path>>(&mut self, from: P, to: P) -> &mut Self {
+    pub fn remap_path_prefix<P: AsRef<Path>, P2: AsRef<Path>>(
+        &mut self,
+        from: P,
+        to: P2,
+    ) -> &mut Self {
         let from = from.as_ref().to_string_lossy();
         let to = to.as_ref().to_string_lossy();
 
diff --git a/src/tools/tidy/src/run_make_tests.rs b/src/tools/tidy/src/run_make_tests.rs
index 2d9f8448a35..8d176787837 100644
--- a/src/tools/tidy/src/run_make_tests.rs
+++ b/src/tools/tidy/src/run_make_tests.rs
@@ -95,7 +95,7 @@ pub fn check(tests_path: &Path, src_path: &Path, bless: bool, bad: &mut bool) {
             tidy_error!(
                 bad,
                 "Makefile `{}` no longer exists and should be removed from the exclusions in \
-                `src/tools/tidy/src/allowed_run_make_makefiles.txt`, you can run --bless to update \
+                `src/tools/tidy/src/allowed_run_make_makefiles.txt`, you can run `x test tidy --bless` to update \
                 the allow list",
                 p.display()
             );
diff --git a/tests/rustdoc-ui/diagnostic-width.stderr b/tests/rustdoc-ui/diagnostic-width.stderr
index c1cc4898ac5..d8c4934a576 100644
--- a/tests/rustdoc-ui/diagnostic-width.stderr
+++ b/tests/rustdoc-ui/diagnostic-width.stderr
@@ -2,7 +2,7 @@ error: this URL is not a hyperlink
   --> $DIR/diagnostic-width.rs:4:41
    |
 LL | ... a http://link.com
-   |       ^^^^^^^^^^^^^^^ help: use an automatic link instead: `<http://link.com>`
+   |       ^^^^^^^^^^^^^^^
    |
    = note: bare URLs are not automatically turned into clickable links
 note: the lint level is defined here
@@ -10,6 +10,10 @@ note: the lint level is defined here
    |
 LL | ...ny(rustdoc::bare_url...
    |       ^^^^^^^^^^^^^^^^^^
+help: use an automatic link instead
+   |
+LL | /// This is a long line that contains a <http://link.com>
+   |                                         +               +
 
 error: aborting due to 1 previous error
 
diff --git a/tests/rustdoc-ui/include-str-bare-urls.stderr b/tests/rustdoc-ui/include-str-bare-urls.stderr
index a4234196b23..53da2411874 100644
--- a/tests/rustdoc-ui/include-str-bare-urls.stderr
+++ b/tests/rustdoc-ui/include-str-bare-urls.stderr
@@ -2,7 +2,7 @@ error: this URL is not a hyperlink
   --> $DIR/auxiliary/include-str-bare-urls.md:1:11
    |
 LL | HEADS UP! https://example.com MUST SHOW UP IN THE STDERR FILE!
-   |           ^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://example.com>`
+   |           ^^^^^^^^^^^^^^^^^^^
    |
    = note: bare URLs are not automatically turned into clickable links
 note: the lint level is defined here
@@ -10,6 +10,10 @@ note: the lint level is defined here
    |
 LL | #![deny(rustdoc::bare_urls)]
    |         ^^^^^^^^^^^^^^^^^^
+help: use an automatic link instead
+   |
+LL | HEADS UP! <https://example.com> MUST SHOW UP IN THE STDERR FILE!
+   |           +                   +
 
 error: aborting due to 1 previous error
 
diff --git a/tests/rustdoc-ui/lints/bare-urls.stderr b/tests/rustdoc-ui/lints/bare-urls.stderr
index ccf52cd0b93..ddfc387eaf6 100644
--- a/tests/rustdoc-ui/lints/bare-urls.stderr
+++ b/tests/rustdoc-ui/lints/bare-urls.stderr
@@ -2,7 +2,7 @@ error: this URL is not a hyperlink
   --> $DIR/bare-urls.rs:5:5
    |
 LL | /// https://somewhere.com
-   |     ^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com>`
+   |     ^^^^^^^^^^^^^^^^^^^^^
    |
    = note: bare URLs are not automatically turned into clickable links
 note: the lint level is defined here
@@ -10,134 +10,202 @@ note: the lint level is defined here
    |
 LL | #![deny(rustdoc::bare_urls)]
    |         ^^^^^^^^^^^^^^^^^^
+help: use an automatic link instead
+   |
+LL | /// <https://somewhere.com>
+   |     +                     +
 
 error: this URL is not a hyperlink
   --> $DIR/bare-urls.rs:7:5
    |
 LL | /// https://somewhere.com/a
-   |     ^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com/a>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: bare URLs are not automatically turned into clickable links
+help: use an automatic link instead
+   |
+LL | /// <https://somewhere.com/a>
+   |     +                       +
 
 error: this URL is not a hyperlink
   --> $DIR/bare-urls.rs:9:5
    |
 LL | /// https://www.somewhere.com
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://www.somewhere.com>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: bare URLs are not automatically turned into clickable links
+help: use an automatic link instead
+   |
+LL | /// <https://www.somewhere.com>
+   |     +                         +
 
 error: this URL is not a hyperlink
   --> $DIR/bare-urls.rs:11:5
    |
 LL | /// https://www.somewhere.com/a
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://www.somewhere.com/a>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: bare URLs are not automatically turned into clickable links
+help: use an automatic link instead
+   |
+LL | /// <https://www.somewhere.com/a>
+   |     +                           +
 
 error: this URL is not a hyperlink
   --> $DIR/bare-urls.rs:13:5
    |
 LL | /// https://subdomain.example.com
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://subdomain.example.com>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: bare URLs are not automatically turned into clickable links
+help: use an automatic link instead
+   |
+LL | /// <https://subdomain.example.com>
+   |     +                             +
 
 error: this URL is not a hyperlink
   --> $DIR/bare-urls.rs:15:5
    |
 LL | /// https://somewhere.com?
-   |     ^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com?>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: bare URLs are not automatically turned into clickable links
+help: use an automatic link instead
+   |
+LL | /// <https://somewhere.com?>
+   |     +                      +
 
 error: this URL is not a hyperlink
   --> $DIR/bare-urls.rs:17:5
    |
 LL | /// https://somewhere.com/a?
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com/a?>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: bare URLs are not automatically turned into clickable links
+help: use an automatic link instead
+   |
+LL | /// <https://somewhere.com/a?>
+   |     +                        +
 
 error: this URL is not a hyperlink
   --> $DIR/bare-urls.rs:19:5
    |
 LL | /// https://somewhere.com?hello=12
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com?hello=12>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: bare URLs are not automatically turned into clickable links
+help: use an automatic link instead
+   |
+LL | /// <https://somewhere.com?hello=12>
+   |     +                              +
 
 error: this URL is not a hyperlink
   --> $DIR/bare-urls.rs:21:5
    |
 LL | /// https://somewhere.com/a?hello=12
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com/a?hello=12>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: bare URLs are not automatically turned into clickable links
+help: use an automatic link instead
+   |
+LL | /// <https://somewhere.com/a?hello=12>
+   |     +                                +
 
 error: this URL is not a hyperlink
   --> $DIR/bare-urls.rs:23:5
    |
 LL | /// https://example.com?hello=12#xyz
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://example.com?hello=12#xyz>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: bare URLs are not automatically turned into clickable links
+help: use an automatic link instead
+   |
+LL | /// <https://example.com?hello=12#xyz>
+   |     +                                +
 
 error: this URL is not a hyperlink
   --> $DIR/bare-urls.rs:25:5
    |
 LL | /// https://example.com/a?hello=12#xyz
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://example.com/a?hello=12#xyz>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: bare URLs are not automatically turned into clickable links
+help: use an automatic link instead
+   |
+LL | /// <https://example.com/a?hello=12#xyz>
+   |     +                                  +
 
 error: this URL is not a hyperlink
   --> $DIR/bare-urls.rs:27:5
    |
 LL | /// https://example.com#xyz
-   |     ^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://example.com#xyz>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: bare URLs are not automatically turned into clickable links
+help: use an automatic link instead
+   |
+LL | /// <https://example.com#xyz>
+   |     +                       +
 
 error: this URL is not a hyperlink
   --> $DIR/bare-urls.rs:29:5
    |
 LL | /// https://example.com/a#xyz
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://example.com/a#xyz>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: bare URLs are not automatically turned into clickable links
+help: use an automatic link instead
+   |
+LL | /// <https://example.com/a#xyz>
+   |     +                         +
 
 error: this URL is not a hyperlink
   --> $DIR/bare-urls.rs:31:5
    |
 LL | /// https://somewhere.com?hello=12&bye=11
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com?hello=12&bye=11>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: bare URLs are not automatically turned into clickable links
+help: use an automatic link instead
+   |
+LL | /// <https://somewhere.com?hello=12&bye=11>
+   |     +                                     +
 
 error: this URL is not a hyperlink
   --> $DIR/bare-urls.rs:33:5
    |
 LL | /// https://somewhere.com/a?hello=12&bye=11
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com/a?hello=12&bye=11>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: bare URLs are not automatically turned into clickable links
+help: use an automatic link instead
+   |
+LL | /// <https://somewhere.com/a?hello=12&bye=11>
+   |     +                                       +
 
 error: this URL is not a hyperlink
   --> $DIR/bare-urls.rs:35:5
    |
 LL | /// https://somewhere.com?hello=12&bye=11#xyz
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com?hello=12&bye=11#xyz>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: bare URLs are not automatically turned into clickable links
+help: use an automatic link instead
+   |
+LL | /// <https://somewhere.com?hello=12&bye=11#xyz>
+   |     +                                         +
 
 error: this URL is not a hyperlink
   --> $DIR/bare-urls.rs:37:10
    |
 LL | /// hey! https://somewhere.com/a?hello=12&bye=11#xyz
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com/a?hello=12&bye=11#xyz>`
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: bare URLs are not automatically turned into clickable links
+help: use an automatic link instead
+   |
+LL | /// hey! <https://somewhere.com/a?hello=12&bye=11#xyz>
+   |          +                                           +
 
 error: aborting due to 17 previous errors
 
diff --git a/tests/rustdoc-ui/lints/renamed-lint-still-applies.stderr b/tests/rustdoc-ui/lints/renamed-lint-still-applies.stderr
index ee9b67cb91b..88807dfb495 100644
--- a/tests/rustdoc-ui/lints/renamed-lint-still-applies.stderr
+++ b/tests/rustdoc-ui/lints/renamed-lint-still-applies.stderr
@@ -29,7 +29,7 @@ error: this URL is not a hyperlink
   --> $DIR/renamed-lint-still-applies.rs:9:5
    |
 LL | //! http://example.com
-   |     ^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<http://example.com>`
+   |     ^^^^^^^^^^^^^^^^^^
    |
    = note: bare URLs are not automatically turned into clickable links
 note: the lint level is defined here
@@ -37,6 +37,10 @@ note: the lint level is defined here
    |
 LL | #![deny(rustdoc::non_autolinks)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
+help: use an automatic link instead
+   |
+LL | //! <http://example.com>
+   |     +                  +
 
 error: aborting due to 2 previous errors; 2 warnings emitted
 
diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs
index 1be9ada2822..ca78604edd8 100644
--- a/tests/ui/abi/compatibility.rs
+++ b/tests/ui/abi/compatibility.rs
@@ -271,6 +271,11 @@ test_abi_compatible!(zst_unit, Zst, ());
 test_abi_compatible!(zst_array, Zst, [u8; 0]);
 test_abi_compatible!(nonzero_int, NonZero<i32>, i32);
 
+// `#[repr(C)]` enums should not change ABI based on individual variant inhabitedness.
+// (However, this is *not* a guarantee. We only guarantee same layout, not same ABI.)
+enum Void {}
+test_abi_compatible!(repr_c_enum_void, ReprCEnum<Void>, ReprCEnum<ReprCUnion<Void>>);
+
 // `DispatchFromDyn` relies on ABI compatibility.
 // This is interesting since these types are not `repr(transparent)`. So this is not part of our
 // public ABI guarantees, but is relied on by the compiler.
diff --git a/tests/ui/assign-imm-local-twice.rs b/tests/ui/assign-imm-local-twice.rs
index b50f6ab5deb..b2dfeb564d9 100644
--- a/tests/ui/assign-imm-local-twice.rs
+++ b/tests/ui/assign-imm-local-twice.rs
@@ -1,7 +1,7 @@
 fn test() {
     let v: isize;
     //~^ HELP consider making this binding mutable
-    //~| SUGGESTION mut v
+    //~| SUGGESTION mut
     v = 1; //~ NOTE first assignment
     println!("v={}", v);
     v = 2; //~ ERROR cannot assign twice to immutable variable
diff --git a/tests/ui/assign-imm-local-twice.stderr b/tests/ui/assign-imm-local-twice.stderr
index d92485de68f..fda3aa3de1b 100644
--- a/tests/ui/assign-imm-local-twice.stderr
+++ b/tests/ui/assign-imm-local-twice.stderr
@@ -1,14 +1,16 @@
 error[E0384]: cannot assign twice to immutable variable `v`
   --> $DIR/assign-imm-local-twice.rs:7:5
    |
-LL |     let v: isize;
-   |         - help: consider making this binding mutable: `mut v`
-...
 LL |     v = 1;
    |     ----- first assignment to `v`
 LL |     println!("v={}", v);
 LL |     v = 2;
    |     ^^^^^ cannot assign twice to immutable variable
+   |
+help: consider making this binding mutable
+   |
+LL |     let mut v: isize;
+   |         +++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/associated-types/issue-22560.stderr b/tests/ui/associated-types/issue-22560.stderr
index 46e6e3951a5..834040490f9 100644
--- a/tests/ui/associated-types/issue-22560.stderr
+++ b/tests/ui/associated-types/issue-22560.stderr
@@ -35,9 +35,13 @@ LL | trait Add<Rhs=Self> {
    | ------------------- type parameter `Rhs` must be specified for this
 ...
 LL | type Test = dyn Add + Sub;
-   |                 ^^^ help: set the type parameter to the desired type: `Add<Rhs>`
+   |                 ^^^
    |
    = note: because of the default `Self` reference, type parameters must be specified on object types
+help: set the type parameter to the desired type
+   |
+LL | type Test = dyn Add<Rhs> + Sub;
+   |                    +++++
 
 error[E0393]: the type parameter `Rhs` must be explicitly specified
   --> $DIR/issue-22560.rs:9:23
@@ -46,9 +50,13 @@ LL | trait Sub<Rhs=Self> {
    | ------------------- type parameter `Rhs` must be specified for this
 ...
 LL | type Test = dyn Add + Sub;
-   |                       ^^^ help: set the type parameter to the desired type: `Sub<Rhs>`
+   |                       ^^^
    |
    = note: because of the default `Self` reference, type parameters must be specified on object types
+help: set the type parameter to the desired type
+   |
+LL | type Test = dyn Add + Sub<Rhs>;
+   |                          +++++
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/async-await/issue-61452.stderr b/tests/ui/async-await/issue-61452.stderr
index 3f623ba8ad2..b7b1e380c9e 100644
--- a/tests/ui/async-await/issue-61452.stderr
+++ b/tests/ui/async-await/issue-61452.stderr
@@ -13,12 +13,14 @@ error[E0384]: cannot assign twice to immutable variable `x`
   --> $DIR/issue-61452.rs:9:5
    |
 LL | pub async fn g(x: usize) {
-   |                -
-   |                |
-   |                first assignment to `x`
-   |                help: consider making this binding mutable: `mut x`
+   |                - first assignment to `x`
 LL |     x += 1;
    |     ^^^^^^ cannot assign twice to immutable variable
+   |
+help: consider making this binding mutable
+   |
+LL | pub async fn g(mut x: usize) {
+   |                +++
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/borrowck/borrow-raw-address-of-mutability.stderr b/tests/ui/borrowck/borrow-raw-address-of-mutability.stderr
index a7748209187..4b5b368287e 100644
--- a/tests/ui/borrowck/borrow-raw-address-of-mutability.stderr
+++ b/tests/ui/borrowck/borrow-raw-address-of-mutability.stderr
@@ -12,11 +12,13 @@ LL |     let mut x = 0;
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/borrow-raw-address-of-mutability.rs:11:17
    |
-LL |     let x = 0;
-   |         - help: consider changing this to be mutable: `mut x`
-LL |     let mut f = || {
 LL |         let y = &raw mut x;
    |                 ^^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut x = 0;
+   |         +++
 
 error[E0596]: cannot borrow `f` as mutable, as it is not declared as mutable
   --> $DIR/borrow-raw-address-of-mutability.rs:21:5
diff --git a/tests/ui/borrowck/borrowck-closures-unique.stderr b/tests/ui/borrowck/borrowck-closures-unique.stderr
index 23d3cc0e76f..613df9f2100 100644
--- a/tests/ui/borrowck/borrowck-closures-unique.stderr
+++ b/tests/ui/borrowck/borrowck-closures-unique.stderr
@@ -43,10 +43,13 @@ LL |     c1;
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
   --> $DIR/borrowck-closures-unique.rs:43:38
    |
-LL | fn e(x: &'static mut isize) {
-   |      - help: consider changing this to be mutable: `mut x`
 LL |     let c1 = |y: &'static mut isize| x = y;
    |                                      ^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL | fn e(mut x: &'static mut isize) {
+   |      +++
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/borrowck/borrowck-match-binding-is-assignment.stderr b/tests/ui/borrowck/borrowck-match-binding-is-assignment.stderr
index 98ffa7f6ffa..e164ea44aa4 100644
--- a/tests/ui/borrowck/borrowck-match-binding-is-assignment.stderr
+++ b/tests/ui/borrowck/borrowck-match-binding-is-assignment.stderr
@@ -9,11 +9,11 @@ LL |             x += 1;
 help: consider making this binding mutable
    |
 LL |         mut x => {
-   |         ~~~~~
+   |         +++
 help: to modify the original value, take a borrow instead
    |
 LL |         ref mut x => {
-   |         ~~~~~~~~~
+   |         +++++++
 
 error[E0384]: cannot assign twice to immutable variable `x`
   --> $DIR/borrowck-match-binding-is-assignment.rs:20:13
@@ -26,11 +26,11 @@ LL |             x += 1;
 help: consider making this binding mutable
    |
 LL |         E::Foo(mut x) => {
-   |                ~~~~~
+   |                +++
 help: to modify the original value, take a borrow instead
    |
 LL |         E::Foo(ref mut x) => {
-   |                ~~~~~~~~~
+   |                +++++++
 
 error[E0384]: cannot assign twice to immutable variable `x`
   --> $DIR/borrowck-match-binding-is-assignment.rs:26:13
@@ -43,11 +43,11 @@ LL |             x += 1;
 help: consider making this binding mutable
    |
 LL |         S { bar: mut x } => {
-   |                  ~~~~~
+   |                  +++
 help: to modify the original value, take a borrow instead
    |
 LL |         S { bar: ref mut x } => {
-   |                  ~~~~~~~~~
+   |                  +++++++
 
 error[E0384]: cannot assign twice to immutable variable `x`
   --> $DIR/borrowck-match-binding-is-assignment.rs:32:13
@@ -60,11 +60,11 @@ LL |             x += 1;
 help: consider making this binding mutable
    |
 LL |         (mut x,) => {
-   |          ~~~~~
+   |          +++
 help: to modify the original value, take a borrow instead
    |
 LL |         (ref mut x,) => {
-   |          ~~~~~~~~~
+   |          +++++++
 
 error[E0384]: cannot assign twice to immutable variable `x`
   --> $DIR/borrowck-match-binding-is-assignment.rs:38:13
@@ -77,11 +77,11 @@ LL |             x += 1;
 help: consider making this binding mutable
    |
 LL |         [mut x,_,_] => {
-   |          ~~~~~
+   |          +++
 help: to modify the original value, take a borrow instead
    |
 LL |         [ref mut x,_,_] => {
-   |          ~~~~~~~~~
+   |          +++++++
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/borrowck/immutable-arg.stderr b/tests/ui/borrowck/immutable-arg.stderr
index 84a480f6410..fb75172532f 100644
--- a/tests/ui/borrowck/immutable-arg.stderr
+++ b/tests/ui/borrowck/immutable-arg.stderr
@@ -1,10 +1,13 @@
 error[E0384]: cannot assign to immutable argument `_x`
   --> $DIR/immutable-arg.rs:2:5
    |
-LL | fn foo(_x: u32) {
-   |        -- help: consider making this binding mutable: `mut _x`
 LL |     _x = 4;
    |     ^^^^^^ cannot assign to immutable argument
+   |
+help: consider making this binding mutable
+   |
+LL | fn foo(mut _x: u32) {
+   |        +++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/borrowck/issue-111554.stderr b/tests/ui/borrowck/issue-111554.stderr
index 6b7a42e4959..b3e8caae343 100644
--- a/tests/ui/borrowck/issue-111554.stderr
+++ b/tests/ui/borrowck/issue-111554.stderr
@@ -19,10 +19,13 @@ LL |         || bar(&mut self);
 error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
   --> $DIR/issue-111554.rs:21:16
    |
-LL |     pub fn quux(self) {
-   |                 ---- help: consider changing this to be mutable: `mut self`
 LL |         || bar(&mut self);
    |                ^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     pub fn quux(mut self) {
+   |                 +++
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/borrowck/issue-33819.stderr b/tests/ui/borrowck/issue-33819.stderr
index 41c9d6aac76..e5f6df26bc1 100644
--- a/tests/ui/borrowck/issue-33819.stderr
+++ b/tests/ui/borrowck/issue-33819.stderr
@@ -2,10 +2,13 @@ error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
   --> $DIR/issue-33819.rs:4:34
    |
 LL |         Some(ref v) => { let a = &mut v; },
-   |                                  ^^^^^^
-   |                                  |
-   |                                  cannot borrow as mutable
-   |                                  help: try removing `&mut` here
+   |                                  ^^^^^^ cannot borrow as mutable
+   |
+help: try removing `&mut` here
+   |
+LL -         Some(ref v) => { let a = &mut v; },
+LL +         Some(ref v) => { let a = v; },
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/borrowck/issue-45199.rs b/tests/ui/borrowck/issue-45199.rs
index ded46e56e34..b38967524fa 100644
--- a/tests/ui/borrowck/issue-45199.rs
+++ b/tests/ui/borrowck/issue-45199.rs
@@ -1,7 +1,7 @@
 fn test_drop_replace() {
     let b: Box<isize>;
     //~^ HELP consider making this binding mutable
-    //~| SUGGESTION mut b
+    //~| SUGGESTION mut
     b = Box::new(1);    //~ NOTE first assignment
     b = Box::new(2);    //~ ERROR cannot assign twice to immutable variable `b`
                         //~| NOTE cannot assign twice to immutable
@@ -10,13 +10,13 @@ fn test_drop_replace() {
 fn test_call() {
     let b = Box::new(1);    //~ NOTE first assignment
                             //~| HELP consider making this binding mutable
-                            //~| SUGGESTION mut b
+                            //~| SUGGESTION mut
     b = Box::new(2);        //~ ERROR cannot assign twice to immutable variable `b`
                             //~| NOTE cannot assign twice to immutable
 }
 
 fn test_args(b: Box<i32>) {  //~ HELP consider making this binding mutable
-                                //~| SUGGESTION mut b
+                                //~| SUGGESTION mut
     b = Box::new(2);            //~ ERROR cannot assign to immutable argument `b`
                                 //~| NOTE cannot assign to immutable argument
 }
diff --git a/tests/ui/borrowck/issue-45199.stderr b/tests/ui/borrowck/issue-45199.stderr
index 47aa3090827..8886e618e18 100644
--- a/tests/ui/borrowck/issue-45199.stderr
+++ b/tests/ui/borrowck/issue-45199.stderr
@@ -1,34 +1,40 @@
 error[E0384]: cannot assign twice to immutable variable `b`
   --> $DIR/issue-45199.rs:6:5
    |
-LL |     let b: Box<isize>;
-   |         - help: consider making this binding mutable: `mut b`
-...
 LL |     b = Box::new(1);
    |     - first assignment to `b`
 LL |     b = Box::new(2);
    |     ^ cannot assign twice to immutable variable
+   |
+help: consider making this binding mutable
+   |
+LL |     let mut b: Box<isize>;
+   |         +++
 
 error[E0384]: cannot assign twice to immutable variable `b`
   --> $DIR/issue-45199.rs:14:5
    |
 LL |     let b = Box::new(1);
-   |         -
-   |         |
-   |         first assignment to `b`
-   |         help: consider making this binding mutable: `mut b`
+   |         - first assignment to `b`
 ...
 LL |     b = Box::new(2);
    |     ^ cannot assign twice to immutable variable
+   |
+help: consider making this binding mutable
+   |
+LL |     let mut b = Box::new(1);
+   |         +++
 
 error[E0384]: cannot assign to immutable argument `b`
   --> $DIR/issue-45199.rs:20:5
    |
-LL | fn test_args(b: Box<i32>) {
-   |              - help: consider making this binding mutable: `mut b`
-LL |
 LL |     b = Box::new(2);
    |     ^ cannot assign to immutable argument
+   |
+help: consider making this binding mutable
+   |
+LL | fn test_args(mut b: Box<i32>) {
+   |              +++
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.stderr b/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.stderr
index 098a2964e9f..ff5ec1db346 100644
--- a/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.stderr
+++ b/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.stderr
@@ -44,56 +44,68 @@ LL |         borrowck_closures_unique::e(addr_of_mut!(X));
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
   --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:9:46
    |
-LL |     pub fn e(x: &'static mut isize) {
-   |              - help: consider changing this to be mutable: `mut x`
-LL |         static mut Y: isize = 3;
 LL |         let mut c1 = |y: &'static mut isize| x = y;
    |                                              ^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |     pub fn e(mut x: &'static mut isize) {
+   |              +++
 
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
   --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:22:50
    |
-LL |     pub fn ee(x: &'static mut isize) {
-   |               - help: consider changing this to be mutable: `mut x`
-...
 LL |             let mut c2 = |y: &'static mut isize| x = y;
    |                                                  ^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |     pub fn ee(mut x: &'static mut isize) {
+   |               +++
 
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
   --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:37:13
    |
-LL |     pub fn capture_assign_whole(x: (i32,)) {
-   |                                 - help: consider changing this to be mutable: `mut x`
-LL |         || {
 LL |             x = (1,);
    |             ^^^^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |     pub fn capture_assign_whole(mut x: (i32,)) {
+   |                                 +++
 
 error[E0594]: cannot assign to `x.0`, as `x` is not declared as mutable
   --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:43:13
    |
-LL |     pub fn capture_assign_part(x: (i32,)) {
-   |                                - help: consider changing this to be mutable: `mut x`
-LL |         || {
 LL |             x.0 = 1;
    |             ^^^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |     pub fn capture_assign_part(mut x: (i32,)) {
+   |                                +++
 
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:49:13
    |
-LL |     pub fn capture_reborrow_whole(x: (i32,)) {
-   |                                   - help: consider changing this to be mutable: `mut x`
-LL |         || {
 LL |             &mut x;
    |             ^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     pub fn capture_reborrow_whole(mut x: (i32,)) {
+   |                                   +++
 
 error[E0596]: cannot borrow `x.0` as mutable, as `x` is not declared as mutable
   --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:55:13
    |
-LL |     pub fn capture_reborrow_part(x: (i32,)) {
-   |                                  - help: consider changing this to be mutable: `mut x`
-LL |         || {
 LL |             &mut x.0;
    |             ^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     pub fn capture_reborrow_part(mut x: (i32,)) {
+   |                                  +++
 
 error: aborting due to 6 previous errors; 3 warnings emitted
 
diff --git a/tests/ui/borrowck/mutability-errors.stderr b/tests/ui/borrowck/mutability-errors.stderr
index b39e57d70ec..3cab3ccb993 100644
--- a/tests/ui/borrowck/mutability-errors.stderr
+++ b/tests/ui/borrowck/mutability-errors.stderr
@@ -262,74 +262,90 @@ LL | fn imm_local(mut x: (i32,)) {
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
   --> $DIR/mutability-errors.rs:60:9
    |
-LL | fn imm_capture(x: (i32,)) {
-   |                - help: consider changing this to be mutable: `mut x`
-LL |     || {
 LL |         x = (1,);
    |         ^^^^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL | fn imm_capture(mut x: (i32,)) {
+   |                +++
 
 error[E0594]: cannot assign to `x.0`, as `x` is not declared as mutable
   --> $DIR/mutability-errors.rs:61:9
    |
-LL | fn imm_capture(x: (i32,)) {
-   |                - help: consider changing this to be mutable: `mut x`
-...
 LL |         x.0 = 1;
    |         ^^^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL | fn imm_capture(mut x: (i32,)) {
+   |                +++
 
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/mutability-errors.rs:62:9
    |
-LL | fn imm_capture(x: (i32,)) {
-   |                - help: consider changing this to be mutable: `mut x`
-...
 LL |         &mut x;
    |         ^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL | fn imm_capture(mut x: (i32,)) {
+   |                +++
 
 error[E0596]: cannot borrow `x.0` as mutable, as `x` is not declared as mutable
   --> $DIR/mutability-errors.rs:63:9
    |
-LL | fn imm_capture(x: (i32,)) {
-   |                - help: consider changing this to be mutable: `mut x`
-...
 LL |         &mut x.0;
    |         ^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL | fn imm_capture(mut x: (i32,)) {
+   |                +++
 
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
   --> $DIR/mutability-errors.rs:66:9
    |
-LL | fn imm_capture(x: (i32,)) {
-   |                - help: consider changing this to be mutable: `mut x`
-...
 LL |         x = (1,);
    |         ^^^^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL | fn imm_capture(mut x: (i32,)) {
+   |                +++
 
 error[E0594]: cannot assign to `x.0`, as `x` is not declared as mutable
   --> $DIR/mutability-errors.rs:67:9
    |
-LL | fn imm_capture(x: (i32,)) {
-   |                - help: consider changing this to be mutable: `mut x`
-...
 LL |         x.0 = 1;
    |         ^^^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL | fn imm_capture(mut x: (i32,)) {
+   |                +++
 
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/mutability-errors.rs:68:9
    |
-LL | fn imm_capture(x: (i32,)) {
-   |                - help: consider changing this to be mutable: `mut x`
-...
 LL |         &mut x;
    |         ^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL | fn imm_capture(mut x: (i32,)) {
+   |                +++
 
 error[E0596]: cannot borrow `x.0` as mutable, as `x` is not declared as mutable
   --> $DIR/mutability-errors.rs:69:9
    |
-LL | fn imm_capture(x: (i32,)) {
-   |                - help: consider changing this to be mutable: `mut x`
-...
 LL |         &mut x.0;
    |         ^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL | fn imm_capture(mut x: (i32,)) {
+   |                +++
 
 error[E0594]: cannot assign to immutable static item `X`
   --> $DIR/mutability-errors.rs:76:5
diff --git a/tests/ui/borrowck/suggest-ref-mut-issue-118596.stderr b/tests/ui/borrowck/suggest-ref-mut-issue-118596.stderr
index fd2a775a099..aec3d663160 100644
--- a/tests/ui/borrowck/suggest-ref-mut-issue-118596.stderr
+++ b/tests/ui/borrowck/suggest-ref-mut-issue-118596.stderr
@@ -9,11 +9,11 @@ LL |         x = 2;
 help: consider making this binding mutable
    |
 LL |     if let Some(mut x) = y {
-   |                 ~~~~~
+   |                 +++
 help: to modify the original value, take a borrow instead
    |
 LL |     if let Some(ref mut x) = y {
-   |                 ~~~~~~~~~
+   |                 +++++++
 
 error[E0384]: cannot assign twice to immutable variable `x`
   --> $DIR/suggest-ref-mut-issue-118596.rs:9:5
@@ -26,11 +26,11 @@ LL |     x = 0;
 help: consider making this binding mutable
    |
 LL |     let [mut x, ref xs_hold @ ..] = arr;
-   |          ~~~~~
+   |          +++
 help: to modify the original value, take a borrow instead
    |
 LL |     let [ref mut x, ref xs_hold @ ..] = arr;
-   |          ~~~~~~~~~
+   |          +++++++
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/borrowck/tainted-promoteds.stderr b/tests/ui/borrowck/tainted-promoteds.stderr
index a5c448fdcdb..04669a29097 100644
--- a/tests/ui/borrowck/tainted-promoteds.stderr
+++ b/tests/ui/borrowck/tainted-promoteds.stderr
@@ -2,12 +2,14 @@ error[E0384]: cannot assign twice to immutable variable `a`
   --> $DIR/tainted-promoteds.rs:7:5
    |
 LL |     let a = 0;
-   |         -
-   |         |
-   |         first assignment to `a`
-   |         help: consider making this binding mutable: `mut a`
+   |         - first assignment to `a`
 LL |     a = &0 * &1 * &2 * &3;
    |     ^^^^^^^^^^^^^^^^^^^^^ cannot assign twice to immutable variable
+   |
+help: consider making this binding mutable
+   |
+LL |     let mut a = 0;
+   |         +++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/cannot-mutate-captured-non-mut-var.stderr b/tests/ui/cannot-mutate-captured-non-mut-var.stderr
index 2d6e83c9e82..8d794f8251f 100644
--- a/tests/ui/cannot-mutate-captured-non-mut-var.stderr
+++ b/tests/ui/cannot-mutate-captured-non-mut-var.stderr
@@ -1,18 +1,24 @@
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
   --> $DIR/cannot-mutate-captured-non-mut-var.rs:9:25
    |
-LL |     let x = 1;
-   |         - help: consider changing this to be mutable: `mut x`
 LL |     to_fn_once(move|| { x = 2; });
    |                         ^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut x = 1;
+   |         +++
 
 error[E0596]: cannot borrow `s` as mutable, as it is not declared as mutable
   --> $DIR/cannot-mutate-captured-non-mut-var.rs:13:25
    |
-LL |     let s = std::io::stdin();
-   |         - help: consider changing this to be mutable: `mut s`
 LL |     to_fn_once(move|| { s.read_to_end(&mut Vec::new()); });
    |                         ^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut s = std::io::stdin();
+   |         +++
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/closures/2229_closure_analysis/array_subslice.stderr b/tests/ui/closures/2229_closure_analysis/array_subslice.stderr
index 888c60d5e91..ee941caa773 100644
--- a/tests/ui/closures/2229_closure_analysis/array_subslice.stderr
+++ b/tests/ui/closures/2229_closure_analysis/array_subslice.stderr
@@ -1,11 +1,13 @@
 error[E0596]: cannot borrow `x[..]` as mutable, as `x` is not declared as mutable
   --> $DIR/array_subslice.rs:7:21
    |
-LL | pub fn subslice_array(x: [u8; 3]) {
-   |                       - help: consider changing this to be mutable: `mut x`
-...
 LL |         let [ref y, ref mut z @ ..] = x;
    |                     ^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL | pub fn subslice_array(mut x: [u8; 3]) {
+   |                       +++
 
 error[E0596]: cannot borrow `f` as mutable, as it is not declared as mutable
   --> $DIR/array_subslice.rs:10:5
diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.stderr
index 98414fa8a3d..6f5043ef08d 100644
--- a/tests/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.stderr
+++ b/tests/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.stderr
@@ -1,20 +1,24 @@
 error[E0594]: cannot assign to `z.0.0.0`, as it is not declared as mutable
   --> $DIR/cant-mutate-imm.rs:12:9
    |
-LL |     let z = (y, 10);
-   |         - help: consider changing this to be mutable: `mut z`
-...
 LL |         z.0.0.0 = 20;
    |         ^^^^^^^^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut z = (y, 10);
+   |         +++
 
 error[E0594]: cannot assign to `*bx.0`, as it is not declared as mutable
   --> $DIR/cant-mutate-imm.rs:24:9
    |
-LL |     let bx = Box::new(x);
-   |         -- help: consider changing this to be mutable: `mut bx`
-...
 LL |         bx.0 = 20;
    |         ^^^^^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut bx = Box::new(x);
+   |         +++
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/closures/closure-immutable-outer-variable.stderr b/tests/ui/closures/closure-immutable-outer-variable.stderr
index 23bd0020db6..c4b0e544957 100644
--- a/tests/ui/closures/closure-immutable-outer-variable.stderr
+++ b/tests/ui/closures/closure-immutable-outer-variable.stderr
@@ -1,10 +1,13 @@
 error[E0594]: cannot assign to `y`, as it is not declared as mutable
   --> $DIR/closure-immutable-outer-variable.rs:11:26
    |
-LL |     let y = true;
-   |         - help: consider changing this to be mutable: `mut y`
 LL |     foo(Box::new(move || y = !y) as Box<_>);
    |                          ^^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut y = true;
+   |         +++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/command-line-diagnostics.stderr b/tests/ui/command-line-diagnostics.stderr
index b719a00ad5d..6d33fb4172f 100644
--- a/tests/ui/command-line-diagnostics.stderr
+++ b/tests/ui/command-line-diagnostics.stderr
@@ -2,12 +2,14 @@ error[E0384]: cannot assign twice to immutable variable `x`
   --> $DIR/command-line-diagnostics.rs:6:5
    |
 LL |     let x = 42;
-   |         -
-   |         |
-   |         first assignment to `x`
-   |         help: consider making this binding mutable: `mut x`
+   |         - first assignment to `x`
 LL |     x = 43;
    |     ^^^^^^ cannot assign twice to immutable variable
+   |
+help: consider making this binding mutable
+   |
+LL |     let mut x = 42;
+   |         +++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr b/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr
index be79450a3ce..416a9381124 100644
--- a/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr
@@ -20,24 +20,32 @@ error[E0393]: the type parameter `Rhs` must be explicitly specified
   --> $DIR/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs:16:27
    |
 LL | ) -> impl Iterator<Item = SubAssign> {
-   |                           ^^^^^^^^^ help: set the type parameter to the desired type: `SubAssign<Rhs>`
+   |                           ^^^^^^^^^
   --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
    |
    = note: type parameter `Rhs` must be specified for this
    |
    = note: because of the default `Self` reference, type parameters must be specified on object types
+help: set the type parameter to the desired type
+   |
+LL | ) -> impl Iterator<Item = SubAssign<Rhs>> {
+   |                                    +++++
 
 error[E0393]: the type parameter `Rhs` must be explicitly specified
   --> $DIR/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs:16:27
    |
 LL | ) -> impl Iterator<Item = SubAssign> {
-   |                           ^^^^^^^^^ help: set the type parameter to the desired type: `SubAssign<Rhs>`
+   |                           ^^^^^^^^^
   --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
    |
    = note: type parameter `Rhs` must be specified for this
    |
    = note: because of the default `Self` reference, type parameters must be specified on object types
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: set the type parameter to the desired type
+   |
+LL | ) -> impl Iterator<Item = SubAssign<Rhs>> {
+   |                                    +++++
 
 error[E0277]: `()` is not an iterator
   --> $DIR/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs:16:6
diff --git a/tests/ui/consts/issue-39974.stderr b/tests/ui/consts/issue-39974.stderr
index 114c4cfeaf7..a371ea5709e 100644
--- a/tests/ui/consts/issue-39974.stderr
+++ b/tests/ui/consts/issue-39974.stderr
@@ -2,10 +2,12 @@ error[E0308]: mismatched types
   --> $DIR/issue-39974.rs:1:21
    |
 LL | const LENGTH: f64 = 2;
-   |                     ^
-   |                     |
-   |                     expected `f64`, found integer
-   |                     help: use a float literal: `2.0`
+   |                     ^ expected `f64`, found integer
+   |
+help: use a float literal
+   |
+LL | const LENGTH: f64 = 2.0;
+   |                      ++
 
 error[E0308]: mismatched types
   --> $DIR/issue-39974.rs:5:19
diff --git a/tests/ui/consts/slice_elem_ty_mismatch_in_unsizing_cast.rs b/tests/ui/consts/slice_elem_ty_mismatch_in_unsizing_cast.rs
new file mode 100644
index 00000000000..d821b6a0117
--- /dev/null
+++ b/tests/ui/consts/slice_elem_ty_mismatch_in_unsizing_cast.rs
@@ -0,0 +1,4 @@
+const FOO: &str = unsafe { &*(1_usize as *const [i64; 0] as *const [u8] as *const str) };
+//~^ ERROR: cannot cast
+
+fn main() {}
diff --git a/tests/ui/consts/slice_elem_ty_mismatch_in_unsizing_cast.stderr b/tests/ui/consts/slice_elem_ty_mismatch_in_unsizing_cast.stderr
new file mode 100644
index 00000000000..3b861d784d8
--- /dev/null
+++ b/tests/ui/consts/slice_elem_ty_mismatch_in_unsizing_cast.stderr
@@ -0,0 +1,9 @@
+error[E0607]: cannot cast thin pointer `*const [i64; 0]` to fat pointer `*const [u8]`
+  --> $DIR/slice_elem_ty_mismatch_in_unsizing_cast.rs:1:31
+   |
+LL | const FOO: &str = unsafe { &*(1_usize as *const [i64; 0] as *const [u8] as *const str) };
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0607`.
diff --git a/tests/ui/deriving/deriving-smart-pointer-neg.rs b/tests/ui/deriving/deriving-smart-pointer-neg.rs
new file mode 100644
index 00000000000..bfb4e86b396
--- /dev/null
+++ b/tests/ui/deriving/deriving-smart-pointer-neg.rs
@@ -0,0 +1,45 @@
+#![feature(derive_smart_pointer, arbitrary_self_types)]
+
+use std::marker::SmartPointer;
+
+#[derive(SmartPointer)]
+//~^ ERROR: `SmartPointer` can only be derived on `struct`s with `#[repr(transparent)]`
+enum NotStruct<'a, T: ?Sized> {
+    Variant(&'a T),
+}
+
+#[derive(SmartPointer)]
+//~^ ERROR: At least one generic type should be designated as `#[pointee]` in order to derive `SmartPointer` traits
+#[repr(transparent)]
+struct NoPointee<'a, T: ?Sized> {
+    ptr: &'a T,
+}
+
+#[derive(SmartPointer)]
+//~^ ERROR: `SmartPointer` can only be derived on `struct`s with at least one field
+#[repr(transparent)]
+struct NoField<'a, #[pointee] T: ?Sized> {}
+//~^ ERROR: lifetime parameter `'a` is never used
+//~| ERROR: type parameter `T` is never used
+
+#[derive(SmartPointer)]
+//~^ ERROR: `SmartPointer` can only be derived on `struct`s with at least one field
+#[repr(transparent)]
+struct NoFieldUnit<'a, #[pointee] T: ?Sized>();
+//~^ ERROR: lifetime parameter `'a` is never used
+//~| ERROR: type parameter `T` is never used
+
+#[derive(SmartPointer)]
+//~^ ERROR: `SmartPointer` can only be derived on `struct`s with `#[repr(transparent)]`
+struct NotTransparent<'a, #[pointee] T: ?Sized> {
+    ptr: &'a T,
+}
+
+// However, reordering attributes should work nevertheless.
+#[repr(transparent)]
+#[derive(SmartPointer)]
+struct ThisIsAPossibleSmartPointer<'a, #[pointee] T: ?Sized> {
+    ptr: &'a T,
+}
+
+fn main() {}
diff --git a/tests/ui/deriving/deriving-smart-pointer-neg.stderr b/tests/ui/deriving/deriving-smart-pointer-neg.stderr
new file mode 100644
index 00000000000..d994a6ee376
--- /dev/null
+++ b/tests/ui/deriving/deriving-smart-pointer-neg.stderr
@@ -0,0 +1,75 @@
+error: `SmartPointer` can only be derived on `struct`s with `#[repr(transparent)]`
+  --> $DIR/deriving-smart-pointer-neg.rs:5:10
+   |
+LL | #[derive(SmartPointer)]
+   |          ^^^^^^^^^^^^
+   |
+   = note: this error originates in the derive macro `SmartPointer` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: At least one generic type should be designated as `#[pointee]` in order to derive `SmartPointer` traits
+  --> $DIR/deriving-smart-pointer-neg.rs:11:10
+   |
+LL | #[derive(SmartPointer)]
+   |          ^^^^^^^^^^^^
+   |
+   = note: this error originates in the derive macro `SmartPointer` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: `SmartPointer` can only be derived on `struct`s with at least one field
+  --> $DIR/deriving-smart-pointer-neg.rs:18:10
+   |
+LL | #[derive(SmartPointer)]
+   |          ^^^^^^^^^^^^
+   |
+   = note: this error originates in the derive macro `SmartPointer` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: `SmartPointer` can only be derived on `struct`s with at least one field
+  --> $DIR/deriving-smart-pointer-neg.rs:25:10
+   |
+LL | #[derive(SmartPointer)]
+   |          ^^^^^^^^^^^^
+   |
+   = note: this error originates in the derive macro `SmartPointer` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: `SmartPointer` can only be derived on `struct`s with `#[repr(transparent)]`
+  --> $DIR/deriving-smart-pointer-neg.rs:32:10
+   |
+LL | #[derive(SmartPointer)]
+   |          ^^^^^^^^^^^^
+   |
+   = note: this error originates in the derive macro `SmartPointer` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0392]: lifetime parameter `'a` is never used
+  --> $DIR/deriving-smart-pointer-neg.rs:21:16
+   |
+LL | struct NoField<'a, #[pointee] T: ?Sized> {}
+   |                ^^ unused lifetime parameter
+   |
+   = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
+
+error[E0392]: type parameter `T` is never used
+  --> $DIR/deriving-smart-pointer-neg.rs:21:31
+   |
+LL | struct NoField<'a, #[pointee] T: ?Sized> {}
+   |                               ^ unused type parameter
+   |
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+
+error[E0392]: lifetime parameter `'a` is never used
+  --> $DIR/deriving-smart-pointer-neg.rs:28:20
+   |
+LL | struct NoFieldUnit<'a, #[pointee] T: ?Sized>();
+   |                    ^^ unused lifetime parameter
+   |
+   = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
+
+error[E0392]: type parameter `T` is never used
+  --> $DIR/deriving-smart-pointer-neg.rs:28:35
+   |
+LL | struct NoFieldUnit<'a, #[pointee] T: ?Sized>();
+   |                                   ^ unused type parameter
+   |
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+
+error: aborting due to 9 previous errors
+
+For more information about this error, try `rustc --explain E0392`.
diff --git a/tests/ui/deriving/deriving-smart-pointer.rs b/tests/ui/deriving/deriving-smart-pointer.rs
index cfc3369850b..d34a502da68 100644
--- a/tests/ui/deriving/deriving-smart-pointer.rs
+++ b/tests/ui/deriving/deriving-smart-pointer.rs
@@ -4,6 +4,7 @@
 use std::marker::SmartPointer;
 
 #[derive(SmartPointer)]
+#[repr(transparent)]
 struct MyPointer<'a, #[pointee] T: ?Sized> {
     ptr: &'a T,
 }
diff --git a/tests/ui/did_you_mean/issue-34337.stderr b/tests/ui/did_you_mean/issue-34337.stderr
index c727a565dbe..7bb651c47d0 100644
--- a/tests/ui/did_you_mean/issue-34337.stderr
+++ b/tests/ui/did_you_mean/issue-34337.stderr
@@ -2,10 +2,13 @@ error[E0596]: cannot borrow `key` as mutable, as it is not declared as mutable
   --> $DIR/issue-34337.rs:6:9
    |
 LL |     get(&mut key);
-   |         ^^^^^^^^
-   |         |
-   |         cannot borrow as mutable
-   |         help: try removing `&mut` here
+   |         ^^^^^^^^ cannot borrow as mutable
+   |
+help: try removing `&mut` here
+   |
+LL -     get(&mut key);
+LL +     get(key);
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/did_you_mean/issue-37139.stderr b/tests/ui/did_you_mean/issue-37139.stderr
index a07d83b31db..dbaab70d8bc 100644
--- a/tests/ui/did_you_mean/issue-37139.stderr
+++ b/tests/ui/did_you_mean/issue-37139.stderr
@@ -2,10 +2,13 @@ error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/issue-37139.rs:12:18
    |
 LL |             test(&mut x);
-   |                  ^^^^^^
-   |                  |
-   |                  cannot borrow as mutable
-   |                  help: try removing `&mut` here
+   |                  ^^^^^^ cannot borrow as mutable
+   |
+help: try removing `&mut` here
+   |
+LL -             test(&mut x);
+LL +             test(x);
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/did_you_mean/issue-53280-expected-float-found-integer-literal.stderr b/tests/ui/did_you_mean/issue-53280-expected-float-found-integer-literal.stderr
index 6f853ccab37..6e32483aee4 100644
--- a/tests/ui/did_you_mean/issue-53280-expected-float-found-integer-literal.stderr
+++ b/tests/ui/did_you_mean/issue-53280-expected-float-found-integer-literal.stderr
@@ -2,31 +2,40 @@ error[E0308]: mismatched types
   --> $DIR/issue-53280-expected-float-found-integer-literal.rs:2:24
    |
 LL |     let sixteen: f32 = 16;
-   |                  ---   ^^
-   |                  |     |
-   |                  |     expected `f32`, found integer
-   |                  |     help: use a float literal: `16.0`
+   |                  ---   ^^ expected `f32`, found integer
+   |                  |
    |                  expected due to this
+   |
+help: use a float literal
+   |
+LL |     let sixteen: f32 = 16.0;
+   |                          ++
 
 error[E0308]: mismatched types
   --> $DIR/issue-53280-expected-float-found-integer-literal.rs:5:38
    |
 LL |     let a_million_and_seventy: f64 = 1_000_070;
-   |                                ---   ^^^^^^^^^
-   |                                |     |
-   |                                |     expected `f64`, found integer
-   |                                |     help: use a float literal: `1_000_070.0`
+   |                                ---   ^^^^^^^^^ expected `f64`, found integer
+   |                                |
    |                                expected due to this
+   |
+help: use a float literal
+   |
+LL |     let a_million_and_seventy: f64 = 1_000_070.0;
+   |                                               ++
 
 error[E0308]: mismatched types
   --> $DIR/issue-53280-expected-float-found-integer-literal.rs:8:30
    |
 LL |     let negative_nine: f32 = -9;
-   |                        ---   ^^
-   |                        |     |
-   |                        |     expected `f32`, found integer
-   |                        |     help: use a float literal: `-9.0`
+   |                        ---   ^^ expected `f32`, found integer
+   |                        |
    |                        expected due to this
+   |
+help: use a float literal
+   |
+LL |     let negative_nine: f32 = -9.0;
+   |                                ++
 
 error[E0308]: mismatched types
   --> $DIR/issue-53280-expected-float-found-integer-literal.rs:15:30
diff --git a/tests/ui/error-codes/E0393.stderr b/tests/ui/error-codes/E0393.stderr
index 4083fa23e87..489398b7be5 100644
--- a/tests/ui/error-codes/E0393.stderr
+++ b/tests/ui/error-codes/E0393.stderr
@@ -5,9 +5,13 @@ LL | trait A<T=Self> {}
    | --------------- type parameter `T` must be specified for this
 LL |
 LL | fn together_we_will_rule_the_galaxy(son: &dyn A) {}
-   |                                               ^ help: set the type parameter to the desired type: `A<T>`
+   |                                               ^
    |
    = note: because of the default `Self` reference, type parameters must be specified on object types
+help: set the type parameter to the desired type
+   |
+LL | fn together_we_will_rule_the_galaxy(son: &dyn A<T>) {}
+   |                                                +++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/feature-gates/feature-gate-derive-smart-pointer.rs b/tests/ui/feature-gates/feature-gate-derive-smart-pointer.rs
index ae8005592cd..3257a9ca624 100644
--- a/tests/ui/feature-gates/feature-gate-derive-smart-pointer.rs
+++ b/tests/ui/feature-gates/feature-gate-derive-smart-pointer.rs
@@ -1,6 +1,7 @@
 use std::marker::SmartPointer; //~ ERROR use of unstable library feature 'derive_smart_pointer'
 
 #[derive(SmartPointer)] //~ ERROR use of unstable library feature 'derive_smart_pointer'
+#[repr(transparent)]
 struct MyPointer<'a, #[pointee] T: ?Sized> {
     //~^ ERROR the `#[pointee]` attribute is an experimental feature
     ptr: &'a T,
diff --git a/tests/ui/feature-gates/feature-gate-derive-smart-pointer.stderr b/tests/ui/feature-gates/feature-gate-derive-smart-pointer.stderr
index 0ffd82fb9e1..19501939dc5 100644
--- a/tests/ui/feature-gates/feature-gate-derive-smart-pointer.stderr
+++ b/tests/ui/feature-gates/feature-gate-derive-smart-pointer.stderr
@@ -9,7 +9,7 @@ LL | #[derive(SmartPointer)]
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: the `#[pointee]` attribute is an experimental feature
-  --> $DIR/feature-gate-derive-smart-pointer.rs:4:22
+  --> $DIR/feature-gate-derive-smart-pointer.rs:5:22
    |
 LL | struct MyPointer<'a, #[pointee] T: ?Sized> {
    |                      ^^^^^^^^^^
diff --git a/tests/ui/fn/suggest-return-closure.stderr b/tests/ui/fn/suggest-return-closure.stderr
index d276ce8be2b..45c12b548e6 100644
--- a/tests/ui/fn/suggest-return-closure.stderr
+++ b/tests/ui/fn/suggest-return-closure.stderr
@@ -34,11 +34,13 @@ LL | fn fun() -> _ {
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/suggest-return-closure.rs:23:9
    |
-LL |     let x = String::new();
-   |         - help: consider changing this to be mutable: `mut x`
-...
 LL |         x.push(c);
    |         ^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut x = String::new();
+   |         +++
 
 error[E0597]: `x` does not live long enough
   --> $DIR/suggest-return-closure.rs:23:9
diff --git a/tests/ui/issues/issue-11004.stderr b/tests/ui/issues/issue-11004.stderr
index ea141e61df8..6d157c91130 100644
--- a/tests/ui/issues/issue-11004.stderr
+++ b/tests/ui/issues/issue-11004.stderr
@@ -2,19 +2,23 @@ error[E0609]: no field `x` on type `*mut A`
   --> $DIR/issue-11004.rs:7:21
    |
 LL |     let x : i32 = n.x;
-   |                   --^
-   |                   | |
-   |                   | unknown field
-   |                   help: `n` is a raw pointer; try dereferencing it: `(*n).x`
+   |                     ^ unknown field
+   |
+help: `n` is a raw pointer; try dereferencing it
+   |
+LL |     let x : i32 = (*n).x;
+   |                   ++ +
 
 error[E0609]: no field `y` on type `*mut A`
   --> $DIR/issue-11004.rs:8:21
    |
 LL |     let y : f64 = n.y;
-   |                   --^
-   |                   | |
-   |                   | unknown field
-   |                   help: `n` is a raw pointer; try dereferencing it: `(*n).y`
+   |                     ^ unknown field
+   |
+help: `n` is a raw pointer; try dereferencing it
+   |
+LL |     let y : f64 = (*n).y;
+   |                   ++ +
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/issues/issue-21950.stderr b/tests/ui/issues/issue-21950.stderr
index e498565d4e6..584370c7178 100644
--- a/tests/ui/issues/issue-21950.stderr
+++ b/tests/ui/issues/issue-21950.stderr
@@ -14,9 +14,13 @@ LL | trait Add<Rhs=Self> {
    | ------------------- type parameter `Rhs` must be specified for this
 ...
 LL |     let x = &10 as &dyn Add;
-   |                         ^^^ help: set the type parameter to the desired type: `Add<Rhs>`
+   |                         ^^^
    |
    = note: because of the default `Self` reference, type parameters must be specified on object types
+help: set the type parameter to the desired type
+   |
+LL |     let x = &10 as &dyn Add<Rhs>;
+   |                            +++++
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/issues/issue-22370.stderr b/tests/ui/issues/issue-22370.stderr
index 977cfe06bb8..3dc060963f9 100644
--- a/tests/ui/issues/issue-22370.stderr
+++ b/tests/ui/issues/issue-22370.stderr
@@ -5,9 +5,13 @@ LL | trait A<T=Self> {}
    | --------------- type parameter `T` must be specified for this
 LL |
 LL | fn f(a: &dyn A) {}
-   |              ^ help: set the type parameter to the desired type: `A<T>`
+   |              ^
    |
    = note: because of the default `Self` reference, type parameters must be specified on object types
+help: set the type parameter to the desired type
+   |
+LL | fn f(a: &dyn A<T>) {}
+   |               +++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/let-else/let-else-slicing-error.stderr b/tests/ui/let-else/let-else-slicing-error.stderr
index 73c357dd5d4..4daae861965 100644
--- a/tests/ui/let-else/let-else-slicing-error.stderr
+++ b/tests/ui/let-else/let-else-slicing-error.stderr
@@ -2,9 +2,12 @@ error[E0529]: expected an array or slice, found `Vec<{integer}>`
   --> $DIR/let-else-slicing-error.rs:6:9
    |
 LL |     let [x, y] = nums else {
-   |         ^^^^^^   ---- help: consider slicing here: `nums[..]`
-   |         |
-   |         pattern cannot match with input type `Vec<{integer}>`
+   |         ^^^^^^ pattern cannot match with input type `Vec<{integer}>`
+   |
+help: consider slicing here
+   |
+LL |     let [x, y] = nums[..] else {
+   |                      ++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr
index 0980de92d35..29bf7e62985 100644
--- a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr
@@ -16,10 +16,13 @@ LL | fn foo<'a>(mut x: Ref<'a, 'a>, y: &'a u32) {
 error[E0384]: cannot assign to immutable argument `y`
   --> $DIR/ex3-both-anon-regions-one-is-struct-2.rs:4:5
    |
-LL | fn foo(mut x: Ref, y: &u32) {
-   |                    - help: consider making this binding mutable: `mut y`
 LL |     y = x.b;
    |     ^^^^^^^ cannot assign to immutable argument
+   |
+help: consider making this binding mutable
+   |
+LL | fn foo(mut x: Ref, mut y: &u32) {
+   |                    +++
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr b/tests/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr
index b47a47d631e..3fbd863467d 100644
--- a/tests/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr
+++ b/tests/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr
@@ -1,45 +1,53 @@
 error[E0384]: cannot assign twice to immutable variable `x`
   --> $DIR/liveness-assign-imm-local-notes.rs:10:9
    |
-LL |     let x;
-   |         - help: consider making this binding mutable: `mut x`
-...
 LL |         x = 2;
    |         ----- first assignment to `x`
 LL |         x = 3;
    |         ^^^^^ cannot assign twice to immutable variable
+   |
+help: consider making this binding mutable
+   |
+LL |     let mut x;
+   |         +++
 
 error[E0384]: cannot assign twice to immutable variable `x`
   --> $DIR/liveness-assign-imm-local-notes.rs:21:13
    |
-LL |         let x;
-   |             - help: consider making this binding mutable: `mut x`
-...
 LL |             x = 2;
    |             ----- first assignment to `x`
 LL |             x = 3;
    |             ^^^^^ cannot assign twice to immutable variable
+   |
+help: consider making this binding mutable
+   |
+LL |         let mut x;
+   |             +++
 
 error[E0384]: cannot assign twice to immutable variable `x`
   --> $DIR/liveness-assign-imm-local-notes.rs:30:13
    |
-LL |     let x;
-   |         - help: consider making this binding mutable: `mut x`
-...
 LL |             x = 1;
    |             ^^^^^ cannot assign twice to immutable variable
+   |
+help: consider making this binding mutable
+   |
+LL |     let mut x;
+   |         +++
 
 error[E0384]: cannot assign twice to immutable variable `x`
   --> $DIR/liveness-assign-imm-local-notes.rs:32:13
    |
-LL |     let x;
-   |         - help: consider making this binding mutable: `mut x`
-...
 LL |             x = 1;
    |             ----- first assignment to `x`
 LL |         } else {
 LL |             x = 2;
    |             ^^^^^ cannot assign twice to immutable variable
+   |
+help: consider making this binding mutable
+   |
+LL |     let mut x;
+   |         +++
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.rs b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.rs
index 08911c5bde7..d2f32a47122 100644
--- a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.rs
+++ b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.rs
@@ -1,7 +1,7 @@
 fn test() {
     let v: isize;
     //~^ HELP consider making this binding mutable
-    //~| SUGGESTION mut v
+    //~| SUGGESTION mut
     loop {
         v = 1; //~ ERROR cannot assign twice to immutable variable `v`
                //~| NOTE cannot assign twice to immutable variable
diff --git a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.stderr b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.stderr
index f0174560fd5..e8c0721b903 100644
--- a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.stderr
+++ b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.stderr
@@ -1,11 +1,13 @@
 error[E0384]: cannot assign twice to immutable variable `v`
   --> $DIR/liveness-assign-imm-local-in-loop.rs:6:9
    |
-LL |     let v: isize;
-   |         - help: consider making this binding mutable: `mut v`
-...
 LL |         v = 1;
    |         ^^^^^ cannot assign twice to immutable variable
+   |
+help: consider making this binding mutable
+   |
+LL |     let mut v: isize;
+   |         +++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.rs b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.rs
index 1752d969086..fd6b4bcdf84 100644
--- a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.rs
+++ b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.rs
@@ -1,7 +1,7 @@
 fn test() {
     let v: isize;
     //~^ HELP consider making this binding mutable
-    //~| SUGGESTION mut v
+    //~| SUGGESTION mut
     v = 2;  //~ NOTE first assignment
     v += 1; //~ ERROR cannot assign twice to immutable variable `v`
             //~| NOTE cannot assign twice to immutable
diff --git a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.stderr b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.stderr
index 578a40e4070..b7373d7cf1d 100644
--- a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.stderr
+++ b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.stderr
@@ -1,13 +1,15 @@
 error[E0384]: cannot assign twice to immutable variable `v`
   --> $DIR/liveness-assign-imm-local-in-op-eq.rs:6:5
    |
-LL |     let v: isize;
-   |         - help: consider making this binding mutable: `mut v`
-...
 LL |     v = 2;
    |     ----- first assignment to `v`
 LL |     v += 1;
    |     ^^^^^^ cannot assign twice to immutable variable
+   |
+help: consider making this binding mutable
+   |
+LL |     let mut v: isize;
+   |         +++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.rs b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.rs
index c9b16e43910..b7050d69306 100644
--- a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.rs
+++ b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.rs
@@ -1,7 +1,7 @@
 fn test() {
     let b = Box::new(1); //~ NOTE first assignment
                          //~| HELP consider making this binding mutable
-                         //~| SUGGESTION mut b
+                         //~| SUGGESTION mut
     drop(b);
     b = Box::new(2); //~ ERROR cannot assign twice to immutable variable `b`
                      //~| NOTE cannot assign twice to immutable
diff --git a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.stderr b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.stderr
index 2f55b50f0ba..35b47bd6d91 100644
--- a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.stderr
+++ b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.stderr
@@ -2,13 +2,15 @@ error[E0384]: cannot assign twice to immutable variable `b`
   --> $DIR/liveness-assign-imm-local-with-drop.rs:6:5
    |
 LL |     let b = Box::new(1);
-   |         -
-   |         |
-   |         first assignment to `b`
-   |         help: consider making this binding mutable: `mut b`
+   |         - first assignment to `b`
 ...
 LL |     b = Box::new(2);
    |     ^ cannot assign twice to immutable variable
+   |
+help: consider making this binding mutable
+   |
+LL |     let mut b = Box::new(1);
+   |         +++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.rs b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.rs
index 4bb2db27a16..67c97e38546 100644
--- a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.rs
+++ b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.rs
@@ -1,7 +1,7 @@
 fn test() {
     let v: isize = 1; //~ NOTE first assignment
                       //~| HELP consider making this binding mutable
-                      //~| SUGGESTION mut v
+                      //~| SUGGESTION mut
     v.clone();
     v = 2; //~ ERROR cannot assign twice to immutable variable `v`
            //~| NOTE cannot assign twice to immutable
diff --git a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.stderr b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.stderr
index 8eb71cd99bf..d1f9e1573e4 100644
--- a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.stderr
+++ b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.stderr
@@ -2,13 +2,15 @@ error[E0384]: cannot assign twice to immutable variable `v`
   --> $DIR/liveness-assign-imm-local-with-init.rs:6:5
    |
 LL |     let v: isize = 1;
-   |         -
-   |         |
-   |         first assignment to `v`
-   |         help: consider making this binding mutable: `mut v`
+   |         - first assignment to `v`
 ...
 LL |     v = 2;
    |     ^^^^^ cannot assign twice to immutable variable
+   |
+help: consider making this binding mutable
+   |
+LL |     let mut v: isize = 1;
+   |         +++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/mismatched_types/float-literal-inference-restrictions.stderr b/tests/ui/mismatched_types/float-literal-inference-restrictions.stderr
index 454373c322e..6b3e0cb505f 100644
--- a/tests/ui/mismatched_types/float-literal-inference-restrictions.stderr
+++ b/tests/ui/mismatched_types/float-literal-inference-restrictions.stderr
@@ -2,11 +2,14 @@ error[E0308]: mismatched types
   --> $DIR/float-literal-inference-restrictions.rs:2:18
    |
 LL |     let x: f32 = 1;
-   |            ---   ^
-   |            |     |
-   |            |     expected `f32`, found integer
-   |            |     help: use a float literal: `1.0`
+   |            ---   ^ expected `f32`, found integer
+   |            |
    |            expected due to this
+   |
+help: use a float literal
+   |
+LL |     let x: f32 = 1.0;
+   |                   ++
 
 error[E0308]: mismatched types
   --> $DIR/float-literal-inference-restrictions.rs:3:18
diff --git a/tests/ui/mut/mut-pattern-internal-mutability.stderr b/tests/ui/mut/mut-pattern-internal-mutability.stderr
index ab80af17a08..f3a8aa0126c 100644
--- a/tests/ui/mut/mut-pattern-internal-mutability.stderr
+++ b/tests/ui/mut/mut-pattern-internal-mutability.stderr
@@ -9,11 +9,11 @@ LL |     x += 1;
 help: consider making this binding mutable
    |
 LL |     let &mut mut x = foo;
-   |              ~~~~~
+   |              +++
 help: to modify the original value, take a borrow instead
    |
 LL |     let &mut ref mut x = foo;
-   |              ~~~~~~~~~
+   |              +++++++
 
 error[E0506]: cannot assign to `*foo` because it is borrowed
   --> $DIR/mut-pattern-internal-mutability.rs:13:5
diff --git a/tests/ui/nll/closure-captures.stderr b/tests/ui/nll/closure-captures.stderr
index 5233f0b2462..828974c517e 100644
--- a/tests/ui/nll/closure-captures.stderr
+++ b/tests/ui/nll/closure-captures.stderr
@@ -1,38 +1,46 @@
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
   --> $DIR/closure-captures.rs:7:5
    |
-LL | fn one_closure(x: i32) {
-   |                - help: consider changing this to be mutable: `mut x`
-LL |     ||
 LL |     x = 1;
    |     ^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL | fn one_closure(mut x: i32) {
+   |                +++
 
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
   --> $DIR/closure-captures.rs:9:5
    |
-LL | fn one_closure(x: i32) {
-   |                - help: consider changing this to be mutable: `mut x`
-...
 LL |     x = 1;
    |     ^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL | fn one_closure(mut x: i32) {
+   |                +++
 
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
   --> $DIR/closure-captures.rs:15:9
    |
-LL | fn two_closures(x: i32) {
-   |                 - help: consider changing this to be mutable: `mut x`
-...
 LL |         x = 1;
    |         ^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL | fn two_closures(mut x: i32) {
+   |                 +++
 
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
   --> $DIR/closure-captures.rs:19:9
    |
-LL | fn two_closures(x: i32) {
-   |                 - help: consider changing this to be mutable: `mut x`
-...
 LL |         x = 1;
    |         ^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL | fn two_closures(mut x: i32) {
+   |                 +++
 
 error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
   --> $DIR/closure-captures.rs:27:9
@@ -67,11 +75,13 @@ LL |     x = 1;});
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
   --> $DIR/closure-captures.rs:39:10
    |
-LL | fn two_closures_ref(x: i32) {
-   |                     - help: consider changing this to be mutable: `mut x`
-...
 LL |          x = 1;}
    |          ^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL | fn two_closures_ref(mut x: i32) {
+   |                     +++
 
 error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
   --> $DIR/closure-captures.rs:38:9
@@ -91,11 +101,13 @@ LL |          x = 1;}
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
   --> $DIR/closure-captures.rs:43:5
    |
-LL | fn two_closures_ref(x: i32) {
-   |                     - help: consider changing this to be mutable: `mut x`
-...
 LL |     x = 1;});
    |     ^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL | fn two_closures_ref(mut x: i32) {
+   |                     +++
 
 error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
   --> $DIR/closure-captures.rs:42:9
diff --git a/tests/ui/nll/coroutine-upvar-mutability.stderr b/tests/ui/nll/coroutine-upvar-mutability.stderr
index 8b9be877c8f..02c01130176 100644
--- a/tests/ui/nll/coroutine-upvar-mutability.stderr
+++ b/tests/ui/nll/coroutine-upvar-mutability.stderr
@@ -1,11 +1,13 @@
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
   --> $DIR/coroutine-upvar-mutability.rs:10:9
    |
-LL |     let x = 0;
-   |         - help: consider changing this to be mutable: `mut x`
-...
 LL |         x = 1;
    |         ^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut x = 0;
+   |         +++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/nll/issue-46023.stderr b/tests/ui/nll/issue-46023.stderr
index 062e07407ce..d071c29271c 100644
--- a/tests/ui/nll/issue-46023.stderr
+++ b/tests/ui/nll/issue-46023.stderr
@@ -1,11 +1,13 @@
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
   --> $DIR/issue-46023.rs:5:9
    |
-LL |     let x = 0;
-   |         - help: consider changing this to be mutable: `mut x`
-...
 LL |         x = 1;
    |         ^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut x = 0;
+   |         +++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr b/tests/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr
index 41d1b79d97d..ed71a39ff7e 100644
--- a/tests/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr
+++ b/tests/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr
@@ -78,11 +78,11 @@ LL |         | Err(a @ b @ a)
 help: consider making this binding mutable
    |
 LL |         Ok(a @ b @ mut a)
-   |                    ~~~~~
+   |                    +++
 help: to modify the original value, take a borrow instead
    |
 LL |         Ok(a @ b @ ref mut a)
-   |                    ~~~~~~~~~
+   |                    +++++++
 
 error: aborting due to 12 previous errors
 
diff --git a/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr b/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr
index 1e7b990b67c..a1049701dc3 100644
--- a/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr
+++ b/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr
@@ -22,11 +22,11 @@ LL |     _x1 = U;
 help: consider making this binding mutable
    |
 LL |     let [ref _x0_hold, mut _x1, ref xs_hold @ ..] = arr;
-   |                        ~~~~~~~
+   |                        +++
 help: to modify the original value, take a borrow instead
    |
 LL |     let [ref _x0_hold, ref mut _x1, ref xs_hold @ ..] = arr;
-   |                        ~~~~~~~~~~~
+   |                        +++++++
 
 error[E0505]: cannot move out of `arr[..]` because it is borrowed
   --> $DIR/borrowck-move-ref-pattern.rs:11:10
@@ -86,11 +86,11 @@ LL |     _x1 = U;
 help: consider making this binding mutable
    |
 LL |     let (ref _x0, mut _x1, ref _x2, ..) = tup;
-   |                   ~~~~~~~
+   |                   +++
 help: to modify the original value, take a borrow instead
    |
 LL |     let (ref _x0, ref mut _x1, ref _x2, ..) = tup;
-   |                   ~~~~~~~~~~~
+   |                   +++++++
 
 error[E0502]: cannot borrow `tup.0` as mutable because it is also borrowed as immutable
   --> $DIR/borrowck-move-ref-pattern.rs:24:20
diff --git a/tests/ui/pattern/mut-ref-mut-2021.stderr b/tests/ui/pattern/mut-ref-mut-2021.stderr
index ebf7979edb6..228afed2026 100644
--- a/tests/ui/pattern/mut-ref-mut-2021.stderr
+++ b/tests/ui/pattern/mut-ref-mut-2021.stderr
@@ -9,11 +9,11 @@ LL |     a = 42;
 help: consider making this binding mutable
    |
 LL |     let Foo(mut a) = Foo(0);
-   |             ~~~~~
+   |             +++
 help: to modify the original value, take a borrow instead
    |
 LL |     let Foo(ref mut a) = Foo(0);
-   |             ~~~~~~~~~
+   |             +++++++
 
 error[E0384]: cannot assign twice to immutable variable `a`
   --> $DIR/mut-ref-mut-2021.rs:15:5
diff --git a/tests/ui/pattern/patkind-ref-binding-issue-114896.stderr b/tests/ui/pattern/patkind-ref-binding-issue-114896.stderr
index 68538255edd..e9c2fccaba2 100644
--- a/tests/ui/pattern/patkind-ref-binding-issue-114896.stderr
+++ b/tests/ui/pattern/patkind-ref-binding-issue-114896.stderr
@@ -1,10 +1,13 @@
 error[E0596]: cannot borrow `b` as mutable, as it is not declared as mutable
   --> $DIR/patkind-ref-binding-issue-114896.rs:7:9
    |
-LL |         let &b = a;
-   |             -- help: consider changing this to be mutable: `&(mut b)`
 LL |         b.make_ascii_uppercase();
    |         ^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |         let &(mut b) = a;
+   |             ~~~~~  +
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/pattern/patkind-ref-binding-issue-122415.stderr b/tests/ui/pattern/patkind-ref-binding-issue-122415.stderr
index 39283133ac7..e93b8bbaccc 100644
--- a/tests/ui/pattern/patkind-ref-binding-issue-122415.stderr
+++ b/tests/ui/pattern/patkind-ref-binding-issue-122415.stderr
@@ -1,10 +1,13 @@
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/patkind-ref-binding-issue-122415.rs:7:12
    |
-LL | fn foo(&x: &i32) {
-   |        -- help: consider changing this to be mutable: `&(mut x)`
 LL |     mutate(&mut x);
    |            ^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL | fn foo(&(mut x): &i32) {
+   |        ~~~~~  +
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr
new file mode 100644
index 00000000000..e2e57fe0e73
--- /dev/null
+++ b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr
@@ -0,0 +1,288 @@
+error: layout_of(Univariant) = Layout {
+           size: Size(4 bytes),
+           align: AbiAndPrefAlign {
+               abi: Align(4 bytes),
+               pref: $SOME_ALIGN,
+           },
+           abi: Uninhabited,
+           fields: Arbitrary {
+               offsets: [
+                   Size(0 bytes),
+               ],
+               memory_index: [
+                   0,
+               ],
+           },
+           largest_niche: Some(
+               Niche {
+                   offset: Size(0 bytes),
+                   value: Int(
+                       I32,
+                       false,
+                   ),
+                   valid_range: 0..=0,
+               },
+           ),
+           variants: Multiple {
+               tag: Initialized {
+                   value: Int(
+                       I32,
+                       false,
+                   ),
+                   valid_range: 0..=0,
+               },
+               tag_encoding: Direct,
+               tag_field: 0,
+               variants: [
+                   Layout {
+                       size: Size(4 bytes),
+                       align: AbiAndPrefAlign {
+                           abi: Align(4 bytes),
+                           pref: $SOME_ALIGN,
+                       },
+                       abi: Uninhabited,
+                       fields: Arbitrary {
+                           offsets: [
+                               Size(4 bytes),
+                           ],
+                           memory_index: [
+                               0,
+                           ],
+                       },
+                       largest_niche: None,
+                       variants: Single {
+                           index: 0,
+                       },
+                       max_repr_align: None,
+                       unadjusted_abi_align: Align(4 bytes),
+                   },
+               ],
+           },
+           max_repr_align: None,
+           unadjusted_abi_align: Align(4 bytes),
+       }
+  --> $DIR/repr-c-dead-variants.rs:38:1
+   |
+LL | enum Univariant {
+   | ^^^^^^^^^^^^^^^
+
+error: layout_of(TwoVariants) = Layout {
+           size: Size(8 bytes),
+           align: AbiAndPrefAlign {
+               abi: Align(4 bytes),
+               pref: $SOME_ALIGN,
+           },
+           abi: ScalarPair(
+               Initialized {
+                   value: Int(
+                       I32,
+                       false,
+                   ),
+                   valid_range: 0..=1,
+               },
+               Union {
+                   value: Int(
+                       I8,
+                       false,
+                   ),
+               },
+           ),
+           fields: Arbitrary {
+               offsets: [
+                   Size(0 bytes),
+               ],
+               memory_index: [
+                   0,
+               ],
+           },
+           largest_niche: Some(
+               Niche {
+                   offset: Size(0 bytes),
+                   value: Int(
+                       I32,
+                       false,
+                   ),
+                   valid_range: 0..=1,
+               },
+           ),
+           variants: Multiple {
+               tag: Initialized {
+                   value: Int(
+                       I32,
+                       false,
+                   ),
+                   valid_range: 0..=1,
+               },
+               tag_encoding: Direct,
+               tag_field: 0,
+               variants: [
+                   Layout {
+                       size: Size(4 bytes),
+                       align: AbiAndPrefAlign {
+                           abi: Align(4 bytes),
+                           pref: $SOME_ALIGN,
+                       },
+                       abi: Uninhabited,
+                       fields: Arbitrary {
+                           offsets: [
+                               Size(4 bytes),
+                           ],
+                           memory_index: [
+                               0,
+                           ],
+                       },
+                       largest_niche: None,
+                       variants: Single {
+                           index: 0,
+                       },
+                       max_repr_align: None,
+                       unadjusted_abi_align: Align(4 bytes),
+                   },
+                   Layout {
+                       size: Size(8 bytes),
+                       align: AbiAndPrefAlign {
+                           abi: Align(4 bytes),
+                           pref: $SOME_ALIGN,
+                       },
+                       abi: ScalarPair(
+                           Initialized {
+                               value: Int(
+                                   I32,
+                                   false,
+                               ),
+                               valid_range: 0..=1,
+                           },
+                           Union {
+                               value: Int(
+                                   I8,
+                                   false,
+                               ),
+                           },
+                       ),
+                       fields: Arbitrary {
+                           offsets: [
+                               Size(4 bytes),
+                           ],
+                           memory_index: [
+                               0,
+                           ],
+                       },
+                       largest_niche: None,
+                       variants: Single {
+                           index: 1,
+                       },
+                       max_repr_align: None,
+                       unadjusted_abi_align: Align(4 bytes),
+                   },
+               ],
+           },
+           max_repr_align: None,
+           unadjusted_abi_align: Align(4 bytes),
+       }
+  --> $DIR/repr-c-dead-variants.rs:45:1
+   |
+LL | enum TwoVariants {
+   | ^^^^^^^^^^^^^^^^
+
+error: layout_of(DeadBranchHasOtherField) = Layout {
+           size: Size(16 bytes),
+           align: AbiAndPrefAlign {
+               abi: Align(8 bytes),
+               pref: $SOME_ALIGN,
+           },
+           abi: Aggregate {
+               sized: true,
+           },
+           fields: Arbitrary {
+               offsets: [
+                   Size(0 bytes),
+               ],
+               memory_index: [
+                   0,
+               ],
+           },
+           largest_niche: Some(
+               Niche {
+                   offset: Size(0 bytes),
+                   value: Int(
+                       I32,
+                       false,
+                   ),
+                   valid_range: 0..=1,
+               },
+           ),
+           variants: Multiple {
+               tag: Initialized {
+                   value: Int(
+                       I32,
+                       false,
+                   ),
+                   valid_range: 0..=1,
+               },
+               tag_encoding: Direct,
+               tag_field: 0,
+               variants: [
+                   Layout {
+                       size: Size(16 bytes),
+                       align: AbiAndPrefAlign {
+                           abi: Align(8 bytes),
+                           pref: $SOME_ALIGN,
+                       },
+                       abi: Uninhabited,
+                       fields: Arbitrary {
+                           offsets: [
+                               Size(8 bytes),
+                               Size(8 bytes),
+                           ],
+                           memory_index: [
+                               0,
+                               1,
+                           ],
+                       },
+                       largest_niche: None,
+                       variants: Single {
+                           index: 0,
+                       },
+                       max_repr_align: Some(
+                           Align(8 bytes),
+                       ),
+                       unadjusted_abi_align: Align(8 bytes),
+                   },
+                   Layout {
+                       size: Size(16 bytes),
+                       align: AbiAndPrefAlign {
+                           abi: Align(8 bytes),
+                           pref: $SOME_ALIGN,
+                       },
+                       abi: Aggregate {
+                           sized: true,
+                       },
+                       fields: Arbitrary {
+                           offsets: [
+                               Size(8 bytes),
+                           ],
+                           memory_index: [
+                               0,
+                           ],
+                       },
+                       largest_niche: None,
+                       variants: Single {
+                           index: 1,
+                       },
+                       max_repr_align: None,
+                       unadjusted_abi_align: Align(8 bytes),
+                   },
+               ],
+           },
+           max_repr_align: Some(
+               Align(8 bytes),
+           ),
+           unadjusted_abi_align: Align(8 bytes),
+       }
+  --> $DIR/repr-c-dead-variants.rs:57:1
+   |
+LL | enum DeadBranchHasOtherField {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr
new file mode 100644
index 00000000000..6ecdab1cc14
--- /dev/null
+++ b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr
@@ -0,0 +1,288 @@
+error: layout_of(Univariant) = Layout {
+           size: Size(1 bytes),
+           align: AbiAndPrefAlign {
+               abi: Align(1 bytes),
+               pref: $SOME_ALIGN,
+           },
+           abi: Uninhabited,
+           fields: Arbitrary {
+               offsets: [
+                   Size(0 bytes),
+               ],
+               memory_index: [
+                   0,
+               ],
+           },
+           largest_niche: Some(
+               Niche {
+                   offset: Size(0 bytes),
+                   value: Int(
+                       I8,
+                       false,
+                   ),
+                   valid_range: 0..=0,
+               },
+           ),
+           variants: Multiple {
+               tag: Initialized {
+                   value: Int(
+                       I8,
+                       false,
+                   ),
+                   valid_range: 0..=0,
+               },
+               tag_encoding: Direct,
+               tag_field: 0,
+               variants: [
+                   Layout {
+                       size: Size(1 bytes),
+                       align: AbiAndPrefAlign {
+                           abi: Align(1 bytes),
+                           pref: $SOME_ALIGN,
+                       },
+                       abi: Uninhabited,
+                       fields: Arbitrary {
+                           offsets: [
+                               Size(1 bytes),
+                           ],
+                           memory_index: [
+                               0,
+                           ],
+                       },
+                       largest_niche: None,
+                       variants: Single {
+                           index: 0,
+                       },
+                       max_repr_align: None,
+                       unadjusted_abi_align: Align(1 bytes),
+                   },
+               ],
+           },
+           max_repr_align: None,
+           unadjusted_abi_align: Align(1 bytes),
+       }
+  --> $DIR/repr-c-dead-variants.rs:38:1
+   |
+LL | enum Univariant {
+   | ^^^^^^^^^^^^^^^
+
+error: layout_of(TwoVariants) = Layout {
+           size: Size(2 bytes),
+           align: AbiAndPrefAlign {
+               abi: Align(1 bytes),
+               pref: $SOME_ALIGN,
+           },
+           abi: ScalarPair(
+               Initialized {
+                   value: Int(
+                       I8,
+                       false,
+                   ),
+                   valid_range: 0..=1,
+               },
+               Union {
+                   value: Int(
+                       I8,
+                       false,
+                   ),
+               },
+           ),
+           fields: Arbitrary {
+               offsets: [
+                   Size(0 bytes),
+               ],
+               memory_index: [
+                   0,
+               ],
+           },
+           largest_niche: Some(
+               Niche {
+                   offset: Size(0 bytes),
+                   value: Int(
+                       I8,
+                       false,
+                   ),
+                   valid_range: 0..=1,
+               },
+           ),
+           variants: Multiple {
+               tag: Initialized {
+                   value: Int(
+                       I8,
+                       false,
+                   ),
+                   valid_range: 0..=1,
+               },
+               tag_encoding: Direct,
+               tag_field: 0,
+               variants: [
+                   Layout {
+                       size: Size(1 bytes),
+                       align: AbiAndPrefAlign {
+                           abi: Align(1 bytes),
+                           pref: $SOME_ALIGN,
+                       },
+                       abi: Uninhabited,
+                       fields: Arbitrary {
+                           offsets: [
+                               Size(1 bytes),
+                           ],
+                           memory_index: [
+                               0,
+                           ],
+                       },
+                       largest_niche: None,
+                       variants: Single {
+                           index: 0,
+                       },
+                       max_repr_align: None,
+                       unadjusted_abi_align: Align(1 bytes),
+                   },
+                   Layout {
+                       size: Size(2 bytes),
+                       align: AbiAndPrefAlign {
+                           abi: Align(1 bytes),
+                           pref: $SOME_ALIGN,
+                       },
+                       abi: ScalarPair(
+                           Initialized {
+                               value: Int(
+                                   I8,
+                                   false,
+                               ),
+                               valid_range: 0..=1,
+                           },
+                           Union {
+                               value: Int(
+                                   I8,
+                                   false,
+                               ),
+                           },
+                       ),
+                       fields: Arbitrary {
+                           offsets: [
+                               Size(1 bytes),
+                           ],
+                           memory_index: [
+                               0,
+                           ],
+                       },
+                       largest_niche: None,
+                       variants: Single {
+                           index: 1,
+                       },
+                       max_repr_align: None,
+                       unadjusted_abi_align: Align(1 bytes),
+                   },
+               ],
+           },
+           max_repr_align: None,
+           unadjusted_abi_align: Align(1 bytes),
+       }
+  --> $DIR/repr-c-dead-variants.rs:45:1
+   |
+LL | enum TwoVariants {
+   | ^^^^^^^^^^^^^^^^
+
+error: layout_of(DeadBranchHasOtherField) = Layout {
+           size: Size(16 bytes),
+           align: AbiAndPrefAlign {
+               abi: Align(8 bytes),
+               pref: $SOME_ALIGN,
+           },
+           abi: Aggregate {
+               sized: true,
+           },
+           fields: Arbitrary {
+               offsets: [
+                   Size(0 bytes),
+               ],
+               memory_index: [
+                   0,
+               ],
+           },
+           largest_niche: Some(
+               Niche {
+                   offset: Size(0 bytes),
+                   value: Int(
+                       I8,
+                       false,
+                   ),
+                   valid_range: 0..=1,
+               },
+           ),
+           variants: Multiple {
+               tag: Initialized {
+                   value: Int(
+                       I8,
+                       false,
+                   ),
+                   valid_range: 0..=1,
+               },
+               tag_encoding: Direct,
+               tag_field: 0,
+               variants: [
+                   Layout {
+                       size: Size(16 bytes),
+                       align: AbiAndPrefAlign {
+                           abi: Align(8 bytes),
+                           pref: $SOME_ALIGN,
+                       },
+                       abi: Uninhabited,
+                       fields: Arbitrary {
+                           offsets: [
+                               Size(8 bytes),
+                               Size(8 bytes),
+                           ],
+                           memory_index: [
+                               0,
+                               1,
+                           ],
+                       },
+                       largest_niche: None,
+                       variants: Single {
+                           index: 0,
+                       },
+                       max_repr_align: Some(
+                           Align(8 bytes),
+                       ),
+                       unadjusted_abi_align: Align(8 bytes),
+                   },
+                   Layout {
+                       size: Size(16 bytes),
+                       align: AbiAndPrefAlign {
+                           abi: Align(8 bytes),
+                           pref: $SOME_ALIGN,
+                       },
+                       abi: Aggregate {
+                           sized: true,
+                       },
+                       fields: Arbitrary {
+                           offsets: [
+                               Size(8 bytes),
+                           ],
+                           memory_index: [
+                               0,
+                           ],
+                       },
+                       largest_niche: None,
+                       variants: Single {
+                           index: 1,
+                       },
+                       max_repr_align: None,
+                       unadjusted_abi_align: Align(8 bytes),
+                   },
+               ],
+           },
+           max_repr_align: Some(
+               Align(8 bytes),
+           ),
+           unadjusted_abi_align: Align(8 bytes),
+       }
+  --> $DIR/repr-c-dead-variants.rs:57:1
+   |
+LL | enum DeadBranchHasOtherField {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr
new file mode 100644
index 00000000000..e2e57fe0e73
--- /dev/null
+++ b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr
@@ -0,0 +1,288 @@
+error: layout_of(Univariant) = Layout {
+           size: Size(4 bytes),
+           align: AbiAndPrefAlign {
+               abi: Align(4 bytes),
+               pref: $SOME_ALIGN,
+           },
+           abi: Uninhabited,
+           fields: Arbitrary {
+               offsets: [
+                   Size(0 bytes),
+               ],
+               memory_index: [
+                   0,
+               ],
+           },
+           largest_niche: Some(
+               Niche {
+                   offset: Size(0 bytes),
+                   value: Int(
+                       I32,
+                       false,
+                   ),
+                   valid_range: 0..=0,
+               },
+           ),
+           variants: Multiple {
+               tag: Initialized {
+                   value: Int(
+                       I32,
+                       false,
+                   ),
+                   valid_range: 0..=0,
+               },
+               tag_encoding: Direct,
+               tag_field: 0,
+               variants: [
+                   Layout {
+                       size: Size(4 bytes),
+                       align: AbiAndPrefAlign {
+                           abi: Align(4 bytes),
+                           pref: $SOME_ALIGN,
+                       },
+                       abi: Uninhabited,
+                       fields: Arbitrary {
+                           offsets: [
+                               Size(4 bytes),
+                           ],
+                           memory_index: [
+                               0,
+                           ],
+                       },
+                       largest_niche: None,
+                       variants: Single {
+                           index: 0,
+                       },
+                       max_repr_align: None,
+                       unadjusted_abi_align: Align(4 bytes),
+                   },
+               ],
+           },
+           max_repr_align: None,
+           unadjusted_abi_align: Align(4 bytes),
+       }
+  --> $DIR/repr-c-dead-variants.rs:38:1
+   |
+LL | enum Univariant {
+   | ^^^^^^^^^^^^^^^
+
+error: layout_of(TwoVariants) = Layout {
+           size: Size(8 bytes),
+           align: AbiAndPrefAlign {
+               abi: Align(4 bytes),
+               pref: $SOME_ALIGN,
+           },
+           abi: ScalarPair(
+               Initialized {
+                   value: Int(
+                       I32,
+                       false,
+                   ),
+                   valid_range: 0..=1,
+               },
+               Union {
+                   value: Int(
+                       I8,
+                       false,
+                   ),
+               },
+           ),
+           fields: Arbitrary {
+               offsets: [
+                   Size(0 bytes),
+               ],
+               memory_index: [
+                   0,
+               ],
+           },
+           largest_niche: Some(
+               Niche {
+                   offset: Size(0 bytes),
+                   value: Int(
+                       I32,
+                       false,
+                   ),
+                   valid_range: 0..=1,
+               },
+           ),
+           variants: Multiple {
+               tag: Initialized {
+                   value: Int(
+                       I32,
+                       false,
+                   ),
+                   valid_range: 0..=1,
+               },
+               tag_encoding: Direct,
+               tag_field: 0,
+               variants: [
+                   Layout {
+                       size: Size(4 bytes),
+                       align: AbiAndPrefAlign {
+                           abi: Align(4 bytes),
+                           pref: $SOME_ALIGN,
+                       },
+                       abi: Uninhabited,
+                       fields: Arbitrary {
+                           offsets: [
+                               Size(4 bytes),
+                           ],
+                           memory_index: [
+                               0,
+                           ],
+                       },
+                       largest_niche: None,
+                       variants: Single {
+                           index: 0,
+                       },
+                       max_repr_align: None,
+                       unadjusted_abi_align: Align(4 bytes),
+                   },
+                   Layout {
+                       size: Size(8 bytes),
+                       align: AbiAndPrefAlign {
+                           abi: Align(4 bytes),
+                           pref: $SOME_ALIGN,
+                       },
+                       abi: ScalarPair(
+                           Initialized {
+                               value: Int(
+                                   I32,
+                                   false,
+                               ),
+                               valid_range: 0..=1,
+                           },
+                           Union {
+                               value: Int(
+                                   I8,
+                                   false,
+                               ),
+                           },
+                       ),
+                       fields: Arbitrary {
+                           offsets: [
+                               Size(4 bytes),
+                           ],
+                           memory_index: [
+                               0,
+                           ],
+                       },
+                       largest_niche: None,
+                       variants: Single {
+                           index: 1,
+                       },
+                       max_repr_align: None,
+                       unadjusted_abi_align: Align(4 bytes),
+                   },
+               ],
+           },
+           max_repr_align: None,
+           unadjusted_abi_align: Align(4 bytes),
+       }
+  --> $DIR/repr-c-dead-variants.rs:45:1
+   |
+LL | enum TwoVariants {
+   | ^^^^^^^^^^^^^^^^
+
+error: layout_of(DeadBranchHasOtherField) = Layout {
+           size: Size(16 bytes),
+           align: AbiAndPrefAlign {
+               abi: Align(8 bytes),
+               pref: $SOME_ALIGN,
+           },
+           abi: Aggregate {
+               sized: true,
+           },
+           fields: Arbitrary {
+               offsets: [
+                   Size(0 bytes),
+               ],
+               memory_index: [
+                   0,
+               ],
+           },
+           largest_niche: Some(
+               Niche {
+                   offset: Size(0 bytes),
+                   value: Int(
+                       I32,
+                       false,
+                   ),
+                   valid_range: 0..=1,
+               },
+           ),
+           variants: Multiple {
+               tag: Initialized {
+                   value: Int(
+                       I32,
+                       false,
+                   ),
+                   valid_range: 0..=1,
+               },
+               tag_encoding: Direct,
+               tag_field: 0,
+               variants: [
+                   Layout {
+                       size: Size(16 bytes),
+                       align: AbiAndPrefAlign {
+                           abi: Align(8 bytes),
+                           pref: $SOME_ALIGN,
+                       },
+                       abi: Uninhabited,
+                       fields: Arbitrary {
+                           offsets: [
+                               Size(8 bytes),
+                               Size(8 bytes),
+                           ],
+                           memory_index: [
+                               0,
+                               1,
+                           ],
+                       },
+                       largest_niche: None,
+                       variants: Single {
+                           index: 0,
+                       },
+                       max_repr_align: Some(
+                           Align(8 bytes),
+                       ),
+                       unadjusted_abi_align: Align(8 bytes),
+                   },
+                   Layout {
+                       size: Size(16 bytes),
+                       align: AbiAndPrefAlign {
+                           abi: Align(8 bytes),
+                           pref: $SOME_ALIGN,
+                       },
+                       abi: Aggregate {
+                           sized: true,
+                       },
+                       fields: Arbitrary {
+                           offsets: [
+                               Size(8 bytes),
+                           ],
+                           memory_index: [
+                               0,
+                           ],
+                       },
+                       largest_niche: None,
+                       variants: Single {
+                           index: 1,
+                       },
+                       max_repr_align: None,
+                       unadjusted_abi_align: Align(8 bytes),
+                   },
+               ],
+           },
+           max_repr_align: Some(
+               Align(8 bytes),
+           ),
+           unadjusted_abi_align: Align(8 bytes),
+       }
+  --> $DIR/repr-c-dead-variants.rs:57:1
+   |
+LL | enum DeadBranchHasOtherField {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/repr/repr-c-dead-variants.rs b/tests/ui/repr/repr-c-dead-variants.rs
new file mode 100644
index 00000000000..f113588e83f
--- /dev/null
+++ b/tests/ui/repr/repr-c-dead-variants.rs
@@ -0,0 +1,63 @@
+#![feature(no_core, rustc_attrs, lang_items)]
+#![allow(dead_code)]
+#![crate_type = "lib"]
+#![no_std]
+#![no_core]
+
+// See also: repr-c-int-dead-variants.rs
+
+//@ normalize-stderr-test "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN"
+
+// This test depends on the value of the `c_enum_min_bits` target option.
+// As there's no way to actually check it from UI test, we only run this test on a subset of archs.
+// Four archs specifically are chosen: one for major architectures (x86_64, i686, aarch64)
+// and `armebv7r-none-eabi` that has `c_enum_min_bits` set to 8.
+
+//@ revisions: aarch64-unknown-linux-gnu
+//@[aarch64-unknown-linux-gnu] compile-flags: --target aarch64-unknown-linux-gnu
+//@[aarch64-unknown-linux-gnu] needs-llvm-components: aarch64
+
+//@ revisions: i686-pc-windows-msvc
+//@[i686-pc-windows-msvc] compile-flags: --target i686-pc-windows-gnu
+//@[i686-pc-windows-msvc] needs-llvm-components: x86
+
+//@ revisions: x86_64-unknown-linux-gnu
+//@[x86_64-unknown-linux-gnu] compile-flags: --target x86_64-unknown-linux-gnu
+//@[x86_64-unknown-linux-gnu] needs-llvm-components: x86
+//
+//@ revisions: armebv7r-none-eabi
+//@[armebv7r-none-eabi] compile-flags: --target armebv7r-none-eabi
+//@[armebv7r-none-eabi] needs-llvm-components: arm
+
+// A simple uninhabited type.
+enum Void {}
+
+// Compiler must not remove dead variants of `#[repr(C, int)]` ADTs.
+#[repr(C)]
+#[rustc_layout(debug)]
+enum Univariant { //~ ERROR layout_of
+    Variant(Void),
+}
+
+// ADTs with variants that have fields must have space allocated for those fields.
+#[repr(C)]
+#[rustc_layout(debug)]
+enum TwoVariants { //~ ERROR layout_of
+    Variant1(Void),
+    Variant2(u8),
+}
+
+// Some targets have 4-byte-aligned u64, make it always 8-byte-aligned.
+#[repr(C, align(8))]
+struct Align8U64(u64);
+
+// This one is 2 x u64: we reserve space for fields in a dead branch.
+#[repr(C)]
+#[rustc_layout(debug)]
+enum DeadBranchHasOtherField { //~ ERROR layout_of
+    Variant1(Void, Align8U64),
+    Variant2(u8),
+}
+
+#[lang = "sized"]
+trait Sized {}
diff --git a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr
new file mode 100644
index 00000000000..e2e57fe0e73
--- /dev/null
+++ b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr
@@ -0,0 +1,288 @@
+error: layout_of(Univariant) = Layout {
+           size: Size(4 bytes),
+           align: AbiAndPrefAlign {
+               abi: Align(4 bytes),
+               pref: $SOME_ALIGN,
+           },
+           abi: Uninhabited,
+           fields: Arbitrary {
+               offsets: [
+                   Size(0 bytes),
+               ],
+               memory_index: [
+                   0,
+               ],
+           },
+           largest_niche: Some(
+               Niche {
+                   offset: Size(0 bytes),
+                   value: Int(
+                       I32,
+                       false,
+                   ),
+                   valid_range: 0..=0,
+               },
+           ),
+           variants: Multiple {
+               tag: Initialized {
+                   value: Int(
+                       I32,
+                       false,
+                   ),
+                   valid_range: 0..=0,
+               },
+               tag_encoding: Direct,
+               tag_field: 0,
+               variants: [
+                   Layout {
+                       size: Size(4 bytes),
+                       align: AbiAndPrefAlign {
+                           abi: Align(4 bytes),
+                           pref: $SOME_ALIGN,
+                       },
+                       abi: Uninhabited,
+                       fields: Arbitrary {
+                           offsets: [
+                               Size(4 bytes),
+                           ],
+                           memory_index: [
+                               0,
+                           ],
+                       },
+                       largest_niche: None,
+                       variants: Single {
+                           index: 0,
+                       },
+                       max_repr_align: None,
+                       unadjusted_abi_align: Align(4 bytes),
+                   },
+               ],
+           },
+           max_repr_align: None,
+           unadjusted_abi_align: Align(4 bytes),
+       }
+  --> $DIR/repr-c-dead-variants.rs:38:1
+   |
+LL | enum Univariant {
+   | ^^^^^^^^^^^^^^^
+
+error: layout_of(TwoVariants) = Layout {
+           size: Size(8 bytes),
+           align: AbiAndPrefAlign {
+               abi: Align(4 bytes),
+               pref: $SOME_ALIGN,
+           },
+           abi: ScalarPair(
+               Initialized {
+                   value: Int(
+                       I32,
+                       false,
+                   ),
+                   valid_range: 0..=1,
+               },
+               Union {
+                   value: Int(
+                       I8,
+                       false,
+                   ),
+               },
+           ),
+           fields: Arbitrary {
+               offsets: [
+                   Size(0 bytes),
+               ],
+               memory_index: [
+                   0,
+               ],
+           },
+           largest_niche: Some(
+               Niche {
+                   offset: Size(0 bytes),
+                   value: Int(
+                       I32,
+                       false,
+                   ),
+                   valid_range: 0..=1,
+               },
+           ),
+           variants: Multiple {
+               tag: Initialized {
+                   value: Int(
+                       I32,
+                       false,
+                   ),
+                   valid_range: 0..=1,
+               },
+               tag_encoding: Direct,
+               tag_field: 0,
+               variants: [
+                   Layout {
+                       size: Size(4 bytes),
+                       align: AbiAndPrefAlign {
+                           abi: Align(4 bytes),
+                           pref: $SOME_ALIGN,
+                       },
+                       abi: Uninhabited,
+                       fields: Arbitrary {
+                           offsets: [
+                               Size(4 bytes),
+                           ],
+                           memory_index: [
+                               0,
+                           ],
+                       },
+                       largest_niche: None,
+                       variants: Single {
+                           index: 0,
+                       },
+                       max_repr_align: None,
+                       unadjusted_abi_align: Align(4 bytes),
+                   },
+                   Layout {
+                       size: Size(8 bytes),
+                       align: AbiAndPrefAlign {
+                           abi: Align(4 bytes),
+                           pref: $SOME_ALIGN,
+                       },
+                       abi: ScalarPair(
+                           Initialized {
+                               value: Int(
+                                   I32,
+                                   false,
+                               ),
+                               valid_range: 0..=1,
+                           },
+                           Union {
+                               value: Int(
+                                   I8,
+                                   false,
+                               ),
+                           },
+                       ),
+                       fields: Arbitrary {
+                           offsets: [
+                               Size(4 bytes),
+                           ],
+                           memory_index: [
+                               0,
+                           ],
+                       },
+                       largest_niche: None,
+                       variants: Single {
+                           index: 1,
+                       },
+                       max_repr_align: None,
+                       unadjusted_abi_align: Align(4 bytes),
+                   },
+               ],
+           },
+           max_repr_align: None,
+           unadjusted_abi_align: Align(4 bytes),
+       }
+  --> $DIR/repr-c-dead-variants.rs:45:1
+   |
+LL | enum TwoVariants {
+   | ^^^^^^^^^^^^^^^^
+
+error: layout_of(DeadBranchHasOtherField) = Layout {
+           size: Size(16 bytes),
+           align: AbiAndPrefAlign {
+               abi: Align(8 bytes),
+               pref: $SOME_ALIGN,
+           },
+           abi: Aggregate {
+               sized: true,
+           },
+           fields: Arbitrary {
+               offsets: [
+                   Size(0 bytes),
+               ],
+               memory_index: [
+                   0,
+               ],
+           },
+           largest_niche: Some(
+               Niche {
+                   offset: Size(0 bytes),
+                   value: Int(
+                       I32,
+                       false,
+                   ),
+                   valid_range: 0..=1,
+               },
+           ),
+           variants: Multiple {
+               tag: Initialized {
+                   value: Int(
+                       I32,
+                       false,
+                   ),
+                   valid_range: 0..=1,
+               },
+               tag_encoding: Direct,
+               tag_field: 0,
+               variants: [
+                   Layout {
+                       size: Size(16 bytes),
+                       align: AbiAndPrefAlign {
+                           abi: Align(8 bytes),
+                           pref: $SOME_ALIGN,
+                       },
+                       abi: Uninhabited,
+                       fields: Arbitrary {
+                           offsets: [
+                               Size(8 bytes),
+                               Size(8 bytes),
+                           ],
+                           memory_index: [
+                               0,
+                               1,
+                           ],
+                       },
+                       largest_niche: None,
+                       variants: Single {
+                           index: 0,
+                       },
+                       max_repr_align: Some(
+                           Align(8 bytes),
+                       ),
+                       unadjusted_abi_align: Align(8 bytes),
+                   },
+                   Layout {
+                       size: Size(16 bytes),
+                       align: AbiAndPrefAlign {
+                           abi: Align(8 bytes),
+                           pref: $SOME_ALIGN,
+                       },
+                       abi: Aggregate {
+                           sized: true,
+                       },
+                       fields: Arbitrary {
+                           offsets: [
+                               Size(8 bytes),
+                           ],
+                           memory_index: [
+                               0,
+                           ],
+                       },
+                       largest_niche: None,
+                       variants: Single {
+                           index: 1,
+                       },
+                       max_repr_align: None,
+                       unadjusted_abi_align: Align(8 bytes),
+                   },
+               ],
+           },
+           max_repr_align: Some(
+               Align(8 bytes),
+           ),
+           unadjusted_abi_align: Align(8 bytes),
+       }
+  --> $DIR/repr-c-dead-variants.rs:57:1
+   |
+LL | enum DeadBranchHasOtherField {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/repr/repr-c-int-dead-variants.rs b/tests/ui/repr/repr-c-int-dead-variants.rs
new file mode 100644
index 00000000000..8d2b39bd648
--- /dev/null
+++ b/tests/ui/repr/repr-c-int-dead-variants.rs
@@ -0,0 +1,38 @@
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+
+// See also: repr-c-dead-variants.rs
+
+//@ normalize-stderr-test "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN"
+
+// A simple uninhabited type.
+enum Void {}
+
+// Compiler must not remove dead variants of `#[repr(C, int)]` ADTs.
+#[repr(C, u8)]
+#[rustc_layout(debug)]
+enum UnivariantU8 { //~ ERROR layout_of
+    Variant(Void),
+}
+
+// ADTs with variants that have fields must have space allocated for those fields.
+#[repr(C, u8)]
+#[rustc_layout(debug)]
+enum TwoVariantsU8 { //~ ERROR layout_of
+    Variant1(Void),
+    Variant2(u8),
+}
+
+// Some targets have 4-byte-aligned u64, make it always 8-byte-aligned.
+#[repr(C, align(8))]
+struct Align8U64(u64);
+
+// This one is 2 x u64: we reserve space for fields in a dead branch.
+#[repr(C, u8)]
+#[rustc_layout(debug)]
+enum DeadBranchHasOtherFieldU8 { //~ ERROR layout_of
+    Variant1(Void, Align8U64),
+    Variant2(u8),
+}
+
+fn main() {}
diff --git a/tests/ui/repr/repr-c-int-dead-variants.stderr b/tests/ui/repr/repr-c-int-dead-variants.stderr
new file mode 100644
index 00000000000..f7df576df24
--- /dev/null
+++ b/tests/ui/repr/repr-c-int-dead-variants.stderr
@@ -0,0 +1,288 @@
+error: layout_of(UnivariantU8) = Layout {
+           size: Size(1 bytes),
+           align: AbiAndPrefAlign {
+               abi: Align(1 bytes),
+               pref: $SOME_ALIGN,
+           },
+           abi: Uninhabited,
+           fields: Arbitrary {
+               offsets: [
+                   Size(0 bytes),
+               ],
+               memory_index: [
+                   0,
+               ],
+           },
+           largest_niche: Some(
+               Niche {
+                   offset: Size(0 bytes),
+                   value: Int(
+                       I8,
+                       false,
+                   ),
+                   valid_range: 0..=0,
+               },
+           ),
+           variants: Multiple {
+               tag: Initialized {
+                   value: Int(
+                       I8,
+                       false,
+                   ),
+                   valid_range: 0..=0,
+               },
+               tag_encoding: Direct,
+               tag_field: 0,
+               variants: [
+                   Layout {
+                       size: Size(1 bytes),
+                       align: AbiAndPrefAlign {
+                           abi: Align(1 bytes),
+                           pref: $SOME_ALIGN,
+                       },
+                       abi: Uninhabited,
+                       fields: Arbitrary {
+                           offsets: [
+                               Size(1 bytes),
+                           ],
+                           memory_index: [
+                               0,
+                           ],
+                       },
+                       largest_niche: None,
+                       variants: Single {
+                           index: 0,
+                       },
+                       max_repr_align: None,
+                       unadjusted_abi_align: Align(1 bytes),
+                   },
+               ],
+           },
+           max_repr_align: None,
+           unadjusted_abi_align: Align(1 bytes),
+       }
+  --> $DIR/repr-c-int-dead-variants.rs:14:1
+   |
+LL | enum UnivariantU8 {
+   | ^^^^^^^^^^^^^^^^^
+
+error: layout_of(TwoVariantsU8) = Layout {
+           size: Size(2 bytes),
+           align: AbiAndPrefAlign {
+               abi: Align(1 bytes),
+               pref: $SOME_ALIGN,
+           },
+           abi: ScalarPair(
+               Initialized {
+                   value: Int(
+                       I8,
+                       false,
+                   ),
+                   valid_range: 0..=1,
+               },
+               Union {
+                   value: Int(
+                       I8,
+                       false,
+                   ),
+               },
+           ),
+           fields: Arbitrary {
+               offsets: [
+                   Size(0 bytes),
+               ],
+               memory_index: [
+                   0,
+               ],
+           },
+           largest_niche: Some(
+               Niche {
+                   offset: Size(0 bytes),
+                   value: Int(
+                       I8,
+                       false,
+                   ),
+                   valid_range: 0..=1,
+               },
+           ),
+           variants: Multiple {
+               tag: Initialized {
+                   value: Int(
+                       I8,
+                       false,
+                   ),
+                   valid_range: 0..=1,
+               },
+               tag_encoding: Direct,
+               tag_field: 0,
+               variants: [
+                   Layout {
+                       size: Size(1 bytes),
+                       align: AbiAndPrefAlign {
+                           abi: Align(1 bytes),
+                           pref: $SOME_ALIGN,
+                       },
+                       abi: Uninhabited,
+                       fields: Arbitrary {
+                           offsets: [
+                               Size(1 bytes),
+                           ],
+                           memory_index: [
+                               0,
+                           ],
+                       },
+                       largest_niche: None,
+                       variants: Single {
+                           index: 0,
+                       },
+                       max_repr_align: None,
+                       unadjusted_abi_align: Align(1 bytes),
+                   },
+                   Layout {
+                       size: Size(2 bytes),
+                       align: AbiAndPrefAlign {
+                           abi: Align(1 bytes),
+                           pref: $SOME_ALIGN,
+                       },
+                       abi: ScalarPair(
+                           Initialized {
+                               value: Int(
+                                   I8,
+                                   false,
+                               ),
+                               valid_range: 0..=1,
+                           },
+                           Union {
+                               value: Int(
+                                   I8,
+                                   false,
+                               ),
+                           },
+                       ),
+                       fields: Arbitrary {
+                           offsets: [
+                               Size(1 bytes),
+                           ],
+                           memory_index: [
+                               0,
+                           ],
+                       },
+                       largest_niche: None,
+                       variants: Single {
+                           index: 1,
+                       },
+                       max_repr_align: None,
+                       unadjusted_abi_align: Align(1 bytes),
+                   },
+               ],
+           },
+           max_repr_align: None,
+           unadjusted_abi_align: Align(1 bytes),
+       }
+  --> $DIR/repr-c-int-dead-variants.rs:21:1
+   |
+LL | enum TwoVariantsU8 {
+   | ^^^^^^^^^^^^^^^^^^
+
+error: layout_of(DeadBranchHasOtherFieldU8) = Layout {
+           size: Size(16 bytes),
+           align: AbiAndPrefAlign {
+               abi: Align(8 bytes),
+               pref: $SOME_ALIGN,
+           },
+           abi: Aggregate {
+               sized: true,
+           },
+           fields: Arbitrary {
+               offsets: [
+                   Size(0 bytes),
+               ],
+               memory_index: [
+                   0,
+               ],
+           },
+           largest_niche: Some(
+               Niche {
+                   offset: Size(0 bytes),
+                   value: Int(
+                       I8,
+                       false,
+                   ),
+                   valid_range: 0..=1,
+               },
+           ),
+           variants: Multiple {
+               tag: Initialized {
+                   value: Int(
+                       I8,
+                       false,
+                   ),
+                   valid_range: 0..=1,
+               },
+               tag_encoding: Direct,
+               tag_field: 0,
+               variants: [
+                   Layout {
+                       size: Size(16 bytes),
+                       align: AbiAndPrefAlign {
+                           abi: Align(8 bytes),
+                           pref: $SOME_ALIGN,
+                       },
+                       abi: Uninhabited,
+                       fields: Arbitrary {
+                           offsets: [
+                               Size(8 bytes),
+                               Size(8 bytes),
+                           ],
+                           memory_index: [
+                               0,
+                               1,
+                           ],
+                       },
+                       largest_niche: None,
+                       variants: Single {
+                           index: 0,
+                       },
+                       max_repr_align: Some(
+                           Align(8 bytes),
+                       ),
+                       unadjusted_abi_align: Align(8 bytes),
+                   },
+                   Layout {
+                       size: Size(16 bytes),
+                       align: AbiAndPrefAlign {
+                           abi: Align(8 bytes),
+                           pref: $SOME_ALIGN,
+                       },
+                       abi: Aggregate {
+                           sized: true,
+                       },
+                       fields: Arbitrary {
+                           offsets: [
+                               Size(8 bytes),
+                           ],
+                           memory_index: [
+                               0,
+                           ],
+                       },
+                       largest_niche: None,
+                       variants: Single {
+                           index: 1,
+                       },
+                       max_repr_align: None,
+                       unadjusted_abi_align: Align(8 bytes),
+                   },
+               ],
+           },
+           max_repr_align: Some(
+               Align(8 bytes),
+           ),
+           unadjusted_abi_align: Align(8 bytes),
+       }
+  --> $DIR/repr-c-int-dead-variants.rs:33:1
+   |
+LL | enum DeadBranchHasOtherFieldU8 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/structs/structure-constructor-type-mismatch.stderr b/tests/ui/structs/structure-constructor-type-mismatch.stderr
index 63dda459396..cb957487347 100644
--- a/tests/ui/structs/structure-constructor-type-mismatch.stderr
+++ b/tests/ui/structs/structure-constructor-type-mismatch.stderr
@@ -2,55 +2,67 @@ error[E0308]: mismatched types
   --> $DIR/structure-constructor-type-mismatch.rs:17:12
    |
 LL |         x: 1,
-   |            ^
-   |            |
-   |            expected `f32`, found integer
-   |            help: use a float literal: `1.0`
+   |            ^ expected `f32`, found integer
+   |
+help: use a float literal
+   |
+LL |         x: 1.0,
+   |             ++
 
 error[E0308]: mismatched types
   --> $DIR/structure-constructor-type-mismatch.rs:20:12
    |
 LL |         y: 2,
-   |            ^
-   |            |
-   |            expected `f32`, found integer
-   |            help: use a float literal: `2.0`
+   |            ^ expected `f32`, found integer
+   |
+help: use a float literal
+   |
+LL |         y: 2.0,
+   |             ++
 
 error[E0308]: mismatched types
   --> $DIR/structure-constructor-type-mismatch.rs:26:12
    |
 LL |         x: 3,
-   |            ^
-   |            |
-   |            expected `f32`, found integer
-   |            help: use a float literal: `3.0`
+   |            ^ expected `f32`, found integer
+   |
+help: use a float literal
+   |
+LL |         x: 3.0,
+   |             ++
 
 error[E0308]: mismatched types
   --> $DIR/structure-constructor-type-mismatch.rs:29:12
    |
 LL |         y: 4,
-   |            ^
-   |            |
-   |            expected `f32`, found integer
-   |            help: use a float literal: `4.0`
+   |            ^ expected `f32`, found integer
+   |
+help: use a float literal
+   |
+LL |         y: 4.0,
+   |             ++
 
 error[E0308]: mismatched types
   --> $DIR/structure-constructor-type-mismatch.rs:35:12
    |
 LL |         x: 5,
-   |            ^
-   |            |
-   |            expected `f32`, found integer
-   |            help: use a float literal: `5.0`
+   |            ^ expected `f32`, found integer
+   |
+help: use a float literal
+   |
+LL |         x: 5.0,
+   |             ++
 
 error[E0308]: mismatched types
   --> $DIR/structure-constructor-type-mismatch.rs:42:12
    |
 LL |         x: 7,
-   |            ^
-   |            |
-   |            expected `f32`, found integer
-   |            help: use a float literal: `7.0`
+   |            ^ expected `f32`, found integer
+   |
+help: use a float literal
+   |
+LL |         x: 7.0,
+   |             ++
 
 error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/structure-constructor-type-mismatch.rs:48:15
@@ -70,19 +82,23 @@ error[E0308]: mismatched types
   --> $DIR/structure-constructor-type-mismatch.rs:49:12
    |
 LL |         x: 9,
-   |            ^
-   |            |
-   |            expected `f32`, found integer
-   |            help: use a float literal: `9.0`
+   |            ^ expected `f32`, found integer
+   |
+help: use a float literal
+   |
+LL |         x: 9.0,
+   |             ++
 
 error[E0308]: mismatched types
   --> $DIR/structure-constructor-type-mismatch.rs:50:12
    |
 LL |         y: 10,
-   |            ^^
-   |            |
-   |            expected `f32`, found integer
-   |            help: use a float literal: `10.0`
+   |            ^^ expected `f32`, found integer
+   |
+help: use a float literal
+   |
+LL |         y: 10.0,
+   |              ++
 
 error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/structure-constructor-type-mismatch.rs:54:9
diff --git a/tests/ui/suggestions/match-ergonomics.stderr b/tests/ui/suggestions/match-ergonomics.stderr
index a3e059e8ac6..2cd43c26ca3 100644
--- a/tests/ui/suggestions/match-ergonomics.stderr
+++ b/tests/ui/suggestions/match-ergonomics.stderr
@@ -17,18 +17,24 @@ LL +         [v] => {},
 error[E0529]: expected an array or slice, found `Vec<i32>`
   --> $DIR/match-ergonomics.rs:8:9
    |
-LL |     match x {
-   |           - help: consider slicing here: `x[..]`
 LL |         [&v] => {},
    |         ^^^^ pattern cannot match with input type `Vec<i32>`
+   |
+help: consider slicing here
+   |
+LL |     match x[..] {
+   |            ++++
 
 error[E0529]: expected an array or slice, found `Vec<i32>`
   --> $DIR/match-ergonomics.rs:20:9
    |
-LL |     match x {
-   |           - help: consider slicing here: `x[..]`
 LL |         [v] => {},
    |         ^^^ pattern cannot match with input type `Vec<i32>`
+   |
+help: consider slicing here
+   |
+LL |     match x[..] {
+   |            ++++
 
 error[E0308]: mismatched types
   --> $DIR/match-ergonomics.rs:29:9
diff --git a/tests/ui/suggestions/parenthesized-deref-suggestion.stderr b/tests/ui/suggestions/parenthesized-deref-suggestion.stderr
index 9f185f5dd52..29e973b3a17 100644
--- a/tests/ui/suggestions/parenthesized-deref-suggestion.stderr
+++ b/tests/ui/suggestions/parenthesized-deref-suggestion.stderr
@@ -4,19 +4,21 @@ error[E0609]: no field `opts` on type `*const Session`
 LL |     (sess as *const Session).opts;
    |                              ^^^^ unknown field
    |
-help: `(sess as *const Session)` is a raw pointer; try dereferencing it
+help: the value is a raw pointer; try dereferencing it
    |
 LL |     (*(sess as *const Session)).opts;
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+   |     ++                        +
 
 error[E0609]: no field `0` on type `[u32; 1]`
   --> $DIR/parenthesized-deref-suggestion.rs:10:21
    |
 LL |     (x as [u32; 1]).0;
-   |     ----------------^
-   |     |               |
-   |     |               unknown field
-   |     help: instead of using tuple indexing, use array indexing: `(x as [u32; 1])[0]`
+   |                     ^ unknown field
+   |
+help: instead of using tuple indexing, use array indexing
+   |
+LL |     (x as [u32; 1])[0];
+   |                    ~ +
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/suggestions/pattern-slice-vec.stderr b/tests/ui/suggestions/pattern-slice-vec.stderr
index f69e7de971a..36a9df3f750 100644
--- a/tests/ui/suggestions/pattern-slice-vec.stderr
+++ b/tests/ui/suggestions/pattern-slice-vec.stderr
@@ -2,42 +2,56 @@ error[E0529]: expected an array or slice, found `Vec<i32>`
   --> $DIR/pattern-slice-vec.rs:8:12
    |
 LL |     if let [_, _, _] = foo() {}
-   |            ^^^^^^^^^   ----- help: consider slicing here: `foo()[..]`
-   |            |
-   |            pattern cannot match with input type `Vec<i32>`
+   |            ^^^^^^^^^ pattern cannot match with input type `Vec<i32>`
+   |
+help: consider slicing here
+   |
+LL |     if let [_, _, _] = foo()[..] {}
+   |                             ++++
 
 error[E0529]: expected an array or slice, found `Vec<i32>`
   --> $DIR/pattern-slice-vec.rs:12:12
    |
 LL |     if let [] = &foo() {}
-   |            ^^   ------ help: consider slicing here: `&foo()[..]`
-   |            |
-   |            pattern cannot match with input type `Vec<i32>`
+   |            ^^ pattern cannot match with input type `Vec<i32>`
+   |
+help: consider slicing here
+   |
+LL |     if let [] = &foo()[..] {}
+   |                       ++++
 
 error[E0529]: expected an array or slice, found `Vec<i32>`
   --> $DIR/pattern-slice-vec.rs:16:12
    |
 LL |     if let [] = foo() {}
-   |            ^^   ----- help: consider slicing here: `foo()[..]`
-   |            |
-   |            pattern cannot match with input type `Vec<i32>`
+   |            ^^ pattern cannot match with input type `Vec<i32>`
+   |
+help: consider slicing here
+   |
+LL |     if let [] = foo()[..] {}
+   |                      ++++
 
 error[E0529]: expected an array or slice, found `Vec<_>`
   --> $DIR/pattern-slice-vec.rs:23:9
    |
-LL |     match &v {
-   |           -- help: consider slicing here: `&v[..]`
-LL |
 LL |         [5] => {}
    |         ^^^ pattern cannot match with input type `Vec<_>`
+   |
+help: consider slicing here
+   |
+LL |     match &v[..] {
+   |             ++++
 
 error[E0529]: expected an array or slice, found `Vec<{integer}>`
   --> $DIR/pattern-slice-vec.rs:28:9
    |
 LL |     let [..] = vec![1, 2, 3];
-   |         ^^^^   ------------- help: consider slicing here: `vec![1, 2, 3][..]`
-   |         |
-   |         pattern cannot match with input type `Vec<{integer}>`
+   |         ^^^^ pattern cannot match with input type `Vec<{integer}>`
+   |
+help: consider slicing here
+   |
+LL |     let [..] = vec![1, 2, 3][..];
+   |                             ++++
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/suggestions/suppress-consider-slicing-issue-120605.stderr b/tests/ui/suggestions/suppress-consider-slicing-issue-120605.stderr
index c28d67604da..cab9bbb72df 100644
--- a/tests/ui/suggestions/suppress-consider-slicing-issue-120605.stderr
+++ b/tests/ui/suggestions/suppress-consider-slicing-issue-120605.stderr
@@ -2,9 +2,12 @@ error[E0529]: expected an array or slice, found `Vec<Struct>`
   --> $DIR/suppress-consider-slicing-issue-120605.rs:7:16
    |
 LL |         if let [Struct { a: [] }] = &self.a {
-   |                ^^^^^^^^^^^^^^^^^^   ------- help: consider slicing here: `&self.a[..]`
-   |                |
-   |                pattern cannot match with input type `Vec<Struct>`
+   |                ^^^^^^^^^^^^^^^^^^ pattern cannot match with input type `Vec<Struct>`
+   |
+help: consider slicing here
+   |
+LL |         if let [Struct { a: [] }] = &self.a[..] {
+   |                                            ++++
 
 error[E0529]: expected an array or slice, found `Vec<Struct>`
   --> $DIR/suppress-consider-slicing-issue-120605.rs:7:29
diff --git a/tests/ui/try-block/try-block-type-error.stderr b/tests/ui/try-block/try-block-type-error.stderr
index 3e9a584a551..2cdb5fdee79 100644
--- a/tests/ui/try-block/try-block-type-error.stderr
+++ b/tests/ui/try-block/try-block-type-error.stderr
@@ -2,10 +2,12 @@ error[E0271]: type mismatch resolving `<Option<f32> as Try>::Output == {integer}
   --> $DIR/try-block-type-error.rs:10:9
    |
 LL |         42
-   |         ^^
-   |         |
-   |         expected `f32`, found integer
-   |         help: use a float literal: `42.0`
+   |         ^^ expected `f32`, found integer
+   |
+help: use a float literal
+   |
+LL |         42.0
+   |           ++
 
 error[E0271]: type mismatch resolving `<Option<i32> as Try>::Output == ()`
   --> $DIR/try-block-type-error.rs:16:5
diff --git a/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903.rs b/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903.rs
deleted file mode 100644
index 4f9d54737dc..00000000000
--- a/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903.rs
+++ /dev/null
@@ -1,29 +0,0 @@
-//@ check-pass
-
-// See https://doc.rust-lang.org/1.77.0/nightly-rustc/rustc_lint/opaque_hidden_inferred_bound/static.OPAQUE_HIDDEN_INFERRED_BOUND.html#example
-
-#![feature(type_alias_impl_trait)]
-#![allow(dead_code)]
-
-trait Duh {}
-
-impl Duh for i32 {}
-
-trait Trait {
-    type Assoc: Duh;
-}
-
-impl<R: Duh, F: FnMut() -> R> Trait for F {
-    type Assoc = R;
-}
-
-type Sendable = impl Send;
-
-type Foo = impl Trait<Assoc = Sendable>;
-                   //~^ WARNING opaque type `Foo` does not satisfy its associated type bounds
-
-fn foo() -> Foo {
-    || 42
-}
-
-fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903.stderr b/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903.stderr
deleted file mode 100644
index 68def454c7f..00000000000
--- a/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-warning: opaque type `Foo` does not satisfy its associated type bounds
-  --> $DIR/tait-in-function-return-type-issue-101903.rs:22:23
-   |
-LL |     type Assoc: Duh;
-   |                 --- this associated type bound is unsatisfied for `Sendable`
-...
-LL | type Foo = impl Trait<Assoc = Sendable>;
-   |                       ^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(opaque_hidden_inferred_bound)]` on by default
-
-warning: 1 warning emitted
-
diff --git a/tests/ui/type/subtyping-opaque-type.rs b/tests/ui/type/subtyping-opaque-type.rs
deleted file mode 100644
index e17114a3647..00000000000
--- a/tests/ui/type/subtyping-opaque-type.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-//@ check-pass
-//@ compile-flags: -Zvalidate-mir
-trait Duh {}
-
-impl Duh for i32 {}
-
-trait Trait {
-    type Assoc: Duh;
-}
-
-impl<R: Duh, F: FnMut() -> R> Trait for F {
-    type Assoc = R;
-}
-
-fn foo() -> impl Trait<Assoc = impl Send> {
-    || 42
-}
-
-fn main() {}
diff --git a/tests/ui/type/type-parameter-defaults-referencing-Self.stderr b/tests/ui/type/type-parameter-defaults-referencing-Self.stderr
index 16d08b26722..c81405f03f8 100644
--- a/tests/ui/type/type-parameter-defaults-referencing-Self.stderr
+++ b/tests/ui/type/type-parameter-defaults-referencing-Self.stderr
@@ -5,9 +5,13 @@ LL | trait Foo<T=Self> {
    | ----------------- type parameter `T` must be specified for this
 ...
 LL | fn foo(x: &dyn Foo) { }
-   |                ^^^ help: set the type parameter to the desired type: `Foo<T>`
+   |                ^^^
    |
    = note: because of the default `Self` reference, type parameters must be specified on object types
+help: set the type parameter to the desired type
+   |
+LL | fn foo(x: &dyn Foo<T>) { }
+   |                   +++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/typeck/issue-53712.rs b/tests/ui/typeck/issue-53712.rs
index 2353904d79d..49db4fa306a 100644
--- a/tests/ui/typeck/issue-53712.rs
+++ b/tests/ui/typeck/issue-53712.rs
@@ -5,5 +5,5 @@ fn main() {
     arr.0;
     //~^ ERROR no field `0` on type `[{integer}; 5]` [E0609]
     //~| HELP instead of using tuple indexing, use array indexing
-    //~| SUGGESTION arr[0]
+    //~| SUGGESTION [
 }
diff --git a/tests/ui/typeck/issue-53712.stderr b/tests/ui/typeck/issue-53712.stderr
index ec31766324b..ffaf5cde1d7 100644
--- a/tests/ui/typeck/issue-53712.stderr
+++ b/tests/ui/typeck/issue-53712.stderr
@@ -2,10 +2,12 @@ error[E0609]: no field `0` on type `[{integer}; 5]`
   --> $DIR/issue-53712.rs:5:9
    |
 LL |     arr.0;
-   |     ----^
-   |     |   |
-   |     |   unknown field
-   |     help: instead of using tuple indexing, use array indexing: `arr[0]`
+   |         ^ unknown field
+   |
+help: instead of using tuple indexing, use array indexing
+   |
+LL |     arr[0];
+   |        ~ +
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/typeck/issue-91328.stderr b/tests/ui/typeck/issue-91328.stderr
index f2f407bcaff..f9016400fd7 100644
--- a/tests/ui/typeck/issue-91328.stderr
+++ b/tests/ui/typeck/issue-91328.stderr
@@ -1,38 +1,46 @@
 error[E0529]: expected an array or slice, found `Vec<i32>`
   --> $DIR/issue-91328.rs:10:12
    |
-LL |     match r {
-   |           - help: consider using `as_deref` here: `r.as_deref()`
-LL |
 LL |         Ok([a, b]) => a + b,
    |            ^^^^^^ pattern cannot match with input type `Vec<i32>`
+   |
+help: consider using `as_deref` here
+   |
+LL |     match r.as_deref() {
+   |            +++++++++++
 
 error[E0529]: expected an array or slice, found `Vec<i32>`
   --> $DIR/issue-91328.rs:20:14
    |
-LL |     match o {
-   |           - help: consider using `as_deref` here: `o.as_deref()`
-LL |
 LL |         Some([a, b]) => a + b,
    |              ^^^^^^ pattern cannot match with input type `Vec<i32>`
+   |
+help: consider using `as_deref` here
+   |
+LL |     match o.as_deref() {
+   |            +++++++++++
 
 error[E0529]: expected an array or slice, found `Vec<i32>`
   --> $DIR/issue-91328.rs:30:9
    |
-LL |     match v {
-   |           - help: consider slicing here: `v[..]`
-LL |
 LL |         [a, b] => a + b,
    |         ^^^^^^ pattern cannot match with input type `Vec<i32>`
+   |
+help: consider slicing here
+   |
+LL |     match v[..] {
+   |            ++++
 
 error[E0529]: expected an array or slice, found `Box<[i32; 2]>`
   --> $DIR/issue-91328.rs:40:14
    |
-LL |     match a {
-   |           - help: consider using `as_deref` here: `a.as_deref()`
-LL |
 LL |         Some([a, b]) => a + b,
    |              ^^^^^^ pattern cannot match with input type `Box<[i32; 2]>`
+   |
+help: consider using `as_deref` here
+   |
+LL |     match a.as_deref() {
+   |            +++++++++++
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/unboxed-closures/unboxed-closure-immutable-capture.stderr b/tests/ui/unboxed-closures/unboxed-closure-immutable-capture.stderr
index ad5451ced55..04f9ab246b3 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-immutable-capture.stderr
+++ b/tests/ui/unboxed-closures/unboxed-closure-immutable-capture.stderr
@@ -1,73 +1,90 @@
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
   --> $DIR/unboxed-closure-immutable-capture.rs:9:13
    |
-LL |     let x = 0;
-   |         - help: consider changing this to be mutable: `mut x`
 LL |     move || x = 1;
    |             ^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut x = 0;
+   |         +++
 
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/unboxed-closure-immutable-capture.rs:10:17
    |
-LL |     let x = 0;
-   |         - help: consider changing this to be mutable: `mut x`
-LL |     move || x = 1;
 LL |     move || set(&mut x);
    |                 ^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut x = 0;
+   |         +++
 
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
   --> $DIR/unboxed-closure-immutable-capture.rs:11:13
    |
-LL |     let x = 0;
-   |         - help: consider changing this to be mutable: `mut x`
-...
 LL |     move || x = 1;
    |             ^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut x = 0;
+   |         +++
 
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/unboxed-closure-immutable-capture.rs:12:17
    |
-LL |     let x = 0;
-   |         - help: consider changing this to be mutable: `mut x`
-...
 LL |     move || set(&mut x);
    |                 ^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut x = 0;
+   |         +++
 
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
   --> $DIR/unboxed-closure-immutable-capture.rs:13:8
    |
-LL |     let x = 0;
-   |         - help: consider changing this to be mutable: `mut x`
-...
 LL |     || x = 1;
    |        ^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut x = 0;
+   |         +++
 
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/unboxed-closure-immutable-capture.rs:14:12
    |
-LL |     let x = 0;
-   |         - help: consider changing this to be mutable: `mut x`
-...
 LL |     || set(&mut x);
    |            ^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut x = 0;
+   |         +++
 
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
   --> $DIR/unboxed-closure-immutable-capture.rs:15:8
    |
-LL |     let x = 0;
-   |         - help: consider changing this to be mutable: `mut x`
-...
 LL |     || x = 1;
    |        ^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut x = 0;
+   |         +++
 
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/unboxed-closure-immutable-capture.rs:16:12
    |
-LL |     let x = 0;
-   |         - help: consider changing this to be mutable: `mut x`
-...
 LL |     || set(&mut x);
    |            ^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut x = 0;
+   |         +++
 
 error: aborting due to 8 previous errors
 
diff --git a/tests/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.stderr b/tests/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.stderr
index 5c93ed6d7f7..07c66276eaf 100644
--- a/tests/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.stderr
+++ b/tests/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.stderr
@@ -1,13 +1,16 @@
 error[E0596]: cannot borrow `tick1` as mutable, as it is not declared as mutable
   --> $DIR/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.rs:16:9
    |
-LL |     let tick1 = || {
-   |         ----- help: consider changing this to be mutable: `mut tick1`
 LL |         counter += 1;
    |         ------- calling `tick1` requires mutable binding due to mutable borrow of `counter`
 ...
 LL |         tick1();
    |         ^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut tick1 = || {
+   |         +++
 
 error[E0596]: cannot borrow `tick2` as mutable, as it is not declared as mutable
   --> $DIR/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.rs:19:5
diff --git a/tests/ui/unboxed-closures/unboxed-closures-mutate-upvar.stderr b/tests/ui/unboxed-closures/unboxed-closures-mutate-upvar.stderr
index 26f97b51913..80caddb2a11 100644
--- a/tests/ui/unboxed-closures/unboxed-closures-mutate-upvar.stderr
+++ b/tests/ui/unboxed-closures/unboxed-closures-mutate-upvar.stderr
@@ -1,29 +1,35 @@
 error[E0594]: cannot assign to `n`, as it is not declared as mutable
   --> $DIR/unboxed-closures-mutate-upvar.rs:15:9
    |
-LL |     let n = 0;
-   |         - help: consider changing this to be mutable: `mut n`
-LL |     let mut f = to_fn_mut(|| {
 LL |         n += 1;
    |         ^^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut n = 0;
+   |         +++
 
 error[E0594]: cannot assign to `n`, as it is not declared as mutable
   --> $DIR/unboxed-closures-mutate-upvar.rs:32:9
    |
-LL |     let n = 0;
-   |         - help: consider changing this to be mutable: `mut n`
-...
 LL |         n += 1;
    |         ^^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut n = 0;
+   |         +++
 
 error[E0594]: cannot assign to `n`, as it is not declared as mutable
   --> $DIR/unboxed-closures-mutate-upvar.rs:46:9
    |
-LL |     let n = 0;
-   |         - help: consider changing this to be mutable: `mut n`
-LL |     let mut f = to_fn(move || {
 LL |         n += 1;
    |         ^^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut n = 0;
+   |         +++
 
 error[E0594]: cannot assign to `n`, as it is a captured variable in a `Fn` closure
   --> $DIR/unboxed-closures-mutate-upvar.rs:53:9
diff --git a/tests/ui/unsafe/unsafe-fn-autoderef.stderr b/tests/ui/unsafe/unsafe-fn-autoderef.stderr
index c3ab8020222..c19028ac866 100644
--- a/tests/ui/unsafe/unsafe-fn-autoderef.stderr
+++ b/tests/ui/unsafe/unsafe-fn-autoderef.stderr
@@ -2,10 +2,12 @@ error[E0609]: no field `f` on type `*const Rec`
   --> $DIR/unsafe-fn-autoderef.rs:19:14
    |
 LL |     return p.f;
-   |            --^
-   |            | |
-   |            | unknown field
-   |            help: `p` is a raw pointer; try dereferencing it: `(*p).f`
+   |              ^ unknown field
+   |
+help: `p` is a raw pointer; try dereferencing it
+   |
+LL |     return (*p).f;
+   |            ++ +
 
 error: aborting due to 1 previous error