about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2021-06-28 11:22:47 -0700
committerEsteban Küber <esteban@kuber.com.ar>2021-07-30 09:26:31 -0700
commit0b8f192cfee2f107867e7b9a0b0f781a5cb48787 (patch)
tree7740090507212c2bf5f630672125bab43d68d093
parent5fb3394cbdf0622c9d0c292feb55db0f4c828dc3 (diff)
downloadrust-0b8f192cfee2f107867e7b9a0b0f781a5cb48787.tar.gz
rust-0b8f192cfee2f107867e7b9a0b0f781a5cb48787.zip
Use multispan suggestions more often
* Use more accurate span for `async move` suggestion
* Use more accurate span for deref suggestion
* Use `multipart_suggestion` more often
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs24
-rw-r--r--compiler/rustc_errors/src/diagnostic_builder.rs14
-rw-r--r--compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs23
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs2
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs14
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs2
-rw-r--r--compiler/rustc_session/src/parse.rs20
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs15
-rw-r--r--compiler/rustc_typeck/src/check/demand.rs104
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs2
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs67
-rw-r--r--src/test/ui/async-await/async-borrowck-escaping-block-error.stderr4
-rw-r--r--src/test/ui/async-await/async-borrowck-escaping-closure-error.stderr2
-rw-r--r--src/test/ui/async-await/issues/issue-62097.nll.stderr2
-rw-r--r--src/test/ui/async-await/issues/issue-78938-async-block.stderr4
-rw-r--r--src/test/ui/block-result/issue-5500.stderr9
-rw-r--r--src/test/ui/borrowck/borrowck-escaping-closure-error-1.stderr2
-rw-r--r--src/test/ui/borrowck/borrowck-escaping-closure-error-2.stderr2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr2
-rw-r--r--src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr2
-rw-r--r--src/test/ui/const-generics/occurs-check/unused-substs-3.stderr3
-rw-r--r--src/test/ui/const-generics/occurs-check/unused-substs-5.stderr3
-rw-r--r--src/test/ui/deref-suggestion.stderr65
-rw-r--r--src/test/ui/diverging-tuple-parts-39485.stderr2
-rw-r--r--src/test/ui/estr-subtyping.stderr3
-rw-r--r--src/test/ui/expr/if/if-no-match-bindings.stderr80
-rw-r--r--src/test/ui/impl-trait/does-not-live-long-enough.stderr2
-rw-r--r--src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr72
-rw-r--r--src/test/ui/infinite/infinite-autoderef.stderr10
-rw-r--r--src/test/ui/issues/issue-22644.stderr72
-rw-r--r--src/test/ui/issues/issue-32122-1.stderr10
-rw-r--r--src/test/ui/issues/issue-32122-2.stderr10
-rw-r--r--src/test/ui/issues/issue-42954.stderr11
-rw-r--r--src/test/ui/issues/issue-50687-ice-on-borrow.stderr10
-rw-r--r--src/test/ui/issues/issue-71676-1.stderr40
-rw-r--r--src/test/ui/issues/issue-71676-2.stderr10
-rw-r--r--src/test/ui/issues/issue-77218.stderr8
-rw-r--r--src/test/ui/json-bom-plus-crlf-multifile.stderr6
-rw-r--r--src/test/ui/json-bom-plus-crlf.stderr6
-rw-r--r--src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.stderr2
-rw-r--r--src/test/ui/mismatched_types/abridged.stderr20
-rw-r--r--src/test/ui/never_type/issue-52443.stderr9
-rw-r--r--src/test/ui/occurs-check-2.stderr10
-rw-r--r--src/test/ui/occurs-check.stderr10
-rw-r--r--src/test/ui/parser/expr-as-stmt-2.stderr7
-rw-r--r--src/test/ui/parser/expr-as-stmt.stderr36
-rw-r--r--src/test/ui/regions/region-borrow-params-issue-29793-big.stderr4
-rw-r--r--src/test/ui/regions/region-borrow-params-issue-29793-small.stderr40
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr20
-rw-r--r--src/test/ui/span/coerce-suggestions.stderr10
-rw-r--r--src/test/ui/static/bad-const-type.stderr3
-rw-r--r--src/test/ui/str/str-lit-type-mismatch.stderr30
-rw-r--r--src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr18
-rw-r--r--src/test/ui/suggestions/format-borrow.stderr44
-rw-r--r--src/test/ui/suggestions/issue-52820.stderr10
-rw-r--r--src/test/ui/suggestions/issue-59819.stderr25
-rw-r--r--src/test/ui/suggestions/issue-82361.stderr30
-rw-r--r--src/test/ui/suggestions/issue-83943.stderr3
-rw-r--r--src/test/ui/suggestions/mut-ref-reassignment.stderr4
-rw-r--r--src/test/ui/typeck/conversion-methods.stderr19
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-6250.stderr10
61 files changed, 661 insertions, 442 deletions
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 45661ac1562..8199c44ee2a 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -444,6 +444,30 @@ impl Diagnostic {
         self
     }
 
+    /// Prints out a message with multiple suggested edits of the code.
+    /// See also [`Diagnostic::span_suggestion()`].
+    pub fn multipart_suggestions(
+        &mut self,
+        msg: &str,
+        suggestions: impl Iterator<Item = Vec<(Span, String)>>,
+        applicability: Applicability,
+    ) -> &mut Self {
+        self.suggestions.push(CodeSuggestion {
+            substitutions: suggestions
+                .map(|sugg| Substitution {
+                    parts: sugg
+                        .into_iter()
+                        .map(|(span, snippet)| SubstitutionPart { snippet, span })
+                        .collect(),
+                })
+                .collect(),
+            msg: msg.to_owned(),
+            style: SuggestionStyle::ShowCode,
+            applicability,
+            tool_metadata: Default::default(),
+        });
+        self
+    }
     /// Prints out a message with a suggested edit of the code. If the suggestion is presented
     /// inline, it will only show the message and not the suggestion.
     ///
diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs
index 282877d5dd1..d35b2924803 100644
--- a/compiler/rustc_errors/src/diagnostic_builder.rs
+++ b/compiler/rustc_errors/src/diagnostic_builder.rs
@@ -301,6 +301,20 @@ impl<'a> DiagnosticBuilder<'a> {
         self
     }
 
