about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2023-05-09 12:33:44 +0530
committerGitHub <noreply@github.com>2023-05-09 12:33:44 +0530
commit2ecc72217b4f134a1ae8b6433af9491bf5d26cf0 (patch)
tree4f0617cc4e1b0a1efa9749576ac0fe0104790053
parent02a85bd038546d040efca42a313e44051b078f9c (diff)
parent4731a25d2dbe84e711101f2cbb83b40fa96c7014 (diff)
downloadrust-2ecc72217b4f134a1ae8b6433af9491bf5d26cf0.tar.gz
rust-2ecc72217b4f134a1ae8b6433af9491bf5d26cf0.zip
Rollup merge of #110504 - compiler-errors:tweak-borrow-sugg, r=cjgillot
Tweak borrow suggestion span

Avoids a `span_to_snippet` call when we don't need to surround the expression in parentheses. The fact that the suggestion was using the whole span of the expression rather than just appending a `&` was prevented me from using `// run-rustfix` in another PR (https://github.com/rust-lang/rust/pull/110432#discussion_r1170500484).

Also some drive-by renames of functions that have been annoying me for a bit.
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs198
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs10
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs8
-rw-r--r--tests/ui/argument-suggestions/issue-97484.stderr2
-rw-r--r--tests/ui/async-await/issues/issue-102206.stderr10
-rw-r--r--tests/ui/coercion/coercion-slice.stderr11
-rw-r--r--tests/ui/inference/deref-suggestion.stderr20
-rw-r--r--tests/ui/issues/issue-11374.stderr10
-rw-r--r--tests/ui/issues/issue-17033.stderr11
-rw-r--r--tests/ui/issues/issue-18819.stderr2
-rw-r--r--tests/ui/issues/issue-46302.stderr10
-rw-r--r--tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr20
-rw-r--r--tests/ui/issues/issue-61106.stderr10
-rw-r--r--tests/ui/methods/method-self-arg-1.stderr10
-rw-r--r--tests/ui/mismatched_types/dont-point-return-on-E0308.stderr10
-rw-r--r--tests/ui/mut/mut-cross-borrowing.stderr10
-rw-r--r--tests/ui/range/issue-54505-no-literals.fixed24
-rw-r--r--tests/ui/range/issue-54505-no-literals.rs24
-rw-r--r--tests/ui/range/issue-54505-no-literals.stderr120
-rw-r--r--tests/ui/range/issue-54505-no-std.rs12
-rw-r--r--tests/ui/range/issue-54505-no-std.stderr60
-rw-r--r--tests/ui/range/issue-54505.fixed12
-rw-r--r--tests/ui/range/issue-54505.rs12
-rw-r--r--tests/ui/range/issue-54505.stderr60
-rw-r--r--tests/ui/range/issue-73553-misinterp-range-literal.stderr20
-rw-r--r--tests/ui/span/coerce-suggestions.stderr11
-rw-r--r--tests/ui/span/issue-39018.stderr10
-rw-r--r--tests/ui/str/str-array-assignment.stderr21
-rw-r--r--tests/ui/suggestions/as-ref.stderr88
-rw-r--r--tests/ui/suggestions/suggest-ref-macro.rs4
-rw-r--r--tests/ui/suggestions/suggest-ref-macro.stderr19
-rw-r--r--tests/ui/type/type-mismatch.stderr20
-rw-r--r--tests/ui/typeck/bad-index-due-to-nested.stderr18
-rw-r--r--tests/ui/typeck/bad-type-in-vec-contains.stderr10
-rw-r--r--tests/ui/typeck/issue-13853.stderr10
-rw-r--r--tests/ui/unsized-locals/suggest-borrow.stderr11
36 files changed, 527 insertions, 391 deletions
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index 9d59cdcbc60..2defca54aff 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -86,9 +86,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.emit_type_mismatch_suggestions(err, expr, expr_ty, expected, expected_ty_expr, error);
         self.note_type_is_not_clone(err, expected, expr_ty, expr);
         self.note_internal_mutation_in_method(err, expr, Some(expected), expr_ty);
-        self.check_for_range_as_method_call(err, expr, expr_ty, expected);
-        self.check_for_binding_assigned_block_without_tail_expression(err, expr, expr_ty, expected);
-        self.check_wrong_return_type_due_to_generic_arg(err, expr, expr_ty);
+        self.suggest_method_call_on_range_literal(err, expr, expr_ty, expected);
+        self.suggest_return_binding_for_missing_tail_expr(err, expr, expr_ty, expected);
+        self.note_wrong_return_ty_due_to_generic_arg(err, expr, expr_ty);
     }
 
     /// Requires that the two types unify, and prints an error message if
@@ -1087,7 +1087,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// ```ignore (illustrative)
     /// opt.map(|param| { takes_ref(param) });
     /// ```
-    fn can_use_as_ref(&self, expr: &hir::Expr<'_>) -> Option<(Span, &'static str, String)> {
+    fn can_use_as_ref(&self, expr: &hir::Expr<'_>) -> Option<(Vec<(Span, String)>, &'static str)> {
         let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = expr.kind else {
             return None;
         };
@@ -1133,12 +1133,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             _ => false,
         };
-        match (is_as_ref_able, self.sess().source_map().span_to_snippet(method_path.ident.span)) {
-            (true, Ok(src)) => {
-                let suggestion = format!("as_ref().{}", src);
-                Some((method_path.ident.span, "consider using `as_ref` instead", suggestion))
-            }
-            _ => None,
+        if is_as_ref_able {
+            Some((
+                vec![(method_path.ident.span.shrink_to_lo(), "as_ref().".to_string())],
+                "consider using `as_ref` instead",
+            ))
+        } else {
+            None
         }
     }
 
@@ -1217,14 +1218,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// In addition of this check, it also checks between references mutability state. If the
     /// expected is mutable but the provided isn't, maybe we could just say "Hey, try with
     /// `&mut`!".
-    pub fn check_ref(
+    pub fn suggest_deref_or_ref(
         &self,
         expr: &hir::Expr<'tcx>,
         checked_ty: Ty<'tcx>,
         expected: Ty<'tcx>,
     ) -> Option<(
-        Span,
-        String,
+        Vec<(Span, String)>,
         String,
         Applicability,
         bool, /* verbose */
@@ -1254,30 +1254,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         && let Ok(src) = sm.span_to_snippet(sp)
                         && replace_prefix(&src, "b\"", "\"").is_some()
                     {
-                                let pos = sp.lo() + BytePos(1);
-                                return Some((
-                                    sp.with_hi(pos),
-                                    "consider removing the leading `b`".to_string(),
-                                    String::new(),
-                                    Applicability::MachineApplicable,
-                                    true,
-                                    false,
-                                ));
-                            }
-                        }
+                        let pos = sp.lo() + BytePos(1);
+                        return Some((
+                            vec![(sp.with_hi(pos), String::new())],
+                            "consider removing the leading `b`".to_string(),
+                            Applicability::MachineApplicable,
+                            true,
+                            false,
+                        ));
+                    }
+                }
                 (&ty::Array(arr, _) | &ty::Slice(arr), &ty::Str) if arr == self.tcx.types.u8 => {
                     if let hir::ExprKind::Lit(_) = expr.kind
                         && let Ok(src) = sm.span_to_snippet(sp)
                         && replace_prefix(&src, "\"", "b\"").is_some()
                     {
-                                return Some((
-                                    sp.shrink_to_lo(),
-                                    "consider adding a leading `b`".to_string(),
-                                    "b".to_string(),
-                                    Applicability::MachineApplicable,
-                                    true,
-                                    false,
-                                ));
+                        return Some((
+                            vec![(sp.shrink_to_lo(), "b".to_string())],
+                            "consider adding a leading `b`".to_string(),
+                            Applicability::MachineApplicable,
+                            true,
+                            false,
+                        ));
                     }
                 }
                 _ => {}
@@ -1320,66 +1318,73 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     }
 
                     if let hir::ExprKind::Unary(hir::UnOp::Deref, ref inner) = expr.kind