+    /// See [`Diagnostic::multipart_suggestions()`].
+    pub fn multipart_suggestions(
+        &mut self,
+        msg: &str,
+        suggestions: impl Iterator<Item = Vec<(Span, String)>>,
+        applicability: Applicability,
+    ) -> &mut Self {
+        if !self.0.allow_suggestions {
+            return self;
+        }
+        self.0.diagnostic.multipart_suggestions(msg, suggestions, applicability);
+        self
+    }
+
     /// See [`Diagnostic::span_suggestion_short()`].
     pub fn span_suggestion_short(
         &mut self,
diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs
index 2e854ea5be7..a9bfbb51573 100644
--- a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs
@@ -12,7 +12,7 @@ use rustc_middle::mir::{
 use rustc_middle::ty::{self, suggest_constraining_type_param, Ty};
 use rustc_span::source_map::DesugaringKind;
 use rustc_span::symbol::sym;
-use rustc_span::{MultiSpan, Span, DUMMY_SP};
+use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP};
 use rustc_trait_selection::infer::InferCtxtExt;
 
 use crate::dataflow::drop_flag_effects;
@@ -1393,18 +1393,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         let tcx = self.infcx.tcx;
         let args_span = use_span.args_or_use();
 
-        let suggestion = match tcx.sess.source_map().span_to_snippet(args_span) {
-            Ok(mut string) => {
+        let (sugg_span, suggestion) = match tcx.sess.source_map().span_to_snippet(args_span) {
+            Ok(string) => {
                 if string.starts_with("async ") {
-                    string.insert_str(6, "move ");
+                    let pos = args_span.lo() + BytePos(6);
+                    (args_span.with_lo(pos).with_hi(pos), "move ".to_string())
                 } else if string.starts_with("async|") {
-                    string.insert_str(5, " move");
+                    let pos = args_span.lo() + BytePos(5);
+                    (args_span.with_lo(pos).with_hi(pos), " move".to_string())
                 } else {
-                    string.insert_str(0, "move ");
-                };
-                string
+                    (args_span.shrink_to_lo(), "move ".to_string())
+                }
             }
-            Err(_) => "move |<args>| <body>".to_string(),
+            Err(_) => (args_span, "move |<args>| <body>".to_string()),
         };
         let kind = match use_span.generator_kind() {
             Some(generator_kind) => match generator_kind {
@@ -1420,8 +1421,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
 
         let mut err =
             self.cannot_capture_in_long_lived_closure(args_span, kind, captured_var, var_span);
-        err.span_suggestion(
-            args_span,
+        err.span_suggestion_verbose(
+            sugg_span,
             &format!(
                 "to force the {} to take ownership of {} (and any \
                  other referenced variables), use the `move` keyword",
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 9818bd8d314..273fbea3580 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -1770,7 +1770,7 @@ impl<'a> Parser<'a> {
         let mut err = self.struct_span_err(span, &msg);
         let sp = self.sess.source_map().start_point(self.token.span);
         if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&sp) {
-            self.sess.expr_parentheses_needed(&mut err, *sp, None);
+            self.sess.expr_parentheses_needed(&mut err, *sp);
         }
         err.span_label(span, "expected expression");
         err
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index ef05f64da94..b774c76103f 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -358,7 +358,7 @@ impl<'a> Parser<'a> {
             &format!("expected expression, found `{}`", pprust::token_to_string(&self.token),),
         );
         err.span_label(self.token.span, "expected expression");
-        self.sess.expr_parentheses_needed(&mut err, lhs.span, Some(pprust::expr_to_string(&lhs)));
+        self.sess.expr_parentheses_needed(&mut err, lhs.span);
         err.emit();
     }
 
@@ -696,20 +696,18 @@ impl<'a> Parser<'a> {
                         let expr =
                             mk_expr(self, lhs, self.mk_ty(path.span, TyKind::Path(None, path)));
 
-                        let expr_str = self
-                            .span_to_snippet(expr.span)
-                            .unwrap_or_else(|_| pprust::expr_to_string(&expr));
-
                         self.struct_span_err(self.token.span, &msg)
                             .span_label(
                                 self.look_ahead(1, |t| t.span).to(span_after_type),
                                 "interpreted as generic arguments",
                             )
                             .span_label(self.token.span, format!("not interpreted as {}", op_noun))
-                            .span_suggestion(
-                                expr.span,
+                            .multipart_suggestion(
                                 &format!("try {} the cast value", op_verb),
-                                format!("({})", expr_str),
+                                vec![
+                                    (expr.span.shrink_to_lo(), "(".to_string()),
+                                    (expr.span.shrink_to_hi(), ")".to_string()),
+                                ],
                                 Applicability::MachineApplicable,
                             )
                             .emit();
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index 7219e39ea6b..b03b5459981 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -763,7 +763,7 @@ impl<'a> Parser<'a> {
 
         let sp = self.sess.source_map().start_point(self.token.span);
         if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&sp) {
-            self.sess.expr_parentheses_needed(&mut err, *sp, None);
+            self.sess.expr_parentheses_needed(&mut err, *sp);
         }
 
         Err(err)
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs
index 226fde2343a..a007b530302 100644
--- a/compiler/rustc_session/src/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
@@ -228,20 +228,12 @@ impl ParseSess {
 
     /// Extend an error with a suggestion to wrap an expression with parentheses to allow the
     /// parser to continue parsing the following operation as part of the same expression.
-    pub fn expr_parentheses_needed(
-        &self,
-        err: &mut DiagnosticBuilder<'_>,
-        span: Span,
-        alt_snippet: Option<String>,
-    ) {
-        if let Some(snippet) = self.source_map().span_to_snippet(span).ok().or(alt_snippet) {
-            err.span_suggestion(
-                span,
-                "parentheses are required to parse this as an expression",
-                format!("({})", snippet),
-                Applicability::MachineApplicable,
-            );
-        }
+    pub fn expr_parentheses_needed(&self, err: &mut DiagnosticBuilder<'_>, span: Span) {
+        err.multipart_suggestion(
+            "parentheses are required to parse this as an expression",
+            vec![(span.shrink_to_lo(), "(".to_string()), (span.shrink_to_hi(), ")".to_string())],
+            Applicability::MachineApplicable,
+        );
     }
 
     pub fn save_proc_macro_span(&self, span: Span) -> usize {
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 9a33875d6e4..712fea84a8b 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -1163,15 +1163,18 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             if is_object_safe {
                 // Suggest `-> Box<dyn Trait>` and `Box::new(returned_value)`.
                 // Get all the return values and collect their span and suggestion.
-                if let Some(mut suggestions) = visitor
+                let mut suggestions: Vec<_> = visitor
                     .returns
                     .iter()
-                    .map(|expr| {
-                        let snip = sm.span_to_snippet(expr.span).ok()?;
-                        Some((expr.span, format!("Box::new({})", snip)))
+                    .flat_map(|expr| {
+                        vec![
+                            (expr.span.shrink_to_lo(), "Box::new(".to_string()),
+                            (expr.span.shrink_to_hi(), ")".to_string()),
+                        ]
+                        .into_iter()
                     })
-                    .collect::<Option<Vec<_>>>()
-                {
+                    .collect();
+                if !suggestions.is_empty() {
                     // Add the suggestion for the return type.
                     suggestions.push((ret_ty.span, format!("Box<dyn {}>", trait_obj)));
                     err.multipart_suggestion(
diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs
index 3ea59906d3d..e5a00f70639 100644
--- a/compiler/rustc_typeck/src/check/demand.rs
+++ b/compiler/rustc_typeck/src/check/demand.rs
@@ -13,7 +13,7 @@ use rustc_middle::ty::adjustment::AllowTwoPhase;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{self, AssocItem, Ty, TypeAndMut};
 use rustc_span::symbol::sym;
-use rustc_span::Span;
+use rustc_span::{BytePos, Span};
 
 use super::method::probe;
 
@@ -415,7 +415,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expr: &hir::Expr<'_>,
         checked_ty: Ty<'tcx>,
         expected: Ty<'tcx>,
-    ) -> Option<(Span, &'static str, String, Applicability)> {
+    ) -> Option<(Span, &'static str, String, Applicability, bool /* verbose */)> {
         let sess = self.sess();
         let sp = expr.span;
 
@@ -441,12 +441,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 (&ty::Str, &ty::Array(arr, _) | &ty::Slice(arr)) if arr == self.tcx.types.u8 => {
                     if let hir::ExprKind::Lit(_) = expr.kind {
                         if let Ok(src) = sm.span_to_snippet(sp) {
-                            if let Some(src) = replace_prefix(&src, "b\"", "\"") {
+                            if let Some(_) = replace_prefix(&src, "b\"", "\"") {
+                                let pos = sp.lo() + BytePos(1);
                                 return Some((
-                                    sp,
+                                    sp.with_hi(pos),
                                     "consider removing the leading `b`",
-                                    src,
+                                    String::new(),
                                     Applicability::MachineApplicable,
+                                    true,
                                 ));
                             }
                         }
@@ -455,12 +457,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 (&ty::Array(arr, _) | &ty::Slice(arr), &ty::Str) if arr == self.tcx.types.u8 => {
                     if let hir::ExprKind::Lit(_) = expr.kind {
                         if let Ok(src) = sm.span_to_snippet(sp) {
-                            if let Some(src) = replace_prefix(&src, "\"", "b\"") {
+                            if let Some(_) = replace_prefix(&src, "\"", "b\"") {
                                 return Some((
-                                    sp,
+                                    sp.shrink_to_lo(),
                                     "consider adding a leading `b`",
-                                    src,
+                                    "b".to_string(),
                                     Applicability::MachineApplicable,
+                                    true,
                                 ));
                             }
                         }
@@ -520,6 +523,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 sugg.1,
                                 sugg.2,
                                 Applicability::MachineApplicable,
+                                false,
                             ));
                         }
                         let field_name = if is_struct_pat_shorthand_field {
@@ -539,13 +543,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 //                                   |     |
                                 //    consider dereferencing here: `*opt`  |
                                 // expected mutable reference, found enum `Option`
-                                if let Ok(src) = sm.span_to_snippet(left_expr.span) {
+                                if sm.span_to_snippet(left_expr.span).is_ok() {
                                     return Some((
-                                        left_expr.span,
+                                        left_expr.span.shrink_to_lo(),
                                         "consider dereferencing here to assign to the mutable \
                                          borrowed piece of memory",
-                                        format!("*{}", src),
+                                        "*".to_string(),
                                         Applicability::MachineApplicable,
+                                        true,
                                     ));
                                 }
                             }
@@ -557,12 +562,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 "consider mutably borrowing here",
                                 format!("{}&mut {}", field_name, sugg_expr),
                                 Applicability::MachineApplicable,
+                                false,
                             ),
                             hir::Mutability::Not => (
                                 sp,
                                 "consider borrowing here",
                                 format!("{}&{}", field_name, sugg_expr),
                                 Applicability::MachineApplicable,
+                                false,
                             ),
                         });
                     }
@@ -584,24 +591,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     if let Some(call_span) =
                         iter::successors(Some(expr.span), |s| s.parent()).find(|&s| sp.contains(s))
                     {
-                        if let Ok(code) = sm.span_to_snippet(call_span) {
+                        if sm.span_to_snippet(call_span).is_ok() {
                             return Some((
-                                sp,
+                                sp.with_hi(call_span.lo()),
                                 "consider removing the borrow",
-                                code,
+                                String::new(),
                                 Applicability::MachineApplicable,
+                                true,
                             ));
                         }
                     }
                     return None;
                 }
                 if sp.contains(expr.span) {
-                    if let Ok(code) = sm.span_to_snippet(expr.span) {
+                    if sm.span_to_snippet(expr.span).is_ok() {
                         return Some((
-                            sp,
+                            sp.with_hi(expr.span.lo()),
                             "consider removing the borrow",
-                            code,
+                            String::new(),
                             Applicability::MachineApplicable,
+                            true,
                         ));
                     }
                 }
@@ -616,36 +625,59 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     if steps > 0 {
                         // The pointer type implements `Copy` trait so the suggestion is always valid.
                         if let Ok(src) = sm.span_to_snippet(sp) {
-                            let derefs = &"*".repeat(steps);
-                            if let Some((src, applicability)) = match mutbl_b {
+                            let derefs = "*".repeat(steps);
+                            if let Some((span, src, applicability)) = match mutbl_b {
                                 hir::Mutability::Mut => {
-                                    let new_prefix = "&mut ".to_owned() + derefs;
+                                    let new_prefix = "&mut ".to_owned() + &derefs;
                                     match mutbl_a {
                                         hir::Mutability::Mut => {
-                                            replace_prefix(&src, "&mut ", &new_prefix)
-                                                .map(|s| (s, Applicability::MachineApplicable))
+                                            replace_prefix(&src, "&mut ", &new_prefix).map(|_| {
+                                                let pos = sp.lo() + BytePos(5);
+                                                let sp = sp.with_lo(pos).with_hi(pos);
+                                                (sp, derefs, Applicability::MachineApplicable)
+                                            })
                                         }
                                         hir::Mutability::Not => {
-                                            replace_prefix(&src, "&", &new_prefix)
-                                                .map(|s| (s, Applicability::Unspecified))
+                                            replace_prefix(&src, "&", &new_prefix).map(|_| {
+                                                let pos = sp.lo() + BytePos(1);
+                                                let sp = sp.with_lo(pos).with_hi(pos);
+                                                (
+                                                    sp,
+                                                    format!("mut {}", derefs),
+                                                    Applicability::Unspecified,
+                                                )
+                                            })
                                         }
                                     }
                                 }
                                 hir::Mutability::Not => {
-                                    let new_prefix = "&".to_owned() + derefs;
+                                    let new_prefix = "&".to_owned() + &derefs;
                                     match mutbl_a {
                                         hir::Mutability::Mut => {
-                                            replace_prefix(&src, "&mut ", &new_prefix)
-                                                .map(|s| (s, Applicability::MachineApplicable))
+                                            replace_prefix(&src, "&mut ", &new_prefix).map(|_| {
+                                                let lo = sp.lo() + BytePos(1);
+                                                let hi = sp.lo() + BytePos(5);
+                                                let sp = sp.with_lo(lo).with_hi(hi);
+                                                (sp, derefs, Applicability::MachineApplicable)
+                                            })
                                         }
                                         hir::Mutability::Not => {
-                                            replace_prefix(&src, "&", &new_prefix)
-                                                .map(|s| (s, Applicability::MachineApplicable))
+                                            replace_prefix(&src, "&", &new_prefix).map(|_| {
+                                                let pos = sp.lo() + BytePos(1);
+                                                let sp = sp.with_lo(pos).with_hi(pos);
+                                                (sp, derefs, Applicability::MachineApplicable)
+                                            })
                                         }
                                     }
                                 }
                             } {
-                                return Some((sp, "consider dereferencing", src, applicability));
+                                return Some((
+                                    span,
+                                    "consider dereferencing",
+                                    src,
+                                    applicability,
+                                    true,
+                                ));
                             }
                         }
                     }
@@ -669,6 +701,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 message,
                                 suggestion,
                                 Applicability::MachineApplicable,
+                                false,
                             ));
                         } else if self.infcx.type_is_copy_modulo_regions(
                             self.param_env,
@@ -682,21 +715,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 } else {
                                     "consider dereferencing the type"
                                 };
-                                let suggestion = if is_struct_pat_shorthand_field {
-                                    format!("{}: *{}", code, code)
+                                let (span, suggestion) = if is_struct_pat_shorthand_field {
+                                    (expr.span, format!("{}: *{}", code, code))
                                 } else if self.is_else_if_block(expr) {
                                     // Don't suggest nonsense like `else *if`
                                     return None;
                                 } else if let Some(expr) = self.maybe_get_block_expr(expr.hir_id) {
-                                    format!("*{}", sm.span_to_snippet(expr.span).unwrap_or(code))
+                                    (expr.span.shrink_to_lo(), "*".to_string())
                                 } else {
-                                    format!("*{}", code)
+                                    (expr.span.shrink_to_lo(), "*".to_string())
                                 };
                                 return Some((
-                                    expr.span,
+                                    span,
                                     message,
                                     suggestion,
                                     Applicability::MachineApplicable,
+                                    true,
                                 ));
                             }
                         }
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index cfe1d1c6871..08258aac96f 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -344,7 +344,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         if let Some(sp) =
                             tcx.sess.parse_sess.ambiguous_block_expr_parse.borrow().get(&sp)
                         {
-                            tcx.sess.parse_sess.expr_parentheses_needed(&mut err, *sp, None);
+                            tcx.sess.parse_sess.expr_parentheses_needed(&mut err, *sp);
                         }
                         err.emit();
                         oprnd_t = tcx.ty_error();
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
index 54aab271fdb..0acf1d26e25 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
@@ -213,8 +213,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
     ) {
         let expr = expr.peel_blocks();
-        if let Some((sp, msg, suggestion, applicability)) = self.check_ref(expr, found, expected) {
-            err.span_suggestion(sp, msg, suggestion, applicability);
+        if let Some((sp, msg, suggestion, applicability, verbose)) =
+            self.check_ref(expr, found, expected)
+        {
+            if verbose {
+                err.span_suggestion_verbose(sp, msg, suggestion, applicability);
+            } else {
+                err.span_suggestion(sp, msg, suggestion, applicability);
+            }
         } else if let (ty::FnDef(def_id, ..), true) =
             (&found.kind(), self.suggest_fn_call(err, expr, expected, found))
         {
@@ -234,29 +240,36 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             None // do not suggest code that is already there (#53348)
                         } else {
                             let method_call_list = [".to_vec()", ".to_string()"];
-                            let sugg = if receiver.ends_with(".clone()")
+                            let mut sugg = if receiver.ends_with(".clone()")
                                 && method_call_list.contains(&method_call.as_str())
                             {
                                 let max_len = receiver.rfind('.').unwrap();
-                                format!("{}{}", &receiver[..max_len], method_call)
+                                vec![(
+                                    expr.span,
+                                    format!("{}{}", &receiver[..max_len], method_call),
+                                )]
                             } else {
                                 if expr.precedence().order() < ExprPrecedence::MethodCall.order() {
-                                    format!("({}){}", receiver, method_call)
+                                    vec![
+                                        (expr.span.shrink_to_lo(), "(".to_string()),
+                                        (expr.span.shrink_to_hi(), format!("){}", method_call)),
+                                    ]
                                 } else {
-                                    format!("{}{}", receiver, method_call)
+                                    vec![(expr.span.shrink_to_hi(), method_call)]
                                 }
                             };
-                            Some(if is_struct_pat_shorthand_field {
-                                format!("{}: {}", receiver, sugg)
-                            } else {
-                                sugg
-                            })
+                            if is_struct_pat_shorthand_field {
+                                sugg.insert(
+                                    0,
+                                    (expr.span.shrink_to_lo(), format!("{}: ", receiver)),
+                                );
+                            }
+                            Some(sugg)
                         }
                     })
                     .peekable();
                 if suggestions.peek().is_some() {
-                    err.span_suggestions(
-                        expr.span,
+                    err.multipart_suggestions(
                         "try using a conversion method",
                         suggestions,
                         Applicability::MaybeIncorrect,
@@ -283,14 +296,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return;
         }
         let boxed_found = self.tcx.mk_box(found);
-        if let (true, Ok(snippet)) = (
-            self.can_coerce(boxed_found, expected),
-            self.sess().source_map().span_to_snippet(expr.span),
-        ) {
-            err.span_suggestion(
-                expr.span,
+        if self.can_coerce(boxed_found, expected) {
+            err.multipart_suggestion(
                 "store this in the heap by calling `Box::new`",
-                format!("Box::new({})", snippet),
+                vec![
+                    (expr.span.shrink_to_lo(), "Box::new(".to_string()),
+                    (expr.span.shrink_to_hi(), ")".to_string()),
+                ],
                 Applicability::MachineApplicable,
             );
             err.note(
@@ -357,19 +369,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
         let boxed_found = self.tcx.mk_box(found);
         let new_found = self.tcx.mk_lang_item(boxed_found, LangItem::Pin).unwrap();
-        if let (true, Ok(snippet)) = (
-            self.can_coerce(new_found, expected),
-            self.sess().source_map().span_to_snippet(expr.span),
-        ) {
+        if self.can_coerce(new_found, expected) {
             match found.kind() {
                 ty::Adt(def, _) if def.is_box() => {
                     err.help("use `Box::pin`");
                 }
                 _ => {
-                    err.span_suggestion(
-                        expr.span,
+                    err.multipart_suggestion(
                         "you need to pin and box this expression",
-                        format!("Box::pin({})", snippet),
+                        vec![
+                            (expr.span.shrink_to_lo(), "Box::pin(".to_string()),
+                            (expr.span.shrink_to_hi(), ")".to_string()),
+                        ],
                         Applicability::MachineApplicable,
                     );
                 }
@@ -547,7 +558,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let sp = self.tcx.sess.source_map().start_point(expr.span);
         if let Some(sp) = self.tcx.sess.parse_sess.ambiguous_block_expr_parse.borrow().get(&sp) {
             // `{ 42 } &&x` (#61475) or `{ 42 } && if x { 1 } else { 0 }`
-            self.tcx.sess.parse_sess.expr_parentheses_needed(err, *sp, None);
+            self.tcx.sess.parse_sess.expr_parentheses_needed(err, *sp);
         }
     }
 
diff --git a/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr b/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr
index 599d0e13557..d0c91c4ab44 100644
--- a/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr
+++ b/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr
@@ -15,7 +15,7 @@ LL | fn test_boxed() -> Box<impl std::future::Future<Output = u32>> {
 help: to force the async block to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |     Box::new(async move { x } )
-   |                    ^^^^^^^^^^
+   |                    ^^^^
 
 error[E0373]: async block may outlive the current function, but it borrows `x`, which is owned by the current function
   --> $DIR/async-borrowck-escaping-block-error.rs:11:11
@@ -34,7 +34,7 @@ LL |     async { *x }
 help: to force the async block to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |     async move { *x }
-   |           ^^^^^^^^^^^
+   |           ^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/async-await/async-borrowck-escaping-closure-error.stderr b/src/test/ui/async-await/async-borrowck-escaping-closure-error.stderr
index 8bcfcf98920..1bcaaf0d6b3 100644
--- a/src/test/ui/async-await/async-borrowck-escaping-closure-error.stderr
+++ b/src/test/ui/async-await/async-borrowck-escaping-closure-error.stderr
@@ -14,7 +14,7 @@ LL |     Box::new((async || x)())
 help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |     Box::new((async move || x)())
-   |               ^^^^^^^^^^^^^
+   |                     ^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/async-await/issues/issue-62097.nll.stderr b/src/test/ui/async-await/issues/issue-62097.nll.stderr
index ab10e5f1810..1139175f8a0 100644
--- a/src/test/ui/async-await/issues/issue-62097.nll.stderr
+++ b/src/test/ui/async-await/issues/issue-62097.nll.stderr
@@ -14,7 +14,7 @@ LL |         foo(|| self.bar()).await;
 help: to force the closure to take ownership of `self` (and any other referenced variables), use the `move` keyword
    |
 LL |         foo(move || self.bar()).await;
-   |             ^^^^^^^
+   |             ^^^^
 
 error[E0521]: borrowed data escapes outside of associated function
   --> $DIR/issue-62097.rs:13:9
diff --git a/src/test/ui/async-await/issues/issue-78938-async-block.stderr b/src/test/ui/async-await/issues/issue-78938-async-block.stderr
index 01ffc48d654..22ebd86d85c 100644
--- a/src/test/ui/async-await/issues/issue-78938-async-block.stderr
+++ b/src/test/ui/async-await/issues/issue-78938-async-block.stderr
@@ -12,9 +12,7 @@ LL | |     });
 help: to force the async block to take ownership of `room_ref` (and any other referenced variables), use the `move` keyword
    |
 LL |     let gameloop_handle = spawn(async move {
-LL |         game_loop(Arc::clone(&room_ref))
-LL |     });
-   |
+   |                                       ^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/block-result/issue-5500.stderr b/src/test/ui/block-result/issue-5500.stderr
index 9d9f7ac2e4a..ef3e2da81b2 100644
--- a/src/test/ui/block-result/issue-5500.stderr
+++ b/src/test/ui/block-result/issue-5500.stderr
@@ -4,13 +4,14 @@ error[E0308]: mismatched types
 LL | fn main() {
    |           - expected `()` because of default return type
 LL |     &panic!()
-   |     ^^^^^^^^^
-   |     |
-   |     expected `()`, found reference
-   |     help: consider removing the borrow: `panic!()`
+   |     ^^^^^^^^^ expected `()`, found reference
    |
    = note: expected unit type `()`
               found reference `&_`
+help: consider removing the borrow
+   |
+LL |     panic!()
+   |    --
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-escaping-closure-error-1.stderr b/src/test/ui/borrowck/borrowck-escaping-closure-error-1.stderr
index 3195120cba2..161e4610d61 100644
--- a/src/test/ui/borrowck/borrowck-escaping-closure-error-1.stderr
+++ b/src/test/ui/borrowck/borrowck-escaping-closure-error-1.stderr
@@ -14,7 +14,7 @@ LL |     spawn(|| books.push(4));
 help: to force the closure to take ownership of `books` (and any other referenced variables), use the `move` keyword
    |
 LL |     spawn(move || books.push(4));
-   |           ^^^^^^^
+   |           ^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-escaping-closure-error-2.stderr b/src/test/ui/borrowck/borrowck-escaping-closure-error-2.stderr
index 3227aa9bb68..b07db6e12ad 100644
--- a/src/test/ui/borrowck/borrowck-escaping-closure-error-2.stderr
+++ b/src/test/ui/borrowck/borrowck-escaping-closure-error-2.stderr
@@ -14,7 +14,7 @@ LL |     Box::new(|| books.push(4))
 help: to force the closure to take ownership of `books` (and any other referenced variables), use the `move` keyword
    |
 LL |     Box::new(move || books.push(4))
-   |              ^^^^^^^
+   |              ^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr
index 29bd4b27d6b..311a1b84e0c 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr
@@ -15,7 +15,7 @@ LL | fn foo () -> impl FnMut()->() {
 help: to force the closure to take ownership of `p` (and any other referenced variables), use the `move` keyword
    |
 LL |     let mut c = move || {
-   |                 ^^^^^^^
+   |                 ^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr b/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr
index 1b0e0902d67..7823e357009 100644
--- a/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr
+++ b/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr
@@ -27,7 +27,7 @@ LL | |     })
 help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |     bar(move || {
-   |         ^^^^^^^
+   |         ^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-3.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-3.stderr
index 2551d68f974..fd8f8b2693a 100644
--- a/src/test/ui/const-generics/occurs-check/unused-substs-3.stderr
+++ b/src/test/ui/const-generics/occurs-check/unused-substs-3.stderr
@@ -2,10 +2,9 @@ error[E0308]: mismatched types
   --> $DIR/unused-substs-3.rs:16:9
    |
 LL |     t = foo;
-   |         ^^^
+   |         ^^^- help: try using a conversion method: `.to_vec()`
    |         |
    |         cyclic type of infinite size
-   |         help: try using a conversion method: `foo.to_vec()`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-5.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-5.stderr
index 239569dab09..be289f44f1b 100644
--- a/src/test/ui/const-generics/occurs-check/unused-substs-5.stderr
+++ b/src/test/ui/const-generics/occurs-check/unused-substs-5.stderr
@@ -2,10 +2,9 @@ error[E0308]: mismatched types
   --> $DIR/unused-substs-5.rs:15:9
    |
 LL |     x = q::<_, N>(x);
-   |         ^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^- help: try using a conversion method: `.to_vec()`
    |         |
    |         cyclic type of infinite size
-   |         help: try using a conversion method: `q::<_, N>(x).to_vec()`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/deref-suggestion.stderr b/src/test/ui/deref-suggestion.stderr
index b3f7b042aac..8c004148a5d 100644
--- a/src/test/ui/deref-suggestion.stderr
+++ b/src/test/ui/deref-suggestion.stderr
@@ -2,37 +2,42 @@ error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:8:9
    |
 LL |     foo(s);
-   |         ^
+   |         ^- help: try using a conversion method: `.to_string()`
    |         |
    |         expected struct `String`, found `&String`
-   |         help: try using a conversion method: `s.to_string()`
 
 error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:14:10
    |
 LL |     foo3(u);
+   |          ^ expected `u32`, found `&u32`
+   |
+help: consider dereferencing the borrow
+   |
+LL |     foo3(*u);
    |          ^
-   |          |
-   |          expected `u32`, found `&u32`
-   |          help: consider dereferencing the borrow: `*u`
 
 error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:30:9
    |
 LL |     foo(&"aaa".to_owned());
-   |         ^^^^^^^^^^^^^^^^^
-   |         |
-   |         expected struct `String`, found `&String`
-   |         help: consider removing the borrow: `"aaa".to_owned()`
+   |         ^^^^^^^^^^^^^^^^^ expected struct `String`, found `&String`
+   |
+help: consider removing the borrow
+   |
+LL |     foo("aaa".to_owned());
+   |        --
 
 error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:32:9
    |
 LL |     foo(&mut "aaa".to_owned());
-   |         ^^^^^^^^^^^^^^^^^^^^^
-   |         |
-   |         expected struct `String`, found `&mut String`
-   |         help: consider removing the borrow: `"aaa".to_owned()`
+   |         ^^^^^^^^^^^^^^^^^^^^^ expected struct `String`, found `&mut String`
+   |
+help: consider removing the borrow
+   |
+LL |     foo("aaa".to_owned());
+   |        --
 
 error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:2:20
@@ -75,37 +80,45 @@ error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:44:17
    |
 LL |     let r = R { i };
-   |                 ^
-   |                 |
-   |                 expected `u32`, found `&{integer}`
-   |                 help: consider dereferencing the borrow: `i: *i`
+   |                 ^ expected `u32`, found `&{integer}`
+   |
+help: consider dereferencing the borrow
+   |
+LL |     let r = R { i: *i };
+   |                 ^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:46:20
    |
 LL |     let r = R { i: i };
+   |                    ^ expected `u32`, found `&{integer}`
+   |
+help: consider dereferencing the borrow
+   |
+LL |     let r = R { i: *i };
    |                    ^
-   |                    |
-   |                    expected `u32`, found `&{integer}`
-   |                    help: consider dereferencing the borrow: `*i`
 
 error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:55:9
    |
 LL |         b
+   |         ^ expected `i32`, found `&{integer}`
+   |
+help: consider dereferencing the borrow
+   |
+LL |         *b
    |         ^
-   |         |
-   |         expected `i32`, found `&{integer}`
-   |         help: consider dereferencing the borrow: `*b`
 
 error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:63:9
    |
 LL |         b
+   |         ^ expected `i32`, found `&{integer}`
+   |
+help: consider dereferencing the borrow
+   |
+LL |         *b
    |         ^
-   |         |
-   |         expected `i32`, found `&{integer}`
-   |         help: consider dereferencing the borrow: `*b`
 
 error[E0308]: `if` and `else` have incompatible types
   --> $DIR/deref-suggestion.rs:68:12
diff --git a/src/test/ui/diverging-tuple-parts-39485.stderr b/src/test/ui/diverging-tuple-parts-39485.stderr
index ad3e5ab3dc9..017b73a0d86 100644
--- a/src/test/ui/diverging-tuple-parts-39485.stderr
+++ b/src/test/ui/diverging-tuple-parts-39485.stderr
@@ -13,7 +13,7 @@ LL | fn g() -> &_ {
 help: consider removing the borrow
    |
 LL |     panic!()
-   |     ^^^^^^^^
+   |    --
 
 error[E0308]: mismatched types
   --> $DIR/diverging-tuple-parts-39485.rs:12:5
diff --git a/src/test/ui/estr-subtyping.stderr b/src/test/ui/estr-subtyping.stderr
index 268ec63a80d..d929c32633a 100644
--- a/src/test/ui/estr-subtyping.stderr
+++ b/src/test/ui/estr-subtyping.stderr
@@ -2,10 +2,9 @@ error[E0308]: mismatched types
   --> $DIR/estr-subtyping.rs:10:15
    |
 LL |    wants_uniq(x);
-   |               ^
+   |               ^- help: try using a conversion method: `.to_string()`
    |               |
    |               expected struct `String`, found `&str`
-   |               help: try using a conversion method: `x.to_string()`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/expr/if/if-no-match-bindings.stderr b/src/test/ui/expr/if/if-no-match-bindings.stderr
index 3f382e023a7..554cc3a2bcf 100644
--- a/src/test/ui/expr/if/if-no-match-bindings.stderr
+++ b/src/test/ui/expr/if/if-no-match-bindings.stderr
@@ -2,73 +2,89 @@ error[E0308]: mismatched types
   --> $DIR/if-no-match-bindings.rs:18:8
    |
 LL |     if b_ref() {}
-   |        ^^^^^^^
-   |        |
-   |        expected `bool`, found `&bool`
-   |        help: consider dereferencing the borrow: `*b_ref()`
+   |        ^^^^^^^ expected `bool`, found `&bool`
+   |
+help: consider dereferencing the borrow
+   |
+LL |     if *b_ref() {}
+   |        ^
 
 error[E0308]: mismatched types
   --> $DIR/if-no-match-bindings.rs:19:8
    |
 LL |     if b_mut_ref() {}
-   |        ^^^^^^^^^^^
-   |        |
-   |        expected `bool`, found `&mut bool`
-   |        help: consider dereferencing the borrow: `*b_mut_ref()`
+   |        ^^^^^^^^^^^ expected `bool`, found `&mut bool`
+   |
+help: consider dereferencing the borrow
+   |
+LL |     if *b_mut_ref() {}
+   |        ^
 
 error[E0308]: mismatched types
   --> $DIR/if-no-match-bindings.rs:20:8
    |
 LL |     if &true {}
-   |        ^^^^^
-   |        |
-   |        expected `bool`, found `&bool`
-   |        help: consider removing the borrow: `true`
+   |        ^^^^^ expected `bool`, found `&bool`
+   |
+help: consider removing the borrow
+   |
+LL |     if true {}
+   |       --
 
 error[E0308]: mismatched types
   --> $DIR/if-no-match-bindings.rs:21:8
    |
 LL |     if &mut true {}
-   |        ^^^^^^^^^
-   |        |
-   |        expected `bool`, found `&mut bool`
-   |        help: consider removing the borrow: `true`
+   |        ^^^^^^^^^ expected `bool`, found `&mut bool`
+   |
+help: consider removing the borrow
+   |
+LL |     if true {}
+   |       --
 
 error[E0308]: mismatched types
   --> $DIR/if-no-match-bindings.rs:24:11
    |
 LL |     while b_ref() {}
-   |           ^^^^^^^
-   |           |
-   |           expected `bool`, found `&bool`
-   |           help: consider dereferencing the borrow: `*b_ref()`
+   |           ^^^^^^^ expected `bool`, found `&bool`
+   |
+help: consider dereferencing the borrow
+   |
+LL |     while *b_ref() {}
+   |           ^
 
 error[E0308]: mismatched types
   --> $DIR/if-no-match-bindings.rs:25:11
    |
 LL |     while b_mut_ref() {}
-   |           ^^^^^^^^^^^
-   |           |
-   |           expected `bool`, found `&mut bool`
-   |           help: consider dereferencing the borrow: `*b_mut_ref()`
+   |           ^^^^^^^^^^^ expected `bool`, found `&mut bool`
+   |
+help: consider dereferencing the borrow
+   |
+LL |     while *b_mut_ref() {}
+   |           ^
 
 error[E0308]: mismatched types
   --> $DIR/if-no-match-bindings.rs:26:11
    |
 LL |     while &true {}
-   |           ^^^^^
-   |           |
-   |           expected `bool`, found `&bool`
-   |           help: consider removing the borrow: `true`
+   |           ^^^^^ expected `bool`, found `&bool`
+   |
+help: consider removing the borrow
+   |
+LL |     while true {}
+   |          --
 
 error[E0308]: mismatched types
   --> $DIR/if-no-match-bindings.rs:27:11
    |
 LL |     while &mut true {}
-   |           ^^^^^^^^^
-   |           |
-   |           expected `bool`, found `&mut bool`
-   |           help: consider removing the borrow: `true`
+   |           ^^^^^^^^^ expected `bool`, found `&mut bool`
+   |
+help: consider removing the borrow
+   |
+LL |     while true {}
+   |          --
 
 error: aborting due to 8 previous errors
 
diff --git a/src/test/ui/impl-trait/does-not-live-long-enough.stderr b/src/test/ui/impl-trait/does-not-live-long-enough.stderr
index 468c2f36629..73fd5e8ded3 100644
--- a/src/test/ui/impl-trait/does-not-live-long-enough.stderr
+++ b/src/test/ui/impl-trait/does-not-live-long-enough.stderr
@@ -14,7 +14,7 @@ LL |     fn started_with<'a>(&'a self, prefix: &'a str) -> impl Iterator<Item=&'
 help: to force the closure to take ownership of `prefix` (and any other referenced variables), use the `move` keyword
    |
 LL |         self.data.iter().filter(move |s| s.starts_with(prefix)).map(|s| s.as_ref())
-   |                                 ^^^^^^^^
+   |                                 ^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr
index 00145d10ed7..0ecec5eea36 100644
--- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr
+++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr
@@ -140,14 +140,15 @@ LL | fn bam() -> Box<dyn Trait> {
    |             -------------- expected `Box<(dyn Trait + 'static)>` because of return type
 LL |     if true {
 LL |         return Struct;
-   |                ^^^^^^
-   |                |
-   |                expected struct `Box`, found struct `Struct`
-   |                help: store this in the heap by calling `Box::new`: `Box::new(Struct)`
+   |                ^^^^^^ expected struct `Box`, found struct `Struct`
    |
    = note: expected struct `Box<(dyn Trait + 'static)>`
               found struct `Struct`
    = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
+help: store this in the heap by calling `Box::new`
+   |
+LL |         return Box::new(Struct);
+   |                ^^^^^^^^^      ^
 
 error[E0308]: mismatched types
   --> $DIR/dyn-trait-return-should-be-impl-trait.rs:36:5
@@ -156,14 +157,15 @@ LL | fn bam() -> Box<dyn Trait> {
    |             -------------- expected `Box<(dyn Trait + 'static)>` because of return type
 ...
 LL |     42
-   |     ^^
-   |     |
-   |     expected struct `Box`, found integer
-   |     help: store this in the heap by calling `Box::new`: `Box::new(42)`
+   |     ^^ expected struct `Box`, found integer
    |
    = note: expected struct `Box<(dyn Trait + 'static)>`
                 found type `{integer}`
    = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
+help: store this in the heap by calling `Box::new`
+   |
+LL |     Box::new(42)
+   |     ^^^^^^^^^  ^
 
 error[E0308]: mismatched types
   --> $DIR/dyn-trait-return-should-be-impl-trait.rs:40:16
@@ -172,14 +174,15 @@ LL | fn baq() -> Box<dyn Trait> {
    |             -------------- expected `Box<(dyn Trait + 'static)>` because of return type
 LL |     if true {
 LL |         return 0;
-   |                ^
-   |                |
-   |                expected struct `Box`, found integer
-   |                help: store this in the heap by calling `Box::new`: `Box::new(0)`
+   |                ^ expected struct `Box`, found integer
    |
    = note: expected struct `Box<(dyn Trait + 'static)>`
                 found type `{integer}`
    = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
+help: store this in the heap by calling `Box::new`
+   |
+LL |         return Box::new(0);
+   |                ^^^^^^^^^ ^
 
 error[E0308]: mismatched types
   --> $DIR/dyn-trait-return-should-be-impl-trait.rs:42:5
@@ -188,14 +191,15 @@ LL | fn baq() -> Box<dyn Trait> {
    |             -------------- expected `Box<(dyn Trait + 'static)>` because of return type
 ...
 LL |     42
-   |     ^^
-   |     |
-   |     expected struct `Box`, found integer
-   |     help: store this in the heap by calling `Box::new`: `Box::new(42)`
+   |     ^^ expected struct `Box`, found integer
    |
    = note: expected struct `Box<(dyn Trait + 'static)>`
                 found type `{integer}`
    = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
+help: store this in the heap by calling `Box::new`
+   |
+LL |     Box::new(42)
+   |     ^^^^^^^^^  ^
 
 error[E0308]: mismatched types
   --> $DIR/dyn-trait-return-should-be-impl-trait.rs:46:9
@@ -204,14 +208,15 @@ LL | fn baz() -> Box<dyn Trait> {
    |             -------------- expected `Box<(dyn Trait + 'static)>` because of return type
 LL |     if true {
 LL |         Struct
-   |         ^^^^^^
-   |         |
-   |         expected struct `Box`, found struct `Struct`
-   |         help: store this in the heap by calling `Box::new`: `Box::new(Struct)`
+   |         ^^^^^^ expected struct `Box`, found struct `Struct`
    |
    = note: expected struct `Box<(dyn Trait + 'static)>`
               found struct `Struct`
    = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
+help: store this in the heap by calling `Box::new`
+   |
+LL |         Box::new(Struct)
+   |         ^^^^^^^^^      ^
 
 error[E0308]: mismatched types
   --> $DIR/dyn-trait-return-should-be-impl-trait.rs:48:9
@@ -220,14 +225,15 @@ LL | fn baz() -> Box<dyn Trait> {
    |             -------------- expected `Box<(dyn Trait + 'static)>` because of return type
 ...
 LL |         42
-   |         ^^
-   |         |
-   |         expected struct `Box`, found integer
-   |         help: store this in the heap by calling `Box::new`: `Box::new(42)`
+   |         ^^ expected struct `Box`, found integer
    |
    = note: expected struct `Box<(dyn Trait + 'static)>`
                 found type `{integer}`
    = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
+help: store this in the heap by calling `Box::new`
+   |
+LL |         Box::new(42)
+   |         ^^^^^^^^^  ^
 
 error[E0308]: mismatched types
   --> $DIR/dyn-trait-return-should-be-impl-trait.rs:53:9
@@ -236,14 +242,15 @@ LL | fn baw() -> Box<dyn Trait> {
    |             -------------- expected `Box<(dyn Trait + 'static)>` because of return type
 LL |     if true {
 LL |         0
-   |         ^
-   |         |
-   |         expected struct `Box`, found integer
-   |         help: store this in the heap by calling `Box::new`: `Box::new(0)`
+   |         ^ expected struct `Box`, found integer
    |
    = note: expected struct `Box<(dyn Trait + 'static)>`
                 found type `{integer}`
    = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
+help: store this in the heap by calling `Box::new`
+   |
+LL |         Box::new(0)
+   |         ^^^^^^^^^ ^
 
 error[E0308]: mismatched types
   --> $DIR/dyn-trait-return-should-be-impl-trait.rs:55:9
@@ -252,14 +259,15 @@ LL | fn baw() -> Box<dyn Trait> {
    |             -------------- expected `Box<(dyn Trait + 'static)>` because of return type
 ...
 LL |         42
-   |         ^^
-   |         |
-   |         expected struct `Box`, found integer
-   |         help: store this in the heap by calling `Box::new`: `Box::new(42)`
+   |         ^^ expected struct `Box`, found integer
    |
    = note: expected struct `Box<(dyn Trait + 'static)>`
                 found type `{integer}`
    = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
+help: store this in the heap by calling `Box::new`
+   |
+LL |         Box::new(42)
+   |         ^^^^^^^^^  ^
 
 error[E0746]: return type cannot have an unboxed trait object
   --> $DIR/dyn-trait-return-should-be-impl-trait.rs:60:13
diff --git a/src/test/ui/infinite/infinite-autoderef.stderr b/src/test/ui/infinite/infinite-autoderef.stderr
index e7d90f00d24..957ab2a7548 100644
--- a/src/test/ui/infinite/infinite-autoderef.stderr
+++ b/src/test/ui/infinite/infinite-autoderef.stderr
@@ -2,10 +2,12 @@ error[E0308]: mismatched types
   --> $DIR/infinite-autoderef.rs:20:13
    |
 LL |         x = box x;
-   |             ^^^^^
-   |             |
-   |             cyclic type of infinite size
-   |             help: try using a conversion method: `(box x).to_string()`
+   |             ^^^^^ cyclic type of infinite size
+   |
+help: try using a conversion method
+   |
+LL |         x = (box x).to_string();
+   |             ^     ^^^^^^^^^^^^^
 
 error[E0055]: reached the recursion limit while auto-dereferencing `Foo`
   --> $DIR/infinite-autoderef.rs:25:5
diff --git a/src/test/ui/issues/issue-22644.stderr b/src/test/ui/issues/issue-22644.stderr
index 1be26949b25..99ff9ac0a0d 100644
--- a/src/test/ui/issues/issue-22644.stderr
+++ b/src/test/ui/issues/issue-22644.stderr
@@ -2,46 +2,66 @@ error: `<` is interpreted as a start of generic arguments for `usize`, not a com
   --> $DIR/issue-22644.rs:8:31
    |
 LL |     println!("{}", a as usize < long_name);
-   |                    ---------- ^ --------- interpreted as generic arguments
-   |                    |          |
-   |                    |          not interpreted as comparison
-   |                    help: try comparing the cast value: `(a as usize)`
+   |                               ^ --------- interpreted as generic arguments
+   |                               |
+   |                               not interpreted as comparison
+   |
+help: try comparing the cast value
+   |
+LL |     println!("{}", (a as usize) < long_name);
+   |                    ^          ^
 
 error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison
   --> $DIR/issue-22644.rs:9:33
    |
 LL |     println!("{}{}", a as usize < long_name, long_name);
-   |                      ---------- ^ -------------------- interpreted as generic arguments
-   |                      |          |
-   |                      |          not interpreted as comparison
-   |                      help: try comparing the cast value: `(a as usize)`
+   |                                 ^ -------------------- interpreted as generic arguments
+   |                                 |
+   |                                 not interpreted as comparison
+   |
+help: try comparing the cast value
+   |
+LL |     println!("{}{}", (a as usize) < long_name, long_name);
+   |                      ^          ^
 
 error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison
   --> $DIR/issue-22644.rs:11:31
    |
 LL |     println!("{}", a as usize < 4);
-   |                    ---------- ^ - interpreted as generic arguments
-   |                    |          |
-   |                    |          not interpreted as comparison
-   |                    help: try comparing the cast value: `(a as usize)`
+   |                               ^ - interpreted as generic arguments
+   |                               |
+   |                               not interpreted as comparison
+   |
+help: try comparing the cast value
+   |
+LL |     println!("{}", (a as usize) < 4);
+   |                    ^          ^
 
 error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison
   --> $DIR/issue-22644.rs:13:31
    |
 LL |     println!("{}{}", a: usize < long_name, long_name);
-   |                      -------- ^ -------------------- interpreted as generic arguments
-   |                      |        |
-   |                      |        not interpreted as comparison
-   |                      help: try comparing the cast value: `(a: usize)`
+   |                               ^ -------------------- interpreted as generic arguments
+   |                               |
+   |                               not interpreted as comparison
+   |
+help: try comparing the cast value
+   |
+LL |     println!("{}{}", (a: usize) < long_name, long_name);
+   |                      ^        ^
 
 error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison
   --> $DIR/issue-22644.rs:15:29
    |
 LL |     println!("{}", a: usize < 4);
-   |                    -------- ^ - interpreted as generic arguments
-   |                    |        |
-   |                    |        not interpreted as comparison
-   |                    help: try comparing the cast value: `(a: usize)`
+   |                             ^ - interpreted as generic arguments
+   |                             |
+   |                             not interpreted as comparison
+   |
+help: try comparing the cast value
+   |
+LL |     println!("{}", (a: usize) < 4);
+   |                    ^        ^
 
 error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison
   --> $DIR/issue-22644.rs:20:20
@@ -80,10 +100,14 @@ error: `<` is interpreted as a start of generic arguments for `usize`, not a shi
   --> $DIR/issue-22644.rs:32:31
    |
 LL |     println!("{}", a as usize << long_name);
-   |                    ---------- ^^ --------- interpreted as generic arguments
-   |                    |          |
-   |                    |          not interpreted as shift
-   |                    help: try shifting the cast value: `(a as usize)`
+   |                               ^^ --------- interpreted as generic arguments
+   |                               |
+   |                               not interpreted as shift
+   |
+help: try shifting the cast value
+   |
+LL |     println!("{}", (a as usize) << long_name);
+   |                    ^          ^
 
 error: expected type, found `4`
   --> $DIR/issue-22644.rs:34:28
diff --git a/src/test/ui/issues/issue-32122-1.stderr b/src/test/ui/issues/issue-32122-1.stderr
index dfbd3223efc..b3362ae44b6 100644
--- a/src/test/ui/issues/issue-32122-1.stderr
+++ b/src/test/ui/issues/issue-32122-1.stderr
@@ -2,14 +2,16 @@ error[E0308]: mismatched types
   --> $DIR/issue-32122-1.rs:16:24
    |
 LL |     let _: *const u8 = &a;
-   |            ---------   ^^
-   |            |           |
-   |            |           expected `u8`, found struct `Foo`
-   |            |           help: consider dereferencing: `&*a`
+   |            ---------   ^^ expected `u8`, found struct `Foo`
+   |            |
    |            expected due to this
    |
    = note: expected raw pointer `*const u8`
                 found reference `&Foo`
+help: consider dereferencing
+   |
+LL |     let _: *const u8 = &*a;
+   |                         ^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-32122-2.stderr b/src/test/ui/issues/issue-32122-2.stderr
index 2e199e2a19f..bcf71638127 100644
--- a/src/test/ui/issues/issue-32122-2.stderr
+++ b/src/test/ui/issues/issue-32122-2.stderr
@@ -2,14 +2,16 @@ error[E0308]: mismatched types
   --> $DIR/issue-32122-2.rs:27:24
    |
 LL |     let _: *const u8 = &a;
-   |            ---------   ^^
-   |            |           |
-   |            |           expected `u8`, found struct `Emm`
-   |            |           help: consider dereferencing: `&***a`
+   |            ---------   ^^ expected `u8`, found struct `Emm`
+   |            |
    |            expected due to this
    |
    = note: expected raw pointer `*const u8`
                 found reference `&Emm`
+help: consider dereferencing
+   |
+LL |     let _: *const u8 = &***a;
+   |                         ^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-42954.stderr b/src/test/ui/issues/issue-42954.stderr
index 8227f8df1e0..4f41c95323a 100644
--- a/src/test/ui/issues/issue-42954.stderr
+++ b/src/test/ui/issues/issue-42954.stderr
@@ -2,15 +2,18 @@ error: `<` is interpreted as a start of generic arguments for `u32`, not a compa
   --> $DIR/issue-42954.rs:7:19
    |
 LL |         $i as u32 < 0
-   |         --------- ^ - interpreted as generic arguments
-   |         |         |
-   |         |         not interpreted as comparison
-   |         help: try comparing the cast value: `($i as u32)`
+   |                   ^ - interpreted as generic arguments
+   |                   |
+   |                   not interpreted as comparison
 ...
 LL |     is_plainly_printable!(c);
    |     ------------------------- in this macro invocation
    |
    = note: this error originates in the macro `is_plainly_printable` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: try comparing the cast value
+   |
+LL |         ($i as u32) < 0
+   |         ^         ^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-50687-ice-on-borrow.stderr b/src/test/ui/issues/issue-50687-ice-on-borrow.stderr
index f6adfc87dad..a9404c1c46a 100644
--- a/src/test/ui/issues/issue-50687-ice-on-borrow.stderr
+++ b/src/test/ui/issues/issue-50687-ice-on-borrow.stderr
@@ -2,14 +2,16 @@ error[E0308]: mismatched types
   --> $DIR/issue-50687-ice-on-borrow.rs:40:17
    |
 LL |     let _: () = Borrow::borrow(&owned);
-   |            --   ^^^^^^^^^^^^^^^^^^^^^^
-   |            |    |
-   |            |    expected `()`, found reference
-   |            |    help: consider dereferencing the borrow: `*Borrow::borrow(&owned)`
+   |            --   ^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found reference
+   |            |
    |            expected due to this
    |
    = note: expected unit type `()`
               found reference `&_`
+help: consider dereferencing the borrow
+   |
+LL |     let _: () = *Borrow::borrow(&owned);
+   |                 ^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-71676-1.stderr b/src/test/ui/issues/issue-71676-1.stderr
index bbabc2202dc..14913c93bf7 100644
--- a/src/test/ui/issues/issue-71676-1.stderr
+++ b/src/test/ui/issues/issue-71676-1.stderr
@@ -2,53 +2,61 @@ error[E0308]: mismatched types
   --> $DIR/issue-71676-1.rs:43:24
    |
 LL |     let _: *const u8 = &a;
-   |            ---------   ^^
-   |            |           |
-   |            |           expected `u8`, found struct `Emm`
-   |            |           help: consider dereferencing: `&***a`
+   |            ---------   ^^ expected `u8`, found struct `Emm`
+   |            |
    |            expected due to this
    |
    = note: expected raw pointer `*const u8`
                 found reference `&Emm`
+help: consider dereferencing
+   |
+LL |     let _: *const u8 = &***a;
+   |                         ^^^
 
 error[E0308]: mismatched types
   --> $DIR/issue-71676-1.rs:46:22
    |
 LL |     let _: *mut u8 = &a;
-   |            -------   ^^
-   |            |         |
-   |            |         types differ in mutability
-   |            |         help: consider dereferencing: `&mut ***a`
+   |            -------   ^^ types differ in mutability
+   |            |
    |            expected due to this
    |
    = note: expected raw pointer `*mut u8`
                 found reference `&Emm`
+help: consider dereferencing
+   |
+LL |     let _: *mut u8 = &mut ***a;
+   |                       ^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/issue-71676-1.rs:49:24
    |
 LL |     let _: *const u8 = &mut a;
-   |            ---------   ^^^^^^
-   |            |           |
-   |            |           expected `u8`, found struct `Emm`
-   |            |           help: consider dereferencing: `&***a`
+   |            ---------   ^^^^^^ expected `u8`, found struct `Emm`
+   |            |
    |            expected due to this
    |
    = note:    expected raw pointer `*const u8`
            found mutable reference `&mut Emm`
+help: consider dereferencing
+   |
+LL |     let _: *const u8 = &***a;
+   |                         ^^^
 
 error[E0308]: mismatched types
   --> $DIR/issue-71676-1.rs:52:22
    |
 LL |     let _: *mut u8 = &mut a;
-   |            -------   ^^^^^^
-   |            |         |
-   |            |         expected `u8`, found struct `Emm`
-   |            |         help: consider dereferencing: `&mut ***a`
+   |            -------   ^^^^^^ expected `u8`, found struct `Emm`
+   |            |
    |            expected due to this
    |
    = note:    expected raw pointer `*mut u8`
            found mutable reference `&mut Emm`
+help: consider dereferencing
+   |
+LL |     let _: *mut u8 = &mut ***a;
+   |                           ^^^
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/issues/issue-71676-2.stderr b/src/test/ui/issues/issue-71676-2.stderr
index ebdd345809a..0544deda4ae 100644
--- a/src/test/ui/issues/issue-71676-2.stderr
+++ b/src/test/ui/issues/issue-71676-2.stderr
@@ -2,14 +2,16 @@ error[E0308]: mismatched types
   --> $DIR/issue-71676-2.rs:41:22
    |
 LL |     let _: *mut u8 = &a;
-   |            -------   ^^
-   |            |         |
-   |            |         types differ in mutability
-   |            |         help: consider dereferencing: `&mut ***a`
+   |            -------   ^^ types differ in mutability
+   |            |
    |            expected due to this
    |
    = note: expected raw pointer `*mut u8`
                 found reference `&Emm`
+help: consider dereferencing
+   |
+LL |     let _: *mut u8 = &mut ***a;
+   |                       ^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-77218.stderr b/src/test/ui/issues/issue-77218.stderr
index 4f6fbaa2265..f945f7f38f9 100644
--- a/src/test/ui/issues/issue-77218.stderr
+++ b/src/test/ui/issues/issue-77218.stderr
@@ -21,10 +21,12 @@ error[E0308]: mismatched types
   --> $DIR/issue-77218.rs:3:16
    |
 LL |     while Some(0) = value.get(0) {
+   |                ^ expected integer, found `&u8`
+   |
+help: consider dereferencing the borrow
+   |
+LL |     while Some(*0) = value.get(0) {
    |                ^
-   |                |
-   |                expected integer, found `&u8`
-   |                help: consider dereferencing the borrow: `*0`
 
 error[E0308]: mismatched types
   --> $DIR/issue-77218.rs:3:11
diff --git a/src/test/ui/json-bom-plus-crlf-multifile.stderr b/src/test/ui/json-bom-plus-crlf-multifile.stderr
index da8849a8284..02f3bc687cb 100644
--- a/src/test/ui/json-bom-plus-crlf-multifile.stderr
+++ b/src/test/ui/json-bom-plus-crlf-multifile.stderr
@@ -24,7 +24,7 @@ This error occurs when an expression was used in a place where the compiler
 expected an expression of a different type. It can occur in several cases, the
 most common being when calling a function and passing an argument which has a
 different type than the matching type in the function declaration.
-"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":621,"byte_end":622,"line_start":17,"line_end":17,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1;  // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":612,"byte_end":618,"line_start":17,"line_end":17,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String = 1;  // Error in the middle of line.","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":621,"byte_end":622,"line_start":17,"line_end":17,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1;  // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:17:22: error[E0308]: mismatched types
+"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":621,"byte_end":622,"line_start":17,"line_end":17,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1;  // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":612,"byte_end":618,"line_start":17,"line_end":17,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String = 1;  // Error in the middle of line.","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":622,"byte_end":622,"line_start":17,"line_end":17,"column_start":23,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1;  // Error in the middle of line.","highlight_start":23,"highlight_end":23}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:17:22: error[E0308]: mismatched types
 "}
 {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
 
@@ -52,7 +52,7 @@ This error occurs when an expression was used in a place where the compiler
 expected an expression of a different type. It can occur in several cases, the
 most common being when calling a function and passing an argument which has a
 different type than the matching type in the function declaration.
-"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":681,"byte_end":682,"line_start":19,"line_end":19,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":672,"byte_end":678,"line_start":19,"line_end":19,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String = 1","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":681,"byte_end":682,"line_start":19,"line_end":19,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1","highlight_start":22,"highlight_end":23}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:19:22: error[E0308]: mismatched types
+"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":681,"byte_end":682,"line_start":19,"line_end":19,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":672,"byte_end":678,"line_start":19,"line_end":19,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String = 1","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":682,"byte_end":682,"line_start":19,"line_end":19,"column_start":23,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1","highlight_start":23,"highlight_end":23}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:19:22: error[E0308]: mismatched types
 "}
 {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
 
@@ -80,7 +80,7 @@ This error occurs when an expression was used in a place where the compiler
 expected an expression of a different type. It can occur in several cases, the
 most common being when calling a function and passing an argument which has a
 different type than the matching type in the function declaration.
-"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":745,"byte_end":746,"line_start":23,"line_end":23,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1;  // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":735,"byte_end":741,"line_start":22,"line_end":22,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String =","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":745,"byte_end":746,"line_start":23,"line_end":23,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1;  // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:23:1: error[E0308]: mismatched types
+"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":745,"byte_end":746,"line_start":23,"line_end":23,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1;  // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":735,"byte_end":741,"line_start":22,"line_end":22,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String =","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":746,"byte_end":746,"line_start":23,"line_end":23,"column_start":2,"column_end":2,"is_primary":true,"text":[{"text":"1;  // Error after the newline.","highlight_start":2,"highlight_end":2}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:23:1: error[E0308]: mismatched types
 "}
 {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
 
diff --git a/src/test/ui/json-bom-plus-crlf.stderr b/src/test/ui/json-bom-plus-crlf.stderr
index 811206f9aa0..df6bd7286a6 100644
--- a/src/test/ui/json-bom-plus-crlf.stderr
+++ b/src/test/ui/json-bom-plus-crlf.stderr
@@ -24,7 +24,7 @@ This error occurs when an expression was used in a place where the compiler
 expected an expression of a different type. It can occur in several cases, the
 most common being when calling a function and passing an argument which has a
 different type than the matching type in the function declaration.
-"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":606,"byte_end":607,"line_start":16,"line_end":16,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1;  // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":597,"byte_end":603,"line_start":16,"line_end":16,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String = 1;  // Error in the middle of line.","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":606,"byte_end":607,"line_start":16,"line_end":16,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1;  // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:16:22: error[E0308]: mismatched types
+"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":606,"byte_end":607,"line_start":16,"line_end":16,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1;  // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":597,"byte_end":603,"line_start":16,"line_end":16,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String = 1;  // Error in the middle of line.","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":607,"byte_end":607,"line_start":16,"line_end":16,"column_start":23,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1;  // Error in the middle of line.","highlight_start":23,"highlight_end":23}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:16:22: error[E0308]: mismatched types
 "}
 {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
 
@@ -52,7 +52,7 @@ This error occurs when an expression was used in a place where the compiler
 expected an expression of a different type. It can occur in several cases, the
 most common being when calling a function and passing an argument which has a
 different type than the matching type in the function declaration.
-"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":666,"byte_end":667,"line_start":18,"line_end":18,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":657,"byte_end":663,"line_start":18,"line_end":18,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String = 1","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":666,"byte_end":667,"line_start":18,"line_end":18,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1","highlight_start":22,"highlight_end":23}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:18:22: error[E0308]: mismatched types
+"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":666,"byte_end":667,"line_start":18,"line_end":18,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":657,"byte_end":663,"line_start":18,"line_end":18,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String = 1","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":667,"byte_end":667,"line_start":18,"line_end":18,"column_start":23,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1","highlight_start":23,"highlight_end":23}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:18:22: error[E0308]: mismatched types
 "}
 {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
 
@@ -80,7 +80,7 @@ This error occurs when an expression was used in a place where the compiler
 expected an expression of a different type. It can occur in several cases, the
 most common being when calling a function and passing an argument which has a
 different type than the matching type in the function declaration.
-"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":730,"byte_end":731,"line_start":22,"line_end":22,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1;  // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":720,"byte_end":726,"line_start":21,"line_end":21,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String =","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":730,"byte_end":731,"line_start":22,"line_end":22,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1;  // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:22:1: error[E0308]: mismatched types
+"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":730,"byte_end":731,"line_start":22,"line_end":22,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1;  // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":720,"byte_end":726,"line_start":21,"line_end":21,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String =","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":731,"byte_end":731,"line_start":22,"line_end":22,"column_start":2,"column_end":2,"is_primary":true,"text":[{"text":"1;  // Error after the newline.","highlight_start":2,"highlight_end":2}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:22:1: error[E0308]: mismatched types
 "}
 {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
 
diff --git a/src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.stderr b/src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.stderr
index 34470119112..1fef8fc69e2 100644
--- a/src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.stderr
+++ b/src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.stderr
@@ -14,7 +14,7 @@ LL |     [0].iter().flat_map(|a| [0].iter().map(|_| &a));
 help: to force the closure to take ownership of `a` (and any other referenced variables), use the `move` keyword
    |
 LL |     [0].iter().flat_map(|a| [0].iter().map(move |_| &a));
-   |                                            ^^^^^^^^
+   |                                            ^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/mismatched_types/abridged.stderr b/src/test/ui/mismatched_types/abridged.stderr
index 61994e5bfee..7697a375fd8 100644
--- a/src/test/ui/mismatched_types/abridged.stderr
+++ b/src/test/ui/mismatched_types/abridged.stderr
@@ -78,10 +78,12 @@ error[E0308]: mismatched types
 LL | fn f() -> String {
    |           ------ expected `String` because of return type
 LL |     1+2
-   |     ^^^
-   |     |
-   |     expected struct `String`, found integer
-   |     help: try using a conversion method: `(1+2).to_string()`
+   |     ^^^ expected struct `String`, found integer
+   |
+help: try using a conversion method
+   |
+LL |     (1+2).to_string()
+   |     ^   ^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/abridged.rs:59:5
@@ -89,10 +91,12 @@ error[E0308]: mismatched types
 LL | fn g() -> String {
    |           ------ expected `String` because of return type
 LL |     -2
-   |     ^^
-   |     |
-   |     expected struct `String`, found integer
-   |     help: try using a conversion method: `(-2).to_string()`
+   |     ^^ expected struct `String`, found integer
+   |
+help: try using a conversion method
+   |
+LL |     (-2).to_string()
+   |     ^  ^^^^^^^^^^^^^
 
 error: aborting due to 8 previous errors
 
diff --git a/src/test/ui/never_type/issue-52443.stderr b/src/test/ui/never_type/issue-52443.stderr
index 1683841e9d7..dcee3986665 100644
--- a/src/test/ui/never_type/issue-52443.stderr
+++ b/src/test/ui/never_type/issue-52443.stderr
@@ -16,13 +16,14 @@ error[E0308]: mismatched types
   --> $DIR/issue-52443.rs:2:10
    |
 LL |     [(); & { loop { continue } } ];
-   |          ^^^^^^^^^^^^^^^^^^^^^^^
-   |          |
-   |          expected `usize`, found reference
-   |          help: consider removing the borrow: `{ loop { continue } }`
+   |          ^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found reference
    |
    = note:   expected type `usize`
            found reference `&_`
+help: consider removing the borrow
+   |
+LL |     [(); { loop { continue } } ];
+   |         --
 
 error[E0308]: mismatched types
   --> $DIR/issue-52443.rs:4:17
diff --git a/src/test/ui/occurs-check-2.stderr b/src/test/ui/occurs-check-2.stderr
index 7f93697c6f7..b2c8775e78c 100644
--- a/src/test/ui/occurs-check-2.stderr
+++ b/src/test/ui/occurs-check-2.stderr
@@ -2,10 +2,12 @@ error[E0308]: mismatched types
   --> $DIR/occurs-check-2.rs:7:9
    |
 LL |     f = box g;
-   |         ^^^^^
-   |         |
-   |         cyclic type of infinite size
-   |         help: try using a conversion method: `(box g).to_string()`
+   |         ^^^^^ cyclic type of infinite size
+   |
+help: try using a conversion method
+   |
+LL |     f = (box g).to_string();
+   |         ^     ^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/occurs-check.stderr b/src/test/ui/occurs-check.stderr
index 01e2b1f7749..a657106ad91 100644
--- a/src/test/ui/occurs-check.stderr
+++ b/src/test/ui/occurs-check.stderr
@@ -2,10 +2,12 @@ error[E0308]: mismatched types
   --> $DIR/occurs-check.rs:5:9
    |
 LL |     f = box f;
-   |         ^^^^^
-   |         |
-   |         cyclic type of infinite size
-   |         help: try using a conversion method: `(box f).to_string()`
+   |         ^^^^^ cyclic type of infinite size
+   |
+help: try using a conversion method
+   |
+LL |     f = (box f).to_string();
+   |         ^     ^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/expr-as-stmt-2.stderr b/src/test/ui/parser/expr-as-stmt-2.stderr
index 2a701274857..affcb6ed224 100644
--- a/src/test/ui/parser/expr-as-stmt-2.stderr
+++ b/src/test/ui/parser/expr-as-stmt-2.stderr
@@ -31,12 +31,15 @@ error[E0308]: mismatched types
    |
 LL |   fn foo(a: Option<u32>, b: Option<u32>) -> bool {
    |                                             ---- expected `bool` because of return type
-LL |       if let Some(x) = a { true } else { false }
-   |       ------------------------------------------ help: parentheses are required to parse this as an expression: `(if let Some(x) = a { true } else { false })`
 ...
 LL | /     &&
 LL | |     if let Some(y) = a { true } else { false }
    | |______________________________________________^ expected `bool`, found `&&bool`
+   |
+help: parentheses are required to parse this as an expression
+   |
+LL |     (if let Some(x) = a { true } else { false })
+   |     ^                                          ^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/parser/expr-as-stmt.stderr b/src/test/ui/parser/expr-as-stmt.stderr
index 067b7edc770..2bb320e7321 100644
--- a/src/test/ui/parser/expr-as-stmt.stderr
+++ b/src/test/ui/parser/expr-as-stmt.stderr
@@ -2,25 +2,34 @@ error: expected expression, found `+`
   --> $DIR/expr-as-stmt.rs:8:9
    |
 LL |     {2} + {2}
-   |     --- ^ expected expression
-   |     |
-   |     help: parentheses are required to parse this as an expression: `({2})`
+   |         ^ expected expression
+   |
+help: parentheses are required to parse this as an expression
+   |
+LL |     ({2}) + {2}
+   |     ^   ^
 
 error: expected expression, found `+`
   --> $DIR/expr-as-stmt.rs:13:9
    |
 LL |     {2} + 2
-   |     --- ^ expected expression
-   |     |
-   |     help: parentheses are required to parse this as an expression: `({2})`
+   |         ^ expected expression
+   |
+help: parentheses are required to parse this as an expression
+   |
+LL |     ({2}) + 2
+   |     ^   ^
 
 error: expected expression, found `+`
   --> $DIR/expr-as-stmt.rs:19:12
    |
 LL |     { 42 } + foo;
-   |     ------ ^ expected expression
-   |     |
-   |     help: parentheses are required to parse this as an expression: `({ 42 })`
+   |            ^ expected expression
+   |
+help: parentheses are required to parse this as an expression
+   |
+LL |     ({ 42 }) + foo;
+   |     ^      ^
 
 error: expected expression, found `>`
   --> $DIR/expr-as-stmt.rs:32:7
@@ -83,9 +92,12 @@ error[E0614]: type `{integer}` cannot be dereferenced
   --> $DIR/expr-as-stmt.rs:25:11
    |
 LL |     { 3 } * 3
-   |     ----- ^^^
-   |     |
-   |     help: parentheses are required to parse this as an expression: `({ 3 })`
+   |           ^^^
+   |
+help: parentheses are required to parse this as an expression
+   |
+LL |     ({ 3 }) * 3
+   |     ^     ^
 
 error: aborting due to 9 previous errors
 
diff --git a/src/test/ui/regions/region-borrow-params-issue-29793-big.stderr b/src/test/ui/regions/region-borrow-params-issue-29793-big.stderr
index 328e602ca76..4bd16c71137 100644
--- a/src/test/ui/regions/region-borrow-params-issue-29793-big.stderr
+++ b/src/test/ui/regions/region-borrow-params-issue-29793-big.stderr
@@ -14,7 +14,7 @@ LL |         WrapB::new().set(|t: bool| if t { x } else { y }) // (separate erro
 help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |         WrapB::new().set(move |t: bool| if t { x } else { y }) // (separate errors for `x` vs `y`)
-   |                          ^^^^^^^^^^^^^^
+   |                          ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-big.rs:67:26
@@ -32,7 +32,7 @@ LL |         WrapB::new().set(|t: bool| if t { x } else { y }) // (separate erro
 help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword
    |
 LL |         WrapB::new().set(move |t: bool| if t { x } else { y }) // (separate errors for `x` vs `y`)
-   |                          ^^^^^^^^^^^^^^
+   |                          ^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/regions/region-borrow-params-issue-29793-small.stderr b/src/test/ui/regions/region-borrow-params-issue-29793-small.stderr
index 18610b7cffb..f70e4ea9fbc 100644
--- a/src/test/ui/regions/region-borrow-params-issue-29793-small.stderr
+++ b/src/test/ui/regions/region-borrow-params-issue-29793-small.stderr
@@ -14,7 +14,7 @@ LL |         return f;
 help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |         let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                 ^^^^^^^^^^^^^^
+   |                 ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:9:17
@@ -32,7 +32,7 @@ LL |         return f;
 help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword
    |
 LL |         let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                 ^^^^^^^^^^^^^^
+   |                 ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:24:17
@@ -50,7 +50,7 @@ LL |         f
 help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |         let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                 ^^^^^^^^^^^^^^
+   |                 ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:24:17
@@ -68,7 +68,7 @@ LL |         f
 help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword
    |
 LL |         let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                 ^^^^^^^^^^^^^^
+   |                 ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:55:17
@@ -86,7 +86,7 @@ LL |         return Box::new(f);
 help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |         let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                 ^^^^^^^^^^^^^^
+   |                 ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:55:17
@@ -104,7 +104,7 @@ LL |         return Box::new(f);
 help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword
    |
 LL |         let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                 ^^^^^^^^^^^^^^
+   |                 ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:66:17
@@ -122,7 +122,7 @@ LL |         Box::new(f)
 help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |         let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                 ^^^^^^^^^^^^^^
+   |                 ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:66:17
@@ -140,7 +140,7 @@ LL |         Box::new(f)
 help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword
    |
 LL |         let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                 ^^^^^^^^^^^^^^
+   |                 ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:90:21
@@ -158,7 +158,7 @@ LL |             return Box::new(f);
 help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |             let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                     ^^^^^^^^^^^^^^
+   |                     ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:90:21
@@ -176,7 +176,7 @@ LL |             return Box::new(f);
 help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword
    |
 LL |             let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                     ^^^^^^^^^^^^^^
+   |                     ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:104:21
@@ -194,7 +194,7 @@ LL |             Box::new(f)
 help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |             let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                     ^^^^^^^^^^^^^^
+   |                     ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:104:21
@@ -212,7 +212,7 @@ LL |             Box::new(f)
 help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword
    |
 LL |             let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                     ^^^^^^^^^^^^^^
+   |                     ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:132:21
@@ -230,7 +230,7 @@ LL |             return Box::new(f);
 help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |             let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                     ^^^^^^^^^^^^^^
+   |                     ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:132:21
@@ -248,7 +248,7 @@ LL |             return Box::new(f);
 help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword
    |
 LL |             let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                     ^^^^^^^^^^^^^^
+   |                     ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:147:21
@@ -266,7 +266,7 @@ LL |             Box::new(f)
 help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |             let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                     ^^^^^^^^^^^^^^
+   |                     ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:147:21
@@ -284,7 +284,7 @@ LL |             Box::new(f)
 help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword
    |
 LL |             let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                     ^^^^^^^^^^^^^^
+   |                     ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:175:21
@@ -302,7 +302,7 @@ LL |             return Box::new(f);
 help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |             let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                     ^^^^^^^^^^^^^^
+   |                     ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:175:21
@@ -320,7 +320,7 @@ LL |             return Box::new(f);
 help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword
    |
 LL |             let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                     ^^^^^^^^^^^^^^
+   |                     ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:189:21
@@ -338,7 +338,7 @@ LL |             Box::new(f)
 help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |             let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                     ^^^^^^^^^^^^^^
+   |                     ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:189:21
@@ -356,7 +356,7 @@ LL |             Box::new(f)
 help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword
    |
 LL |             let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                     ^^^^^^^^^^^^^^
+   |                     ^^^^
 
 error: aborting due to 20 previous errors
 
diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
index 4950b654141..23eabfa3b3e 100644
--- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
+++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
@@ -478,10 +478,12 @@ error[E0308]: mismatched types
   --> $DIR/disallowed-positions.rs:32:8
    |
 LL |     if &let 0 = 0 {}
-   |        ^^^^^^^^^^
-   |        |
-   |        expected `bool`, found `&bool`
-   |        help: consider removing the borrow: `let 0 = 0`
+   |        ^^^^^^^^^^ expected `bool`, found `&bool`
+   |
+help: consider removing the borrow
+   |
+LL |     if let 0 = 0 {}
+   |       --
 
 error[E0614]: type `bool` cannot be dereferenced
   --> $DIR/disallowed-positions.rs:36:8
@@ -678,10 +680,12 @@ error[E0308]: mismatched types
   --> $DIR/disallowed-positions.rs:96:11
    |
 LL |     while &let 0 = 0 {}
-   |           ^^^^^^^^^^
-   |           |
-   |           expected `bool`, found `&bool`
-   |           help: consider removing the borrow: `let 0 = 0`
+   |           ^^^^^^^^^^ expected `bool`, found `&bool`
+   |
+help: consider removing the borrow
+   |
+LL |     while let 0 = 0 {}
+   |          --
 
 error[E0614]: type `bool` cannot be dereferenced
   --> $DIR/disallowed-positions.rs:100:11
diff --git a/src/test/ui/span/coerce-suggestions.stderr b/src/test/ui/span/coerce-suggestions.stderr
index 0e40ca67351..2595cd91dc1 100644
--- a/src/test/ui/span/coerce-suggestions.stderr
+++ b/src/test/ui/span/coerce-suggestions.stderr
@@ -38,10 +38,12 @@ error[E0308]: mismatched types
   --> $DIR/coerce-suggestions.rs:17:9
    |
 LL |     f = box f;
-   |         ^^^^^
-   |         |
-   |         cyclic type of infinite size
-   |         help: try using a conversion method: `(box f).to_string()`
+   |         ^^^^^ cyclic type of infinite size
+   |
+help: try using a conversion method
+   |
+LL |     f = (box f).to_string();
+   |         ^     ^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/coerce-suggestions.rs:21:9
diff --git a/src/test/ui/static/bad-const-type.stderr b/src/test/ui/static/bad-const-type.stderr
index a9c84b4b41c..dcc1ee07cbd 100644
--- a/src/test/ui/static/bad-const-type.stderr
+++ b/src/test/ui/static/bad-const-type.stderr
@@ -2,10 +2,9 @@ error[E0308]: mismatched types
   --> $DIR/bad-const-type.rs:1:20
    |
 LL | static i: String = 10;
-   |                    ^^
+   |                    ^^- help: try using a conversion method: `.to_string()`
    |                    |
    |                    expected struct `String`, found integer
-   |                    help: try using a conversion method: `10.to_string()`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/str/str-lit-type-mismatch.stderr b/src/test/ui/str/str-lit-type-mismatch.stderr
index 64ddfcc9b47..e8e2c4e24f5 100644
--- a/src/test/ui/str/str-lit-type-mismatch.stderr
+++ b/src/test/ui/str/str-lit-type-mismatch.stderr
@@ -2,40 +2,46 @@ error[E0308]: mismatched types
   --> $DIR/str-lit-type-mismatch.rs:2:20
    |
 LL |     let x: &[u8] = "foo";
-   |            -----   ^^^^^
-   |            |       |
-   |            |       expected slice `[u8]`, found `str`
-   |            |       help: consider adding a leading `b`: `b"foo"`
+   |            -----   ^^^^^ expected slice `[u8]`, found `str`
+   |            |
    |            expected due to this
    |
    = note: expected reference `&[u8]`
               found reference `&'static str`
+help: consider adding a leading `b`
+   |
+LL |     let x: &[u8] = b"foo";
+   |                    ^
 
 error[E0308]: mismatched types
   --> $DIR/str-lit-type-mismatch.rs:3:23
    |
 LL |     let y: &[u8; 4] = "baaa";
-   |            --------   ^^^^^^
-   |            |          |
-   |            |          expected array `[u8; 4]`, found `str`
-   |            |          help: consider adding a leading `b`: `b"baaa"`
+   |            --------   ^^^^^^ expected array `[u8; 4]`, found `str`
+   |            |
    |            expected due to this
    |
    = note: expected reference `&[u8; 4]`
               found reference `&'static str`
+help: consider adding a leading `b`
+   |
+LL |     let y: &[u8; 4] = b"baaa";
+   |                       ^
 
 error[E0308]: mismatched types
   --> $DIR/str-lit-type-mismatch.rs:4:19
    |
 LL |     let z: &str = b"foo";
-   |            ----   ^^^^^^
-   |            |      |
-   |            |      expected `str`, found array `[u8; 3]`
-   |            |      help: consider removing the leading `b`: `"foo"`
+   |            ----   ^^^^^^ expected `str`, found array `[u8; 3]`
+   |            |
    |            expected due to this
    |
    = note: expected reference `&str`
               found reference `&'static [u8; 3]`
+help: consider removing the leading `b`
+   |
+LL |     let z: &str = "foo";
+   |                  --
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
index d5d51324e63..119599c22a6 100644
--- a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
+++ b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
@@ -5,13 +5,14 @@ LL | fn foo<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static,
    |        - this type parameter                            ----------------------- expected `Pin<Box<(dyn Future<Output = i32> + Send + 'static)>>` because of return type
 LL |     // We could instead use an `async` block, but this way we have no std spans.
 LL |     x
-   |     ^
-   |     |
-   |     expected struct `Pin`, found type parameter `F`
-   |     help: you need to pin and box this expression: `Box::pin(x)`
+   |     ^ expected struct `Pin`, found type parameter `F`
    |
    = note:      expected struct `Pin<Box<(dyn Future<Output = i32> + Send + 'static)>>`
            found type parameter `F`
+help: you need to pin and box this expression
+   |
+LL |     Box::pin(x)
+   |     ^^^^^^^^^ ^
 
 error[E0308]: mismatched types
   --> $DIR/expected-boxed-future-isnt-pinned.rs:18:5
@@ -31,14 +32,15 @@ error[E0308]: mismatched types
 LL | fn baz<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
    |        - this type parameter
 LL |     Pin::new(x)
-   |              ^
-   |              |
-   |              expected struct `Box`, found type parameter `F`
-   |              help: store this in the heap by calling `Box::new`: `Box::new(x)`
+   |              ^ expected struct `Box`, found type parameter `F`
    |
    = note:      expected struct `Box<dyn Future<Output = i32> + Send>`
            found type parameter `F`
    = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
+help: store this in the heap by calling `Box::new`
+   |
+LL |     Pin::new(Box::new(x))
+   |              ^^^^^^^^^ ^
 
 error[E0277]: `dyn Future<Output = i32> + Send` cannot be unpinned
   --> $DIR/expected-boxed-future-isnt-pinned.rs:22:5
diff --git a/src/test/ui/suggestions/format-borrow.stderr b/src/test/ui/suggestions/format-borrow.stderr
index 0881b024712..15cb845a06d 100644
--- a/src/test/ui/suggestions/format-borrow.stderr
+++ b/src/test/ui/suggestions/format-borrow.stderr
@@ -2,41 +2,53 @@ error[E0308]: mismatched types
   --> $DIR/format-borrow.rs:2:21
    |
 LL |     let a: String = &String::from("a");
-   |            ------   ^^^^^^^^^^^^^^^^^^
-   |            |        |
-   |            |        expected struct `String`, found `&String`
-   |            |        help: consider removing the borrow: `String::from("a")`
+   |            ------   ^^^^^^^^^^^^^^^^^^ expected struct `String`, found `&String`
+   |            |
    |            expected due to this
+   |
+help: consider removing the borrow
+   |
+LL |     let a: String = String::from("a");
+   |                    --
 
 error[E0308]: mismatched types
   --> $DIR/format-borrow.rs:4:21
    |
 LL |     let b: String = &format!("b");
-   |            ------   ^^^^^^^^^^^^^
-   |            |        |
-   |            |        expected struct `String`, found `&String`
-   |            |        help: consider removing the borrow: `format!("b")`
+   |            ------   ^^^^^^^^^^^^^ expected struct `String`, found `&String`
+   |            |
    |            expected due to this
+   |
+help: consider removing the borrow
+   |
+LL |     let b: String = format!("b");
+   |                    --
 
 error[E0308]: mismatched types
   --> $DIR/format-borrow.rs:6:21
    |
 LL |     let c: String = &mut format!("c");
-   |            ------   ^^^^^^^^^^^^^^^^^
-   |            |        |
-   |            |        expected struct `String`, found `&mut String`
-   |            |        help: consider removing the borrow: `format!("c")`
+   |            ------   ^^^^^^^^^^^^^^^^^ expected struct `String`, found `&mut String`
+   |            |
    |            expected due to this
+   |
+help: consider removing the borrow
+   |
+LL |     let c: String = format!("c");
+   |                    --
 
 error[E0308]: mismatched types
   --> $DIR/format-borrow.rs:8:21
    |
 LL |     let d: String = &mut (format!("d"));
-   |            ------   ^^^^^^^^^^^^^^^^^^^
-   |            |        |
-   |            |        expected struct `String`, found `&mut String`
-   |            |        help: consider removing the borrow: `format!("d")`
+   |            ------   ^^^^^^^^^^^^^^^^^^^ expected struct `String`, found `&mut String`
+   |            |
    |            expected due to this
+   |
+help: consider removing the borrow
+   |
+LL |     let d: String = format!("d"));
+   |                    --
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/suggestions/issue-52820.stderr b/src/test/ui/suggestions/issue-52820.stderr
index ece784de3e2..62c04584d3c 100644
--- a/src/test/ui/suggestions/issue-52820.stderr
+++ b/src/test/ui/suggestions/issue-52820.stderr
@@ -2,10 +2,12 @@ error[E0308]: mismatched types
   --> $DIR/issue-52820.rs:9:9
    |
 LL |         guts,
-   |         ^^^^
-   |         |
-   |         expected struct `String`, found `&str`
-   |         help: try using a conversion method: `guts: guts.to_string()`
+   |         ^^^^ expected struct `String`, found `&str`
+   |
+help: try using a conversion method
+   |
+LL |         guts: guts.to_string(),
+   |         ^^^^^     ^^^^^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/issue-52820.rs:10:17
diff --git a/src/test/ui/suggestions/issue-59819.stderr b/src/test/ui/suggestions/issue-59819.stderr
index 43e0016ee20..ac9b6d975f4 100644
--- a/src/test/ui/suggestions/issue-59819.stderr
+++ b/src/test/ui/suggestions/issue-59819.stderr
@@ -2,30 +2,35 @@ error[E0308]: mismatched types
   --> $DIR/issue-59819.rs:28:18
    |
 LL |     let y: i32 = x;
-   |            ---   ^
-   |            |     |
-   |            |     expected `i32`, found struct `Foo`
-   |            |     help: consider dereferencing the type: `*x`
+   |            ---   ^ expected `i32`, found struct `Foo`
+   |            |
    |            expected due to this
+   |
+help: consider dereferencing the type
+   |
+LL |     let y: i32 = *x;
+   |                  ^
 
 error[E0308]: mismatched types
   --> $DIR/issue-59819.rs:30:18
    |
 LL |     let b: i32 = a;
-   |            ---   ^
-   |            |     |
-   |            |     expected `i32`, found `&{integer}`
-   |            |     help: consider dereferencing the borrow: `*a`
+   |            ---   ^ expected `i32`, found `&{integer}`
+   |            |
    |            expected due to this
+   |
+help: consider dereferencing the borrow
+   |
+LL |     let b: i32 = *a;
+   |                  ^
 
 error[E0308]: mismatched types
   --> $DIR/issue-59819.rs:34:21
    |
 LL |     let g: String = f;
-   |            ------   ^
+   |            ------   ^- help: try using a conversion method: `.to_string()`
    |            |        |
    |            |        expected struct `String`, found struct `Bar`
-   |            |        help: try using a conversion method: `f.to_string()`
    |            expected due to this
 
 error: aborting due to 3 previous errors
diff --git a/src/test/ui/suggestions/issue-82361.stderr b/src/test/ui/suggestions/issue-82361.stderr
index 4c78293ebb7..91b380e4e0d 100644
--- a/src/test/ui/suggestions/issue-82361.stderr
+++ b/src/test/ui/suggestions/issue-82361.stderr
@@ -6,12 +6,14 @@ LL | |         a
    | |         - expected because of this
 LL | |     } else {
 LL | |         b
-   | |         ^
-   | |         |
-   | |         expected `usize`, found `&usize`
-   | |         help: consider dereferencing the borrow: `*b`
+   | |         ^ expected `usize`, found `&usize`
 LL | |     };
    | |_____- `if` and `else` have incompatible types
+   |
+help: consider dereferencing the borrow
+   |
+LL |         *b
+   |         ^
 
 error[E0308]: `if` and `else` have incompatible types
   --> $DIR/issue-82361.rs:16:9
@@ -21,12 +23,14 @@ LL | |         1
    | |         - expected because of this
 LL | |     } else {
 LL | |         &1
-   | |         ^^
-   | |         |
-   | |         expected integer, found `&{integer}`
-   | |         help: consider removing the borrow: `1`
+   | |         ^^ expected integer, found `&{integer}`
 LL | |     };
    | |_____- `if` and `else` have incompatible types
+   |
+help: consider removing the borrow
+   |
+LL |         1
+   |        --
 
 error[E0308]: `if` and `else` have incompatible types
   --> $DIR/issue-82361.rs:22:9
@@ -36,12 +40,14 @@ LL | |         1
    | |         - expected because of this
 LL | |     } else {
 LL | |         &mut 1
-   | |         ^^^^^^
-   | |         |
-   | |         expected integer, found `&mut {integer}`
-   | |         help: consider removing the borrow: `1`
+   | |         ^^^^^^ expected integer, found `&mut {integer}`
 LL | |     };
    | |_____- `if` and `else` have incompatible types
+   |
+help: consider removing the borrow
+   |
+LL |         1
+   |        --
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/suggestions/issue-83943.stderr b/src/test/ui/suggestions/issue-83943.stderr
index a26700ea3c7..885106e8429 100644
--- a/src/test/ui/suggestions/issue-83943.stderr
+++ b/src/test/ui/suggestions/issue-83943.stderr
@@ -6,10 +6,9 @@ LL | |         "A".to_string()
    | |         --------------- expected because of this
 LL | |     } else {
 LL | |         "B"
-   | |         ^^^
+   | |         ^^^- help: try using a conversion method: `.to_string()`
    | |         |
    | |         expected struct `String`, found `&str`
-   | |         help: try using a conversion method: `"B".to_string()`
 LL | |     };
    | |_____- `if` and `else` have incompatible types
 
diff --git a/src/test/ui/suggestions/mut-ref-reassignment.stderr b/src/test/ui/suggestions/mut-ref-reassignment.stderr
index 327bbee1968..13b6182c0f5 100644
--- a/src/test/ui/suggestions/mut-ref-reassignment.stderr
+++ b/src/test/ui/suggestions/mut-ref-reassignment.stderr
@@ -9,7 +9,7 @@ LL |     opt = None;
 help: consider dereferencing here to assign to the mutable borrowed piece of memory
    |
 LL |     *opt = None;
-   |     ^^^^
+   |     ^
 
 error[E0308]: mismatched types
   --> $DIR/mut-ref-reassignment.rs:6:11
@@ -31,7 +31,7 @@ LL |     opt = Some(String::new())
 help: consider dereferencing here to assign to the mutable borrowed piece of memory
    |
 LL |     *opt = Some(String::new())
-   |     ^^^^
+   |     ^
 
 error[E0308]: mismatched types
   --> $DIR/mut-ref-reassignment.rs:14:11
diff --git a/src/test/ui/typeck/conversion-methods.stderr b/src/test/ui/typeck/conversion-methods.stderr
index 4f47e1fd0ff..15848c66c15 100644
--- a/src/test/ui/typeck/conversion-methods.stderr
+++ b/src/test/ui/typeck/conversion-methods.stderr
@@ -2,44 +2,43 @@ error[E0308]: mismatched types
   --> $DIR/conversion-methods.rs:5:41
    |
 LL |     let _tis_an_instants_play: String = "'Tis a fond Ambush—";
-   |                                ------   ^^^^^^^^^^^^^^^^^^^^^
+   |                                ------   ^^^^^^^^^^^^^^^^^^^^^- help: try using a conversion method: `.to_string()`
    |                                |        |
    |                                |        expected struct `String`, found `&str`
-   |                                |        help: try using a conversion method: `"'Tis a fond Ambush—".to_string()`
    |                                expected due to this
 
 error[E0308]: mismatched types
   --> $DIR/conversion-methods.rs:6:40
    |
 LL |     let _just_to_make_bliss: PathBuf = Path::new("/ern/her/own/surprise");
-   |                              -------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                              -------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: try using a conversion method: `.to_path_buf()`
    |                              |         |
    |                              |         expected struct `PathBuf`, found `&Path`
-   |                              |         help: try using a conversion method: `Path::new("/ern/her/own/surprise").to_path_buf()`
    |                              expected due to this
 
 error[E0308]: mismatched types
   --> $DIR/conversion-methods.rs:9:40
    |
 LL |     let _but_should_the_play: String = 2; // Perhaps surprisingly, we suggest .to_string() here
-   |                               ------   ^
+   |                               ------   ^- help: try using a conversion method: `.to_string()`
    |                               |        |
    |                               |        expected struct `String`, found integer
-   |                               |        help: try using a conversion method: `2.to_string()`
    |                               expected due to this
 
 error[E0308]: mismatched types
   --> $DIR/conversion-methods.rs:12:47
    |
 LL |     let _prove_piercing_earnest: Vec<usize> = &[1, 2, 3];
-   |                                  ----------   ^^^^^^^^^^
-   |                                  |            |
-   |                                  |            expected struct `Vec`, found `&[{integer}; 3]`
-   |                                  |            help: try using a conversion method: `(&[1, 2, 3]).to_vec()`
+   |                                  ----------   ^^^^^^^^^^ expected struct `Vec`, found `&[{integer}; 3]`
+   |                                  |
    |                                  expected due to this
    |
    = note: expected struct `Vec<usize>`
            found reference `&[{integer}; 3]`
+help: try using a conversion method
+   |
+LL |     let _prove_piercing_earnest: Vec<usize> = (&[1, 2, 3]).to_vec();
+   |                                               ^          ^^^^^^^^^^
 
 error: aborting due to 4 previous errors
 
diff --git a/src/tools/clippy/tests/ui/crashes/ice-6250.stderr b/src/tools/clippy/tests/ui/crashes/ice-6250.stderr
index c38727316cd..320b3bb42f8 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-6250.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-6250.stderr
@@ -25,10 +25,12 @@ error[E0308]: mismatched types
   --> $DIR/ice-6250.rs:12:14
    |
 LL |         Some(reference) = cache.data.get(key) {
-   |              ^^^^^^^^^
-   |              |
-   |              expected integer, found `&i32`
-   |              help: consider dereferencing the borrow: `*reference`
+   |              ^^^^^^^^^ expected integer, found `&i32`
+   |
+help: consider dereferencing the borrow
+   |
+LL |         Some(*reference) = cache.data.get(key) {
+   |              ^
 
 error[E0308]: mismatched types
   --> $DIR/ice-6250.rs:12:9