-                        && let Some(1) = self.deref_steps(expected, checked_ty) {
+                        && let Some(1) = self.deref_steps(expected, checked_ty)
+                    {
                         // We have `*&T`, check if what was expected was `&T`.
                         // If so, we may want to suggest removing a `*`.
                         sugg_sp = sugg_sp.with_hi(inner.span.lo());
                         return Some((
-                            sugg_sp,
+                            vec![(sugg_sp, String::new())],
                             "consider removing deref here".to_string(),
-                            "".to_string(),
                             Applicability::MachineApplicable,
                             true,
                             false,
                         ));
                     }
 
-                    if let Ok(src) = sm.span_to_snippet(sugg_sp) {
-                        let needs_parens = match expr.kind {
-                            // parenthesize if needed (Issue #46756)
-                            hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true,
-                            // parenthesize borrows of range literals (Issue #54505)
-                            _ if is_range_literal(expr) => true,
-                            _ => false,
-                        };
-
-                        if let Some(sugg) = self.can_use_as_ref(expr) {
-                            return Some((
-                                sugg.0,
-                                sugg.1.to_string(),
-                                sugg.2,
-                                Applicability::MachineApplicable,
-                                false,
-                                false,
-                            ));
-                        }
-
-                        let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
-                            Some(ident) => format!("{ident}: "),
-                            None => String::new(),
-                        };
-
-                        if let Some(hir::Node::Expr(hir::Expr {
-                            kind: hir::ExprKind::Assign(..),
-                            ..
-                        })) = self.tcx.hir().find_parent(expr.hir_id)
-                        {
-                            if mutability.is_mut() {
-                                // Suppressing this diagnostic, we'll properly print it in `check_expr_assign`
-                                return None;
-                            }
-                        }
+                    let needs_parens = match expr.kind {
+                        // parenthesize if needed (Issue #46756)
+                        hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true,
+                        // parenthesize borrows of range literals (Issue #54505)
+                        _ if is_range_literal(expr) => true,
+                        _ => false,
+                    };
 
-                        let sugg_expr = if needs_parens { format!("({src})") } else { src };
+                    if let Some((sugg, msg)) = self.can_use_as_ref(expr) {
                         return Some((
-                            sp,
-                            format!("consider {}borrowing here", mutability.mutably_str()),
-                            format!("{prefix}{}{sugg_expr}", mutability.ref_prefix_str()),
+                            sugg,
+                            msg.to_string(),
                             Applicability::MachineApplicable,
-                            false,
+                            true,
                             false,
                         ));
                     }
+
+                    let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
+                        Some(ident) => format!("{ident}: "),
+                        None => String::new(),
+                    };
+
+                    if let Some(hir::Node::Expr(hir::Expr {
+                        kind: hir::ExprKind::Assign(..),
+                        ..
+                    })) = self.tcx.hir().find_parent(expr.hir_id)
+                    {
+                        if mutability.is_mut() {
+                            // Suppressing this diagnostic, we'll properly print it in `check_expr_assign`
+                            return None;
+                        }
+                    }
+
+                    let sugg = mutability.ref_prefix_str();
+                    let (sugg, verbose) = if needs_parens {
+                        (
+                            vec![
+                                (sp.shrink_to_lo(), format!("{prefix}{sugg}(")),
+                                (sp.shrink_to_hi(), ")".to_string()),
+                            ],
+                            false,
+                        )
+                    } else {
+                        (vec![(sp.shrink_to_lo(), format!("{prefix}{sugg}"))], true)
+                    };
+                    return Some((
+                        sugg,
+                        format!("consider {}borrowing here", mutability.mutably_str()),
+                        Applicability::MachineApplicable,
+                        verbose,
+                        false,
+                    ));
                 }
             }
             (
@@ -1401,23 +1406,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         && sm.is_span_accessible(call_span)
                     {
                         return Some((
-                            sp.with_hi(call_span.lo()),
+                            vec![(sp.with_hi(call_span.lo()), String::new())],
                             "consider removing the borrow".to_string(),
-                            String::new(),
                             Applicability::MachineApplicable,
                             true,
-                            true
+                            true,
                         ));
                     }
                     return None;
                 }
-                if sp.contains(expr.span)
-                    && sm.is_span_accessible(expr.span)
-                {
+                if sp.contains(expr.span) && sm.is_span_accessible(expr.span) {
                     return Some((
-                        sp.with_hi(expr.span.lo()),
+                        vec![(sp.with_hi(expr.span.lo()), String::new())],
                         "consider removing the borrow".to_string(),
-                        String::new(),
                         Applicability::MachineApplicable,
                         true,
                         true,
@@ -1441,23 +1442,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                     let suggestion = replace_prefix(&src, old_prefix, &new_prefix).map(|_| {
                         // skip `&` or `&mut ` if both mutabilities are mutable
-                        let lo = sp.lo() + BytePos(min(old_prefix.len(), mutbl_b.ref_prefix_str().len()) as _);
+                        let lo = sp.lo()
+                            + BytePos(min(old_prefix.len(), mutbl_b.ref_prefix_str().len()) as _);
                         // skip `&` or `&mut `
                         let hi = sp.lo() + BytePos(old_prefix.len() as _);
                         let sp = sp.with_lo(lo).with_hi(hi);
 
                         (
                             sp,
-                            format!("{}{derefs}", if mutbl_a != mutbl_b { mutbl_b.prefix_str() } else { "" }),
-                            if mutbl_b <= mutbl_a { Applicability::MachineApplicable } else { Applicability::MaybeIncorrect }
+                            format!(
+                                "{}{derefs}",
+                                if mutbl_a != mutbl_b { mutbl_b.prefix_str() } else { "" }
+                            ),
+                            if mutbl_b <= mutbl_a {
+                                Applicability::MachineApplicable
+                            } else {
+                                Applicability::MaybeIncorrect
+                            },
                         )
                     });
 
                     if let Some((span, src, applicability)) = suggestion {
                         return Some((
-                            span,
+                            vec![(span, src)],
                             "consider dereferencing".to_string(),
-                            src,
                             applicability,
                             true,
                             false,
@@ -1486,9 +1494,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     // If we've reached our target type with just removing `&`, then just print now.
                     if steps == 0 && !remove.trim().is_empty() {
                         return Some((
-                            prefix_span,
+                            vec![(prefix_span, String::new())],
                             format!("consider removing the `{}`", remove.trim()),
-                            String::new(),
                             // Do not remove `&&` to get to bool, because it might be something like
                             // { a } && b, which we have a separate fixup suggestion that is more
                             // likely correct...
@@ -1554,9 +1561,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         }
 
                         return Some((
-                            span,
+                            vec![(span, suggestion)],
                             message,
-                            suggestion,
                             Applicability::MachineApplicable,
                             true,
                             false,
@@ -1569,7 +1575,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         None
     }
 
-    pub fn check_for_cast(
+    pub fn suggest_cast(
         &self,
         err: &mut Diagnostic,
         expr: &hir::Expr<'_>,
@@ -1936,7 +1942,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// Identify when the user has written `foo..bar()` instead of `foo.bar()`.
-    pub fn check_for_range_as_method_call(
+    pub fn suggest_method_call_on_range_literal(
         &self,
         err: &mut Diagnostic,
         expr: &hir::Expr<'tcx>,
@@ -2005,7 +2011,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     /// Identify when the type error is because `()` is found in a binding that was assigned a
     /// block without a tail expression.
-    fn check_for_binding_assigned_block_without_tail_expression(
+    fn suggest_return_binding_for_missing_tail_expr(
         &self,
         err: &mut Diagnostic,
         expr: &hir::Expr<'_>,
@@ -2047,7 +2053,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    fn check_wrong_return_type_due_to_generic_arg(
+    fn note_wrong_return_ty_due_to_generic_arg(
         &self,
         err: &mut Diagnostic,
         expr: &hir::Expr<'_>,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 2867fcc8ecd..c4add4dbdfb 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -275,13 +275,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
     ) -> bool {
         let expr = expr.peel_blocks();
-        if let Some((sp, msg, suggestion, applicability, verbose, annotation)) =
-            self.check_ref(expr, found, expected)
+        if let Some((suggestion, msg, applicability, verbose, annotation)) =
+            self.suggest_deref_or_ref(expr, found, expected)
         {
             if verbose {
-                err.span_suggestion_verbose(sp, msg, suggestion, applicability);
+                err.multipart_suggestion_verbose(msg, suggestion, applicability);
             } else {
-                err.span_suggestion(sp, msg, suggestion, applicability);
+                err.multipart_suggestion(msg, suggestion, applicability);
             }
             if annotation {
                 let suggest_annotation = match expr.peel_drop_temps().kind {
@@ -343,7 +343,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 err.span_label(sp, format!("{descr} `{name}` defined here"));
             }
             return true;
-        } else if self.check_for_cast(err, expr, found, expected, expected_ty_expr) {
+        } else if self.suggest_cast(err, expr, found, expected, expected_ty_expr) {
             return true;
         } else {
             let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id);
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 3741672e568..486c217707e 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -1045,7 +1045,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             );
         }
 
-        self.check_for_inner_self(&mut err, source, rcvr_ty, item_name);
+        self.suggest_unwrapping_inner_self(&mut err, source, rcvr_ty, item_name);
 
         bound_spans.sort();
         bound_spans.dedup();
@@ -1132,7 +1132,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         }
 
-        self.check_for_deref_method(&mut err, source, rcvr_ty, item_name, expected);
+        self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_name, expected);
         return Some(err);
     }
 
@@ -1805,7 +1805,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    fn check_for_inner_self(
+    fn suggest_unwrapping_inner_self(
         &self,
         err: &mut Diagnostic,
         source: SelfSource<'tcx>,
@@ -2175,7 +2175,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    fn check_for_deref_method(
+    fn note_derefed_ty_has_method(
         &self,
         err: &mut Diagnostic,
         self_source: SelfSource<'tcx>,
diff --git a/tests/ui/argument-suggestions/issue-97484.stderr b/tests/ui/argument-suggestions/issue-97484.stderr
index a86cbbf1802..082564fbc7f 100644
--- a/tests/ui/argument-suggestions/issue-97484.stderr
+++ b/tests/ui/argument-suggestions/issue-97484.stderr
@@ -16,7 +16,7 @@ LL | fn foo(a: &A, d: D, e: &E, g: G) {}
 help: consider borrowing here
    |
 LL |     foo(&&A, B, C, D, &E, F, G);
-   |                       ~~
+   |                       +
 help: remove the extra arguments
    |
 LL -     foo(&&A, B, C, D, E, F, G);
diff --git a/tests/ui/async-await/issues/issue-102206.stderr b/tests/ui/async-await/issues/issue-102206.stderr
index 750b7a886ef..cd845056805 100644
--- a/tests/ui/async-await/issues/issue-102206.stderr
+++ b/tests/ui/async-await/issues/issue-102206.stderr
@@ -2,14 +2,16 @@ error[E0308]: mismatched types
   --> $DIR/issue-102206.rs:6:27
    |
 LL |     std::mem::size_of_val(foo());
-   |     --------------------- ^^^^^
-   |     |                     |
-   |     |                     expected `&_`, found future
-   |     |                     help: consider borrowing here: `&foo()`
+   |     --------------------- ^^^^^ expected `&_`, found future
+   |     |
    |     arguments to this function are incorrect
    |
 note: function defined here
   --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
+help: consider borrowing here
+   |
+LL |     std::mem::size_of_val(&foo());
+   |                           +
 
 error: aborting due to previous error
 
diff --git a/tests/ui/coercion/coercion-slice.stderr b/tests/ui/coercion/coercion-slice.stderr
index c7b856a57eb..17bbca7a0bd 100644
--- a/tests/ui/coercion/coercion-slice.stderr
+++ b/tests/ui/coercion/coercion-slice.stderr
@@ -2,11 +2,14 @@ error[E0308]: mismatched types
   --> $DIR/coercion-slice.rs:4:21
    |
 LL |     let _: &[i32] = [0];
-   |            ------   ^^^
-   |            |        |
-   |            |        expected `&[i32]`, found `[{integer}; 1]`
-   |            |        help: consider borrowing here: `&[0]`
+   |            ------   ^^^ expected `&[i32]`, found `[{integer}; 1]`
+   |            |
    |            expected due to this
+   |
+help: consider borrowing here
+   |
+LL |     let _: &[i32] = &[0];
+   |                     +
 
 error: aborting due to previous error
 
diff --git a/tests/ui/inference/deref-suggestion.stderr b/tests/ui/inference/deref-suggestion.stderr
index 6f5aacacfc1..c58aab42269 100644
--- a/tests/ui/inference/deref-suggestion.stderr
+++ b/tests/ui/inference/deref-suggestion.stderr
@@ -98,19 +98,23 @@ error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:40:17
    |
 LL |     let s = S { u };
-   |                 ^
-   |                 |
-   |                 expected `&u32`, found integer
-   |                 help: consider borrowing here: `u: &u`
+   |                 ^ expected `&u32`, found integer
+   |
+help: consider borrowing here
+   |
+LL |     let s = S { u: &u };
+   |                 ++++
 
 error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:42:20
    |
 LL |     let s = S { u: u };
-   |                    ^
-   |                    |
-   |                    expected `&u32`, found integer
-   |                    help: consider borrowing here: `&u`
+   |                    ^ expected `&u32`, found integer
+   |
+help: consider borrowing here
+   |
+LL |     let s = S { u: &u };
+   |                    +
 
 error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:45:17
diff --git a/tests/ui/issues/issue-11374.stderr b/tests/ui/issues/issue-11374.stderr
index 6e1fb1540bb..879dc5b76c5 100644
--- a/tests/ui/issues/issue-11374.stderr
+++ b/tests/ui/issues/issue-11374.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
   --> $DIR/issue-11374.rs:26:15
    |
 LL |     c.read_to(v);
-   |       ------- ^
-   |       |       |
-   |       |       expected `&mut [u8]`, found `Vec<_>`
-   |       |       help: consider mutably borrowing here: `&mut v`
+   |       ------- ^ expected `&mut [u8]`, found `Vec<_>`
+   |       |
    |       arguments to this method are incorrect
    |
    = note: expected mutable reference `&mut [u8]`
@@ -15,6 +13,10 @@ note: method defined here
    |
 LL |     pub fn read_to(&mut self, vec: &mut [u8]) {
    |            ^^^^^^^            --------------
+help: consider mutably borrowing here
+   |
+LL |     c.read_to(&mut v);
+   |               ++++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/issues/issue-17033.stderr b/tests/ui/issues/issue-17033.stderr
index f26bee5ff45..3419c079859 100644
--- a/tests/ui/issues/issue-17033.stderr
+++ b/tests/ui/issues/issue-17033.stderr
@@ -2,11 +2,14 @@ error[E0308]: mismatched types
   --> $DIR/issue-17033.rs:2:10
    |
 LL |     (*p)(())
-   |     ---- ^^
-   |     |    |
-   |     |    expected `&mut ()`, found `()`
-   |     |    help: consider mutably borrowing here: `&mut ()`
+   |     ---- ^^ expected `&mut ()`, found `()`
+   |     |
    |     arguments to this function are incorrect
+   |
+help: consider mutably borrowing here
+   |
+LL |     (*p)(&mut ())
+   |          ++++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/issues/issue-18819.stderr b/tests/ui/issues/issue-18819.stderr
index 1fc974b609c..40098f9622f 100644
--- a/tests/ui/issues/issue-18819.stderr
+++ b/tests/ui/issues/issue-18819.stderr
@@ -19,7 +19,7 @@ LL | fn print_x(_: &dyn Foo<Item=bool>, extra: &str) {
 help: consider borrowing here
    |
 LL |     print_x(&X);
-   |             ~~
+   |             +
 help: provide the argument
    |
 LL |     print_x(/* &dyn Foo<Item = bool> */, /* &str */);
diff --git a/tests/ui/issues/issue-46302.stderr b/tests/ui/issues/issue-46302.stderr
index a6f97c3c9af..6e126038cc9 100644
--- a/tests/ui/issues/issue-46302.stderr
+++ b/tests/ui/issues/issue-46302.stderr
@@ -2,10 +2,12 @@ error[E0308]: mismatched types
   --> $DIR/issue-46302.rs:3:27
    |
 LL |   let u: &str = if true { s[..2] } else { s };
-   |                           ^^^^^^
-   |                           |
-   |                           expected `&str`, found `str`
-   |                           help: consider borrowing here: `&s[..2]`
+   |                           ^^^^^^ expected `&str`, found `str`
+   |
+help: consider borrowing here
+   |
+LL |   let u: &str = if true { &s[..2] } else { s };
+   |                           +
 
 error: aborting due to previous error
 
diff --git a/tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr b/tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr
index e874ded8ec5..211dd512895 100644
--- a/tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr
+++ b/tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
   --> $DIR/issue-46756-consider-borrowing-cast-or-binexpr.rs:12:42
    |
 LL |     light_flows_our_war_of_mocking_words(behold as usize);
-   |     ------------------------------------ ^^^^^^^^^^^^^^^
-   |     |                                    |
-   |     |                                    expected `&usize`, found `usize`
-   |     |                                    help: consider borrowing here: `&(behold as usize)`
+   |     ------------------------------------ ^^^^^^^^^^^^^^^ expected `&usize`, found `usize`
+   |     |
    |     arguments to this function are incorrect
    |
 note: function defined here
@@ -13,15 +11,17 @@ note: function defined here
    |
 LL | fn light_flows_our_war_of_mocking_words(and_yet: &usize) -> usize {
    |    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------
+help: consider borrowing here
+   |
+LL |     light_flows_our_war_of_mocking_words(&(behold as usize));
+   |                                          ++               +
 
 error[E0308]: mismatched types
   --> $DIR/issue-46756-consider-borrowing-cast-or-binexpr.rs:14:42
    |
 LL |     light_flows_our_war_of_mocking_words(with_tears + 4);
-   |     ------------------------------------ ^^^^^^^^^^^^^^
-   |     |                                    |
-   |     |                                    expected `&usize`, found `usize`
-   |     |                                    help: consider borrowing here: `&(with_tears + 4)`
+   |     ------------------------------------ ^^^^^^^^^^^^^^ expected `&usize`, found `usize`
+   |     |
    |     arguments to this function are incorrect
    |
 note: function defined here
@@ -29,6 +29,10 @@ note: function defined here
    |
 LL | fn light_flows_our_war_of_mocking_words(and_yet: &usize) -> usize {
    |    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------
+help: consider borrowing here
+   |
+LL |     light_flows_our_war_of_mocking_words(&(with_tears + 4));
+   |                                          ++              +
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/issues/issue-61106.stderr b/tests/ui/issues/issue-61106.stderr
index eff3e6e7849..aa922e2682d 100644
--- a/tests/ui/issues/issue-61106.stderr
+++ b/tests/ui/issues/issue-61106.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
   --> $DIR/issue-61106.rs:3:9
    |
 LL |     foo(x.clone());
-   |     --- ^^^^^^^^^
-   |     |   |
-   |     |   expected `&str`, found `String`
-   |     |   help: consider borrowing here: `&x`
+   |     --- ^^^^^^^^^ expected `&str`, found `String`
+   |     |
    |     arguments to this function are incorrect
    |
 note: function defined here
@@ -13,6 +11,10 @@ note: function defined here
    |
 LL | fn foo(_: &str) {}
    |    ^^^ -------
+help: consider borrowing here
+   |
+LL |     foo(&x.clone());
+   |         +
 
 error: aborting due to previous error
 
diff --git a/tests/ui/methods/method-self-arg-1.stderr b/tests/ui/methods/method-self-arg-1.stderr
index 9241a8be58f..dcc21acc5c0 100644
--- a/tests/ui/methods/method-self-arg-1.stderr
+++ b/tests/ui/methods/method-self-arg-1.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
   --> $DIR/method-self-arg-1.rs:11:14
    |
 LL |     Foo::bar(x);
-   |     -------- ^
-   |     |        |
-   |     |        expected `&Foo`, found `Foo`
-   |     |        help: consider borrowing here: `&x`
+   |     -------- ^ expected `&Foo`, found `Foo`
+   |     |
    |     arguments to this function are incorrect
    |
 note: method defined here
@@ -13,6 +11,10 @@ note: method defined here
    |
 LL |     fn bar(&self) {}
    |        ^^^ -----
+help: consider borrowing here
+   |
+LL |     Foo::bar(&x);
+   |              +
 
 error[E0308]: mismatched types
   --> $DIR/method-self-arg-1.rs:13:14
diff --git a/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr b/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr
index 13942682d28..7be94ef4ad6 100644
--- a/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr
+++ b/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
   --> $DIR/dont-point-return-on-E0308.rs:11:11
    |
 LL |         f(());
-   |         - ^^
-   |         | |
-   |         | expected `&()`, found `()`
-   |         | help: consider borrowing here: `&()`
+   |         - ^^ expected `&()`, found `()`
+   |         |
    |         arguments to this function are incorrect
    |
 note: function defined here
@@ -13,6 +11,10 @@ note: function defined here
    |
 LL | async fn f(_: &()) {}
    |          ^ ------
+help: consider borrowing here
+   |
+LL |         f(&());
+   |           +
 
 error: aborting due to previous error
 
diff --git a/tests/ui/mut/mut-cross-borrowing.stderr b/tests/ui/mut/mut-cross-borrowing.stderr
index 8401827e51f..8a3076db9b2 100644
--- a/tests/ui/mut/mut-cross-borrowing.stderr
+++ b/tests/ui/mut/mut-cross-borrowing.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
   --> $DIR/mut-cross-borrowing.rs:7:7
    |
 LL |     f(x)
-   |     - ^
-   |     | |
-   |     | expected `&mut isize`, found `Box<{integer}>`
-   |     | help: consider mutably borrowing here: `&mut x`
+   |     - ^ expected `&mut isize`, found `Box<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected mutable reference `&mut isize`
@@ -15,6 +13,10 @@ note: function defined here
    |
 LL | fn f(_: &mut isize) {}
    |    ^ -------------
+help: consider mutably borrowing here
+   |
+LL |     f(&mut x)
+   |       ++++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/range/issue-54505-no-literals.fixed b/tests/ui/range/issue-54505-no-literals.fixed
index 4d8f67182b9..71c36c741cc 100644
--- a/tests/ui/range/issue-54505-no-literals.fixed
+++ b/tests/ui/range/issue-54505-no-literals.fixed
@@ -16,60 +16,60 @@ fn main() {
     take_range(&std::ops::Range { start: 0, end: 1 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &std::ops::Range { start: 0, end: 1 }
+    //~| SUGGESTION &
 
     take_range(&::std::ops::Range { start: 0, end: 1 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &::std::ops::Range { start: 0, end: 1 }
+    //~| SUGGESTION &
 
     take_range(&std::ops::RangeFrom { start: 1 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &std::ops::RangeFrom { start: 1 }
+    //~| SUGGESTION &
 
     take_range(&::std::ops::RangeFrom { start: 1 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &::std::ops::RangeFrom { start: 1 }
+    //~| SUGGESTION &
 
     take_range(&std::ops::RangeFull {});
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &std::ops::RangeFull {}
+    //~| SUGGESTION &
 
     take_range(&::std::ops::RangeFull {});
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &::std::ops::RangeFull {}
+    //~| SUGGESTION &
 
     take_range(&std::ops::RangeInclusive::new(0, 1));
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &std::ops::RangeInclusive::new(0, 1)
+    //~| SUGGESTION &
 
     take_range(&::std::ops::RangeInclusive::new(0, 1));
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &::std::ops::RangeInclusive::new(0, 1)
+    //~| SUGGESTION &
 
     take_range(&std::ops::RangeTo { end: 5 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &std::ops::RangeTo { end: 5 }
+    //~| SUGGESTION &
 
     take_range(&::std::ops::RangeTo { end: 5 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &::std::ops::RangeTo { end: 5 }
+    //~| SUGGESTION &
 
     take_range(&std::ops::RangeToInclusive { end: 5 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &std::ops::RangeToInclusive { end: 5 }
+    //~| SUGGESTION &
 
     take_range(&::std::ops::RangeToInclusive { end: 5 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &::std::ops::RangeToInclusive { end: 5 }
+    //~| SUGGESTION &
 }
diff --git a/tests/ui/range/issue-54505-no-literals.rs b/tests/ui/range/issue-54505-no-literals.rs
index dc21dcbc2db..db125d1a22b 100644
--- a/tests/ui/range/issue-54505-no-literals.rs
+++ b/tests/ui/range/issue-54505-no-literals.rs
@@ -16,60 +16,60 @@ fn main() {
     take_range(std::ops::Range { start: 0, end: 1 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &std::ops::Range { start: 0, end: 1 }
+    //~| SUGGESTION &
 
     take_range(::std::ops::Range { start: 0, end: 1 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &::std::ops::Range { start: 0, end: 1 }
+    //~| SUGGESTION &
 
     take_range(std::ops::RangeFrom { start: 1 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &std::ops::RangeFrom { start: 1 }
+    //~| SUGGESTION &
 
     take_range(::std::ops::RangeFrom { start: 1 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &::std::ops::RangeFrom { start: 1 }
+    //~| SUGGESTION &
 
     take_range(std::ops::RangeFull {});
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &std::ops::RangeFull {}
+    //~| SUGGESTION &
 
     take_range(::std::ops::RangeFull {});
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &::std::ops::RangeFull {}
+    //~| SUGGESTION &
 
     take_range(std::ops::RangeInclusive::new(0, 1));
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &std::ops::RangeInclusive::new(0, 1)
+    //~| SUGGESTION &
 
     take_range(::std::ops::RangeInclusive::new(0, 1));
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &::std::ops::RangeInclusive::new(0, 1)
+    //~| SUGGESTION &
 
     take_range(std::ops::RangeTo { end: 5 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &std::ops::RangeTo { end: 5 }
+    //~| SUGGESTION &
 
     take_range(::std::ops::RangeTo { end: 5 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &::std::ops::RangeTo { end: 5 }
+    //~| SUGGESTION &
 
     take_range(std::ops::RangeToInclusive { end: 5 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &std::ops::RangeToInclusive { end: 5 }
+    //~| SUGGESTION &
 
     take_range(::std::ops::RangeToInclusive { end: 5 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &::std::ops::RangeToInclusive { end: 5 }
+    //~| SUGGESTION &
 }
diff --git a/tests/ui/range/issue-54505-no-literals.stderr b/tests/ui/range/issue-54505-no-literals.stderr
index d112983848d..5894bb6ba55 100644
--- a/tests/ui/range/issue-54505-no-literals.stderr
+++ b/tests/ui/range/issue-54505-no-literals.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:16:16
    |
 LL |     take_range(std::ops::Range { start: 0, end: 1 });
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |     |          |
-   |     |          expected `&_`, found `Range<{integer}>`
-   |     |          help: consider borrowing here: `&std::ops::Range { start: 0, end: 1 }`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `Range<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -15,15 +13,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&std::ops::Range { start: 0, end: 1 });
+   |                +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:21:16
    |
 LL |     take_range(::std::ops::Range { start: 0, end: 1 });
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |     |          |
-   |     |          expected `&_`, found `Range<{integer}>`
-   |     |          help: consider borrowing here: `&::std::ops::Range { start: 0, end: 1 }`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `Range<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -33,15 +33,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&::std::ops::Range { start: 0, end: 1 });
+   |                +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:26:16
    |
 LL |     take_range(std::ops::RangeFrom { start: 1 });
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeFrom<{integer}>`
-   |     |          help: consider borrowing here: `&std::ops::RangeFrom { start: 1 }`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeFrom<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -51,15 +53,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&std::ops::RangeFrom { start: 1 });
+   |                +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:31:16
    |
 LL |     take_range(::std::ops::RangeFrom { start: 1 });
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeFrom<{integer}>`
-   |     |          help: consider borrowing here: `&::std::ops::RangeFrom { start: 1 }`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeFrom<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -69,15 +73,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&::std::ops::RangeFrom { start: 1 });
+   |                +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:36:16
    |
 LL |     take_range(std::ops::RangeFull {});
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeFull`
-   |     |          help: consider borrowing here: `&std::ops::RangeFull {}`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeFull`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -87,15 +93,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&std::ops::RangeFull {});
+   |                +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:41:16
    |
 LL |     take_range(::std::ops::RangeFull {});
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeFull`
-   |     |          help: consider borrowing here: `&::std::ops::RangeFull {}`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeFull`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -105,15 +113,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&::std::ops::RangeFull {});
+   |                +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:46:16
    |
 LL |     take_range(std::ops::RangeInclusive::new(0, 1));
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeInclusive<{integer}>`
-   |     |          help: consider borrowing here: `&std::ops::RangeInclusive::new(0, 1)`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeInclusive<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -123,15 +133,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&std::ops::RangeInclusive::new(0, 1));
+   |                +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:51:16
    |
 LL |     take_range(::std::ops::RangeInclusive::new(0, 1));
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeInclusive<{integer}>`
-   |     |          help: consider borrowing here: `&::std::ops::RangeInclusive::new(0, 1)`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeInclusive<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -141,15 +153,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&::std::ops::RangeInclusive::new(0, 1));
+   |                +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:56:16
    |
 LL |     take_range(std::ops::RangeTo { end: 5 });
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeTo<{integer}>`
-   |     |          help: consider borrowing here: `&std::ops::RangeTo { end: 5 }`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeTo<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -159,15 +173,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&std::ops::RangeTo { end: 5 });
+   |                +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:61:16
    |
 LL |     take_range(::std::ops::RangeTo { end: 5 });
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeTo<{integer}>`
-   |     |          help: consider borrowing here: `&::std::ops::RangeTo { end: 5 }`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeTo<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -177,15 +193,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&::std::ops::RangeTo { end: 5 });
+   |                +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:66:16
    |
 LL |     take_range(std::ops::RangeToInclusive { end: 5 });
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeToInclusive<{integer}>`
-   |     |          help: consider borrowing here: `&std::ops::RangeToInclusive { end: 5 }`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeToInclusive<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -195,15 +213,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&std::ops::RangeToInclusive { end: 5 });
+   |                +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:71:16
    |
 LL |     take_range(::std::ops::RangeToInclusive { end: 5 });
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeToInclusive<{integer}>`
-   |     |          help: consider borrowing here: `&::std::ops::RangeToInclusive { end: 5 }`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeToInclusive<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -213,6 +233,10 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&::std::ops::RangeToInclusive { end: 5 });
+   |                +
 
 error: aborting due to 12 previous errors
 
diff --git a/tests/ui/range/issue-54505-no-std.rs b/tests/ui/range/issue-54505-no-std.rs
index 9f378b4836e..db455fada3b 100644
--- a/tests/ui/range/issue-54505-no-std.rs
+++ b/tests/ui/range/issue-54505-no-std.rs
@@ -29,30 +29,30 @@ fn main() {
     take_range(0..1);
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(0..1)
+    //~| SUGGESTION &(
 
     take_range(1..);
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(1..)
+    //~| SUGGESTION &(
 
     take_range(..);
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(..)
+    //~| SUGGESTION &(
 
     take_range(0..=1);
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(0..=1)
+    //~| SUGGESTION &(
 
     take_range(..5);
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(..5)
+    //~| SUGGESTION &(
 
     take_range(..=42);
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(..=42)
+    //~| SUGGESTION &(
 }
diff --git a/tests/ui/range/issue-54505-no-std.stderr b/tests/ui/range/issue-54505-no-std.stderr
index a6a9f89da74..13563d1940c 100644
--- a/tests/ui/range/issue-54505-no-std.stderr
+++ b/tests/ui/range/issue-54505-no-std.stderr
@@ -14,10 +14,8 @@ error[E0308]: mismatched types
   --> $DIR/issue-54505-no-std.rs:29:16
    |
 LL |     take_range(0..1);
-   |     ---------- ^^^^
-   |     |          |
-   |     |          expected `&_`, found `Range<{integer}>`
-   |     |          help: consider borrowing here: `&(0..1)`
+   |     ---------- ^^^^ expected `&_`, found `Range<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -27,15 +25,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&(0..1));
+   |                ++    +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-std.rs:34:16
    |
 LL |     take_range(1..);
-   |     ---------- ^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeFrom<{integer}>`
-   |     |          help: consider borrowing here: `&(1..)`
+   |     ---------- ^^^ expected `&_`, found `RangeFrom<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -45,15 +45,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&(1..));
+   |                ++   +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-std.rs:39:16
    |
 LL |     take_range(..);
-   |     ---------- ^^
-   |     |          |
-   |     |          expected `&_`, found `RangeFull`
-   |     |          help: consider borrowing here: `&(..)`
+   |     ---------- ^^ expected `&_`, found `RangeFull`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -63,15 +65,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&(..));
+   |                ++  +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-std.rs:44:16
    |
 LL |     take_range(0..=1);
-   |     ---------- ^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeInclusive<{integer}>`
-   |     |          help: consider borrowing here: `&(0..=1)`
+   |     ---------- ^^^^^ expected `&_`, found `RangeInclusive<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -81,15 +85,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&(0..=1));
+   |                ++     +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-std.rs:49:16
    |
 LL |     take_range(..5);
-   |     ---------- ^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeTo<{integer}>`
-   |     |          help: consider borrowing here: `&(..5)`
+   |     ---------- ^^^ expected `&_`, found `RangeTo<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -99,15 +105,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&(..5));
+   |                ++   +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-std.rs:54:16
    |
 LL |     take_range(..=42);
-   |     ---------- ^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeToInclusive<{integer}>`
-   |     |          help: consider borrowing here: `&(..=42)`
+   |     ---------- ^^^^^ expected `&_`, found `RangeToInclusive<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -117,6 +125,10 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&(..=42));
+   |                ++     +
 
 error: aborting due to 8 previous errors
 
diff --git a/tests/ui/range/issue-54505.fixed b/tests/ui/range/issue-54505.fixed
index f8298c0b5ce..9d113ba1d35 100644
--- a/tests/ui/range/issue-54505.fixed
+++ b/tests/ui/range/issue-54505.fixed
@@ -14,30 +14,30 @@ fn main() {
     take_range(&(0..1));
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(0..1)
+    //~| SUGGESTION &(
 
     take_range(&(1..));
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(1..)
+    //~| SUGGESTION &(
 
     take_range(&(..));
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(..)
+    //~| SUGGESTION &(
 
     take_range(&(0..=1));
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(0..=1)
+    //~| SUGGESTION &(
 
     take_range(&(..5));
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(..5)
+    //~| SUGGESTION &(
 
     take_range(&(..=42));
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(..=42)
+    //~| SUGGESTION &(
 }
diff --git a/tests/ui/range/issue-54505.rs b/tests/ui/range/issue-54505.rs
index 03673252dd3..c9929988fe5 100644
--- a/tests/ui/range/issue-54505.rs
+++ b/tests/ui/range/issue-54505.rs
@@ -14,30 +14,30 @@ fn main() {
     take_range(0..1);
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(0..1)
+    //~| SUGGESTION &(
 
     take_range(1..);
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(1..)
+    //~| SUGGESTION &(
 
     take_range(..);
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(..)
+    //~| SUGGESTION &(
 
     take_range(0..=1);
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(0..=1)
+    //~| SUGGESTION &(
 
     take_range(..5);
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(..5)
+    //~| SUGGESTION &(
 
     take_range(..=42);
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(..=42)
+    //~| SUGGESTION &(
 }
diff --git a/tests/ui/range/issue-54505.stderr b/tests/ui/range/issue-54505.stderr
index eda047b507a..0e959fc05e2 100644
--- a/tests/ui/range/issue-54505.stderr
+++ b/tests/ui/range/issue-54505.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
   --> $DIR/issue-54505.rs:14:16
    |
 LL |     take_range(0..1);
-   |     ---------- ^^^^
-   |     |          |
-   |     |          expected `&_`, found `Range<{integer}>`
-   |     |          help: consider borrowing here: `&(0..1)`
+   |     ---------- ^^^^ expected `&_`, found `Range<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -15,15 +13,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&(0..1));
+   |                ++    +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505.rs:19:16
    |
 LL |     take_range(1..);
-   |     ---------- ^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeFrom<{integer}>`
-   |     |          help: consider borrowing here: `&(1..)`
+   |     ---------- ^^^ expected `&_`, found `RangeFrom<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -33,15 +33,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&(1..));
+   |                ++   +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505.rs:24:16
    |
 LL |     take_range(..);
-   |     ---------- ^^
-   |     |          |
-   |     |          expected `&_`, found `RangeFull`
-   |     |          help: consider borrowing here: `&(..)`
+   |     ---------- ^^ expected `&_`, found `RangeFull`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -51,15 +53,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&(..));
+   |                ++  +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505.rs:29:16
    |
 LL |     take_range(0..=1);
-   |     ---------- ^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeInclusive<{integer}>`
-   |     |          help: consider borrowing here: `&(0..=1)`
+   |     ---------- ^^^^^ expected `&_`, found `RangeInclusive<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -69,15 +73,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&(0..=1));
+   |                ++     +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505.rs:34:16
    |
 LL |     take_range(..5);
-   |     ---------- ^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeTo<{integer}>`
-   |     |          help: consider borrowing here: `&(..5)`
+   |     ---------- ^^^ expected `&_`, found `RangeTo<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -87,15 +93,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&(..5));
+   |                ++   +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505.rs:39:16
    |
 LL |     take_range(..=42);
-   |     ---------- ^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeToInclusive<{integer}>`
-   |     |          help: consider borrowing here: `&(..=42)`
+   |     ---------- ^^^^^ expected `&_`, found `RangeToInclusive<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -105,6 +113,10 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&(..=42));
+   |                ++     +
 
 error: aborting due to 6 previous errors
 
diff --git a/tests/ui/range/issue-73553-misinterp-range-literal.stderr b/tests/ui/range/issue-73553-misinterp-range-literal.stderr
index 77595b3678e..52efa241d0b 100644
--- a/tests/ui/range/issue-73553-misinterp-range-literal.stderr
+++ b/tests/ui/range/issue-73553-misinterp-range-literal.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
   --> $DIR/issue-73553-misinterp-range-literal.rs:12:10
    |
 LL |     demo(tell(1)..tell(10));
-   |     ---- ^^^^^^^^^^^^^^^^^
-   |     |    |
-   |     |    expected `&Range<usize>`, found `Range<usize>`
-   |     |    help: consider borrowing here: `&(tell(1)..tell(10))`
+   |     ---- ^^^^^^^^^^^^^^^^^ expected `&Range<usize>`, found `Range<usize>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&std::ops::Range<usize>`
@@ -15,15 +13,17 @@ note: function defined here
    |
 LL | fn demo(r: &Range) {
    |    ^^^^ ---------
+help: consider borrowing here
+   |
+LL |     demo(&(tell(1)..tell(10)));
+   |          ++                 +
 
 error[E0308]: mismatched types
   --> $DIR/issue-73553-misinterp-range-literal.rs:14:10
    |
 LL |     demo(1..10);
-   |     ---- ^^^^^
-   |     |    |
-   |     |    expected `&Range<usize>`, found `Range<{integer}>`
-   |     |    help: consider borrowing here: `&(1..10)`
+   |     ---- ^^^^^ expected `&Range<usize>`, found `Range<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&std::ops::Range<usize>`
@@ -33,6 +33,10 @@ note: function defined here
    |
 LL | fn demo(r: &Range) {
    |    ^^^^ ---------
+help: consider borrowing here
+   |
+LL |     demo(&(1..10));
+   |          ++     +
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/span/coerce-suggestions.stderr b/tests/ui/span/coerce-suggestions.stderr
index bb30f000ea7..ff840b781f0 100644
--- a/tests/ui/span/coerce-suggestions.stderr
+++ b/tests/ui/span/coerce-suggestions.stderr
@@ -10,11 +10,14 @@ error[E0308]: mismatched types
   --> $DIR/coerce-suggestions.rs:9:19
    |
 LL |     let x: &str = String::new();
-   |            ----   ^^^^^^^^^^^^^
-   |            |      |
-   |            |      expected `&str`, found `String`
-   |            |      help: consider borrowing here: `&String::new()`
+   |            ----   ^^^^^^^^^^^^^ expected `&str`, found `String`
+   |            |
    |            expected due to this
+   |
+help: consider borrowing here
+   |
+LL |     let x: &str = &String::new();
+   |                   +
 
 error[E0308]: mismatched types
   --> $DIR/coerce-suggestions.rs:12:10
diff --git a/tests/ui/span/issue-39018.stderr b/tests/ui/span/issue-39018.stderr
index bae93639271..c8c4a513988 100644
--- a/tests/ui/span/issue-39018.stderr
+++ b/tests/ui/span/issue-39018.stderr
@@ -78,10 +78,12 @@ error[E0308]: mismatched types
   --> $DIR/issue-39018.rs:29:17
    |
 LL |     let _ = a + b;
-   |                 ^
-   |                 |
-   |                 expected `&str`, found `String`
-   |                 help: consider borrowing here: `&b`
+   |                 ^ expected `&str`, found `String`
+   |
+help: consider borrowing here
+   |
+LL |     let _ = a + &b;
+   |                 +
 
 error[E0369]: cannot add `String` to `&String`
   --> $DIR/issue-39018.rs:30:15
diff --git a/tests/ui/str/str-array-assignment.stderr b/tests/ui/str/str-array-assignment.stderr
index c23400a1d14..515cb9e12f8 100644
--- a/tests/ui/str/str-array-assignment.stderr
+++ b/tests/ui/str/str-array-assignment.stderr
@@ -10,10 +10,12 @@ error[E0308]: mismatched types
   --> $DIR/str-array-assignment.rs:5:27
    |
 LL |   let u: &str = if true { s[..2] } else { s };
-   |                           ^^^^^^
-   |                           |
-   |                           expected `&str`, found `str`
-   |                           help: consider borrowing here: `&s[..2]`
+   |                           ^^^^^^ expected `&str`, found `str`
+   |
+help: consider borrowing here
+   |
+LL |   let u: &str = if true { &s[..2] } else { s };
+   |                           +
 
 error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/str-array-assignment.rs:7:7
@@ -33,11 +35,14 @@ error[E0308]: mismatched types
   --> $DIR/str-array-assignment.rs:9:17
    |
 LL |   let w: &str = s[..2];
-   |          ----   ^^^^^^
-   |          |      |
-   |          |      expected `&str`, found `str`
-   |          |      help: consider borrowing here: `&s[..2]`
+   |          ----   ^^^^^^ expected `&str`, found `str`
+   |          |
    |          expected due to this
+   |
+help: consider borrowing here
+   |
+LL |   let w: &str = &s[..2];
+   |                 +
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/suggestions/as-ref.stderr b/tests/ui/suggestions/as-ref.stderr
index 0ee343ebf9f..2147d2d92e3 100644
--- a/tests/ui/suggestions/as-ref.stderr
+++ b/tests/ui/suggestions/as-ref.stderr
@@ -2,61 +2,73 @@ error[E0308]: mismatched types
   --> $DIR/as-ref.rs:7:29
    |
 LL |     opt.map(|arg| takes_ref(arg));
-   |         ---       --------- ^^^ expected `&Foo`, found `Foo`
-   |         |         |
-   |         |         arguments to this function are incorrect
-   |         help: consider using `as_ref` instead: `as_ref().map`
+   |                   --------- ^^^ expected `&Foo`, found `Foo`
+   |                   |
+   |                   arguments to this function are incorrect
    |
 note: function defined here
   --> $DIR/as-ref.rs:3:4
    |
 LL | fn takes_ref(_: &Foo) {}
    |    ^^^^^^^^^ -------
+help: consider using `as_ref` instead
+   |
+LL |     opt.as_ref().map(|arg| takes_ref(arg));
+   |         +++++++++
 
 error[E0308]: mismatched types
   --> $DIR/as-ref.rs:8:39
    |
 LL |     opt.and_then(|arg| Some(takes_ref(arg)));
-   |         --------            --------- ^^^ expected `&Foo`, found `Foo`
-   |         |                   |
-   |         |                   arguments to this function are incorrect
-   |         help: consider using `as_ref` instead: `as_ref().and_then`
+   |                             --------- ^^^ expected `&Foo`, found `Foo`
+   |                             |
+   |                             arguments to this function are incorrect
    |
 note: function defined here
   --> $DIR/as-ref.rs:3:4
    |
 LL | fn takes_ref(_: &Foo) {}
    |    ^^^^^^^^^ -------
+help: consider using `as_ref` instead
+   |
+LL |     opt.as_ref().and_then(|arg| Some(takes_ref(arg)));
+   |         +++++++++
 
 error[E0308]: mismatched types
   --> $DIR/as-ref.rs:10:29
    |
 LL |     opt.map(|arg| takes_ref(arg));
-   |         ---       --------- ^^^ expected `&Foo`, found `Foo`
-   |         |         |
-   |         |         arguments to this function are incorrect
-   |         help: consider using `as_ref` instead: `as_ref().map`
+   |                   --------- ^^^ expected `&Foo`, found `Foo`
+   |                   |
+   |                   arguments to this function are incorrect
    |
 note: function defined here
   --> $DIR/as-ref.rs:3:4
    |
 LL | fn takes_ref(_: &Foo) {}
    |    ^^^^^^^^^ -------
+help: consider using `as_ref` instead
+   |
+LL |     opt.as_ref().map(|arg| takes_ref(arg));
+   |         +++++++++
 
 error[E0308]: mismatched types
   --> $DIR/as-ref.rs:11:37
    |
 LL |     opt.and_then(|arg| Ok(takes_ref(arg)));
-   |         --------          --------- ^^^ expected `&Foo`, found `Foo`
-   |         |                 |
-   |         |                 arguments to this function are incorrect
-   |         help: consider using `as_ref` instead: `as_ref().and_then`
+   |                           --------- ^^^ expected `&Foo`, found `Foo`
+   |                           |
+   |                           arguments to this function are incorrect
    |
 note: function defined here
   --> $DIR/as-ref.rs:3:4
    |
 LL | fn takes_ref(_: &Foo) {}
    |    ^^^^^^^^^ -------
+help: consider using `as_ref` instead
+   |
+LL |     opt.as_ref().and_then(|arg| Ok(takes_ref(arg)));
+   |         +++++++++
 
 error[E0308]: mismatched types
   --> $DIR/as-ref.rs:13:29
@@ -101,61 +113,73 @@ error[E0308]: mismatched types
   --> $DIR/as-ref.rs:22:42
    |
 LL |     multiple_ref_opt.map(|arg| takes_ref(arg));
-   |                      ---       --------- ^^^ expected `&Foo`, found `Foo`
-   |                      |         |
-   |                      |         arguments to this function are incorrect
-   |                      help: consider using `as_ref` instead: `as_ref().map`
+   |                                --------- ^^^ expected `&Foo`, found `Foo`
+   |                                |
+   |                                arguments to this function are incorrect
    |
 note: function defined here
   --> $DIR/as-ref.rs:3:4
    |
 LL | fn takes_ref(_: &Foo) {}
    |    ^^^^^^^^^ -------
+help: consider using `as_ref` instead
+   |
+LL |     multiple_ref_opt.as_ref().map(|arg| takes_ref(arg));
+   |                      +++++++++
 
 error[E0308]: mismatched types
   --> $DIR/as-ref.rs:23:52
    |
 LL |     multiple_ref_opt.and_then(|arg| Some(takes_ref(arg)));
-   |                      --------            --------- ^^^ expected `&Foo`, found `Foo`
-   |                      |                   |
-   |                      |                   arguments to this function are incorrect
-   |                      help: consider using `as_ref` instead: `as_ref().and_then`
+   |                                          --------- ^^^ expected `&Foo`, found `Foo`
+   |                                          |
+   |                                          arguments to this function are incorrect
    |
 note: function defined here
   --> $DIR/as-ref.rs:3:4
    |
 LL | fn takes_ref(_: &Foo) {}
    |    ^^^^^^^^^ -------
+help: consider using `as_ref` instead
+   |
+LL |     multiple_ref_opt.as_ref().and_then(|arg| Some(takes_ref(arg)));
+   |                      +++++++++
 
 error[E0308]: mismatched types
   --> $DIR/as-ref.rs:25:45
    |
 LL |     multiple_ref_result.map(|arg| takes_ref(arg));
-   |                         ---       --------- ^^^ expected `&Foo`, found `Foo`
-   |                         |         |
-   |                         |         arguments to this function are incorrect
-   |                         help: consider using `as_ref` instead: `as_ref().map`
+   |                                   --------- ^^^ expected `&Foo`, found `Foo`
+   |                                   |
+   |                                   arguments to this function are incorrect
    |
 note: function defined here
   --> $DIR/as-ref.rs:3:4
    |
 LL | fn takes_ref(_: &Foo) {}
    |    ^^^^^^^^^ -------
+help: consider using `as_ref` instead
+   |
+LL |     multiple_ref_result.as_ref().map(|arg| takes_ref(arg));
+   |                         +++++++++
 
 error[E0308]: mismatched types
   --> $DIR/as-ref.rs:26:53
    |
 LL |     multiple_ref_result.and_then(|arg| Ok(takes_ref(arg)));
-   |                         --------          --------- ^^^ expected `&Foo`, found `Foo`
-   |                         |                 |
-   |                         |                 arguments to this function are incorrect
-   |                         help: consider using `as_ref` instead: `as_ref().and_then`
+   |                                           --------- ^^^ expected `&Foo`, found `Foo`
+   |                                           |
+   |                                           arguments to this function are incorrect
    |
 note: function defined here
   --> $DIR/as-ref.rs:3:4
    |
 LL | fn takes_ref(_: &Foo) {}
    |    ^^^^^^^^^ -------
+help: consider using `as_ref` instead
+   |
+LL |     multiple_ref_result.as_ref().and_then(|arg| Ok(takes_ref(arg)));
+   |                         +++++++++
 
 error: aborting due to 11 previous errors
 
diff --git a/tests/ui/suggestions/suggest-ref-macro.rs b/tests/ui/suggestions/suggest-ref-macro.rs
index 6f780f32a14..730f5fa1b5e 100644
--- a/tests/ui/suggestions/suggest-ref-macro.rs
+++ b/tests/ui/suggestions/suggest-ref-macro.rs
@@ -14,7 +14,7 @@ macro_rules! bla {
     () => {
         x(123);
         //~^ ERROR mismatched types
-        //~| SUGGESTION &mut 123
+        //~| SUGGESTION &mut
     };
     ($v:expr) => {
         x($v)
@@ -25,5 +25,5 @@ fn main() {
     bla!();
     bla!(456);
     //~^ ERROR mismatched types
-    //~| SUGGESTION &mut 456
+    //~| SUGGESTION &mut
 }
diff --git a/tests/ui/suggestions/suggest-ref-macro.stderr b/tests/ui/suggestions/suggest-ref-macro.stderr
index 17de49fbd84..08bc9e86a50 100644
--- a/tests/ui/suggestions/suggest-ref-macro.stderr
+++ b/tests/ui/suggestions/suggest-ref-macro.stderr
@@ -18,10 +18,8 @@ error[E0308]: mismatched types
   --> $DIR/suggest-ref-macro.rs:15:11
    |
 LL |         x(123);
-   |         - ^^^
-   |         | |
-   |         | expected `&mut i32`, found integer
-   |         | help: consider mutably borrowing here: `&mut 123`
+   |         - ^^^ expected `&mut i32`, found integer
+   |         |
    |         arguments to this function are incorrect
 ...
 LL |     bla!();
@@ -33,6 +31,10 @@ note: function defined here
 LL | fn x(_: &mut i32) {}
    |    ^ -----------
    = note: this error originates in the macro `bla` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider mutably borrowing here
+   |
+LL |         x(&mut 123);
+   |           ++++
 
 error[E0308]: mismatched types
   --> $DIR/suggest-ref-macro.rs:26:10
@@ -41,16 +43,17 @@ LL |         x($v)
    |         - arguments to this function are incorrect
 ...
 LL |     bla!(456);
-   |          ^^^
-   |          |
-   |          expected `&mut i32`, found integer
-   |          help: consider mutably borrowing here: `&mut 456`
+   |          ^^^ expected `&mut i32`, found integer
    |
 note: function defined here
   --> $DIR/suggest-ref-macro.rs:11:4
    |
 LL | fn x(_: &mut i32) {}
    |    ^ -----------
+help: consider mutably borrowing here
+   |
+LL |     bla!(&mut 456);
+   |          ++++
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/type/type-mismatch.stderr b/tests/ui/type/type-mismatch.stderr
index 67a1f893050..ce6f29d354f 100644
--- a/tests/ui/type/type-mismatch.stderr
+++ b/tests/ui/type/type-mismatch.stderr
@@ -378,10 +378,8 @@ error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:47:23
    |
 LL |     want::<&Foo<foo>>(f);
-   |     ----------------- ^
-   |     |                 |
-   |     |                 expected `&Foo<foo>`, found `Foo<foo>`
-   |     |                 help: consider borrowing here: `&f`
+   |     ----------------- ^ expected `&Foo<foo>`, found `Foo<foo>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&Foo<foo>`
@@ -391,6 +389,10 @@ note: function defined here
    |
 LL | fn want<T>(t: T) {}
    |    ^^^^    ----
+help: consider borrowing here
+   |
+LL |     want::<&Foo<foo>>(&f);
+   |                       +
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:48:26
@@ -556,10 +558,8 @@ error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:61:26
    |
 LL |     want::<&Foo<foo, B>>(f);
-   |     -------------------- ^
-   |     |                    |
-   |     |                    expected `&Foo<foo, B>`, found `Foo<foo, B>`
-   |     |                    help: consider borrowing here: `&f`
+   |     -------------------- ^ expected `&Foo<foo, B>`, found `Foo<foo, B>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&Foo<foo, B>`
@@ -569,6 +569,10 @@ note: function defined here
    |
 LL | fn want<T>(t: T) {}
    |    ^^^^    ----
+help: consider borrowing here
+   |
+LL |     want::<&Foo<foo, B>>(&f);
+   |                          +
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:65:19
diff --git a/tests/ui/typeck/bad-index-due-to-nested.stderr b/tests/ui/typeck/bad-index-due-to-nested.stderr
index cdb23372c4b..f9cdb280e27 100644
--- a/tests/ui/typeck/bad-index-due-to-nested.stderr
+++ b/tests/ui/typeck/bad-index-due-to-nested.stderr
@@ -42,13 +42,14 @@ error[E0308]: mismatched types
 LL | fn index<'a, K, V>(map: &'a HashMap<K, V>, k: K) -> &'a V {
    |              - this type parameter
 LL |     map[k]
-   |         ^
-   |         |
-   |         expected `&K`, found type parameter `K`
-   |         help: consider borrowing here: `&k`
+   |         ^ expected `&K`, found type parameter `K`
    |
    = note:   expected reference `&K`
            found type parameter `K`
+help: consider borrowing here
+   |
+LL |     map[&k]
+   |         +
 
 error[E0308]: mismatched types
   --> $DIR/bad-index-due-to-nested.rs:20:5
@@ -56,13 +57,14 @@ error[E0308]: mismatched types
 LL | fn index<'a, K, V>(map: &'a HashMap<K, V>, k: K) -> &'a V {
    |                 - this type parameter               ----- expected `&'a V` because of return type
 LL |     map[k]
-   |     ^^^^^^
-   |     |
-   |     expected `&V`, found type parameter `V`
-   |     help: consider borrowing here: `&map[k]`
+   |     ^^^^^^ expected `&V`, found type parameter `V`
    |
    = note:   expected reference `&'a V`
            found type parameter `V`
+help: consider borrowing here
+   |
+LL |     &map[k]
+   |     +
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/typeck/bad-type-in-vec-contains.stderr b/tests/ui/typeck/bad-type-in-vec-contains.stderr
index 72533ab1fa3..b9b3a5fe5ec 100644
--- a/tests/ui/typeck/bad-type-in-vec-contains.stderr
+++ b/tests/ui/typeck/bad-type-in-vec-contains.stderr
@@ -2,16 +2,18 @@ error[E0308]: mismatched types
   --> $DIR/bad-type-in-vec-contains.rs:5:21
    |
 LL |     primes.contains(3);
-   |            -------- ^
-   |            |        |
-   |            |        expected `&_`, found integer
-   |            |        help: consider borrowing here: `&3`
+   |            -------- ^ expected `&_`, found integer
+   |            |
    |            arguments to this method are incorrect
    |
    = note: expected reference `&_`
                    found type `{integer}`
 note: method defined here
   --> $SRC_DIR/core/src/slice/mod.rs:LL:COL
+help: consider borrowing here
+   |
+LL |     primes.contains(&3);
+   |                     +
 
 error: aborting due to previous error
 
diff --git a/tests/ui/typeck/issue-13853.stderr b/tests/ui/typeck/issue-13853.stderr
index 11d34f5b93b..8ecb8b68016 100644
--- a/tests/ui/typeck/issue-13853.stderr
+++ b/tests/ui/typeck/issue-13853.stderr
@@ -20,10 +20,8 @@ error[E0308]: mismatched types
   --> $DIR/issue-13853.rs:37:13
    |
 LL |     iterate(graph);
-   |     ------- ^^^^^
-   |     |       |
-   |     |       expected `&_`, found `Vec<Stuff>`
-   |     |       help: consider borrowing here: `&graph`
+   |     ------- ^^^^^ expected `&_`, found `Vec<Stuff>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -33,6 +31,10 @@ note: function defined here
    |
 LL | fn iterate<N: Node, G: Graph<N>>(graph: &G) {
    |    ^^^^^^^                       ---------
+help: consider borrowing here
+   |
+LL |     iterate(&graph);
+   |             +
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/unsized-locals/suggest-borrow.stderr b/tests/ui/unsized-locals/suggest-borrow.stderr
index d456c16de0d..8741b35cdcf 100644
--- a/tests/ui/unsized-locals/suggest-borrow.stderr
+++ b/tests/ui/unsized-locals/suggest-borrow.stderr
@@ -16,11 +16,14 @@ error[E0308]: mismatched types
   --> $DIR/suggest-borrow.rs:3:20
    |
 LL |     let x: &[u8] = vec!(1, 2, 3)[..];
-   |            -----   ^^^^^^^^^^^^^^^^^
-   |            |       |
-   |            |       expected `&[u8]`, found `[{integer}]`
-   |            |       help: consider borrowing here: `&vec!(1, 2, 3)[..]`
+   |            -----   ^^^^^^^^^^^^^^^^^ expected `&[u8]`, found `[{integer}]`
+   |            |
    |            expected due to this
+   |
+help: consider borrowing here
+   |
+LL |     let x: &[u8] = &vec!(1, 2, 3)[..];
+   |                    +
 
 error[E0308]: mismatched types
   --> $DIR/suggest-borrow.rs:4:19