about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-01-02 07:30:23 +0000
committerbors <bors@rust-lang.org>2023-01-02 07:30:23 +0000
commitd5a7ddd99f5e43116ec452777f08fddbde7f42fd (patch)
tree3061e2a9858a21c04f33f95129da18893295cdcc
parentc5cb156caa27655bc8dcf135de4d026ac4b25a4a (diff)
parent545406528a229f24844305b1a925cd6c743ea8ed (diff)
downloadrust-d5a7ddd99f5e43116ec452777f08fddbde7f42fd.tar.gz
rust-d5a7ddd99f5e43116ec452777f08fddbde7f42fd.zip
Auto merge of #106284 - estebank:merge-mut-errors, r=jyn514
Merge multiple mutable borrows of immutable binding errors

Fix #53466.
-rw-r--r--compiler/rustc_borrowck/src/borrowck_errors.rs28
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs90
-rw-r--r--compiler/rustc_borrowck/src/lib.rs24
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs4
-rw-r--r--compiler/rustc_expand/src/mbe/diagnostics.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs2
-rw-r--r--src/test/ui/asm/aarch64/type-check-2-2.rs4
-rw-r--r--src/test/ui/asm/aarch64/type-check-2-2.stderr22
-rw-r--r--src/test/ui/asm/x86_64/type-check-5.rs3
-rw-r--r--src/test/ui/asm/x86_64/type-check-5.stderr24
-rw-r--r--src/test/ui/async-await/issue-61452.stderr7
-rw-r--r--src/test/ui/async-await/issues/issue-61187.stderr7
-rw-r--r--src/test/ui/augmented-assignments.rs2
-rw-r--r--src/test/ui/augmented-assignments.stderr8
-rw-r--r--src/test/ui/borrowck/borrow-raw-address-of-mutability.stderr14
-rw-r--r--src/test/ui/borrowck/borrowck-access-permissions.stderr16
-rw-r--r--src/test/ui/borrowck/borrowck-argument.stderr30
-rw-r--r--src/test/ui/borrowck/borrowck-auto-mut-ref-to-immut-var.stderr7
-rw-r--r--src/test/ui/borrowck/borrowck-borrow-from-owned-ptr.stderr7
-rw-r--r--src/test/ui/borrowck/borrowck-borrow-from-stack-variable.stderr7
-rw-r--r--src/test/ui/borrowck/borrowck-borrow-immut-deref-of-box-as-mut.stderr7
-rw-r--r--src/test/ui/borrowck/borrowck-mut-addr-of-imm-var.stderr7
-rw-r--r--src/test/ui/borrowck/borrowck-mut-slice-of-imm-vec.stderr7
-rw-r--r--src/test/ui/borrowck/borrowck-overloaded-call.stderr8
-rw-r--r--src/test/ui/borrowck/borrowck-ref-mut-of-imm.stderr8
-rw-r--r--src/test/ui/borrowck/borrowck-unboxed-closures.stderr7
-rw-r--r--src/test/ui/borrowck/immut-function-arguments.stderr16
-rw-r--r--src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out.stderr48
-rw-r--r--src/test/ui/borrowck/many-mutable-borrows.rs18
-rw-r--r--src/test/ui/borrowck/many-mutable-borrows.stderr33
-rw-r--r--src/test/ui/borrowck/mut-borrow-of-mut-ref.rs9
-rw-r--r--src/test/ui/borrowck/mut-borrow-of-mut-ref.stderr30
-rw-r--r--src/test/ui/borrowck/mutability-errors.rs6
-rw-r--r--src/test/ui/borrowck/mutability-errors.stderr22
-rw-r--r--src/test/ui/borrowck/reassignment_immutable_fields_overlapping.stderr8
-rw-r--r--src/test/ui/borrowck/reassignment_immutable_fields_twice.stderr8
-rw-r--r--src/test/ui/closures/issue-80313-mutable-borrow-in-closure.stderr7
-rw-r--r--src/test/ui/closures/issue-80313-mutable-borrow-in-move-closure.stderr7
-rw-r--r--src/test/ui/closures/issue-80313-mutation-in-closure.stderr7
-rw-r--r--src/test/ui/closures/issue-80313-mutation-in-move-closure.stderr7
-rw-r--r--src/test/ui/closures/issue-81700-mut-borrow.stderr9
-rw-r--r--src/test/ui/closures/issue-82438-mut-without-upvar.stderr8
-rw-r--r--src/test/ui/closures/issue-84044-drop-non-mut.stderr7
-rw-r--r--src/test/ui/codemap_tests/huge_multispan_highlight.stderr8
-rw-r--r--src/test/ui/did_you_mean/issue-35937.stderr21
-rw-r--r--src/test/ui/did_you_mean/issue-39544.stderr14
-rw-r--r--src/test/ui/error-codes/E0596.stderr7
-rw-r--r--src/test/ui/issues/issue-36400.stderr7
-rw-r--r--src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.stderr7
-rw-r--r--src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.stderr7
-rw-r--r--src/test/ui/macros/span-covering-argument-1.stderr6
-rw-r--r--src/test/ui/mut/mut-suggestion.rs4
-rw-r--r--src/test/ui/mut/mut-suggestion.stderr16
-rw-r--r--src/test/ui/mut/mutable-class-fields.stderr7
-rw-r--r--src/test/ui/nll/issue-51191.stderr7
-rw-r--r--src/test/ui/pattern/bindings-after-at/nested-binding-modes-mut.stderr16
-rw-r--r--src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr28
-rw-r--r--src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr14
-rw-r--r--src/test/ui/span/borrowck-object-mutability.stderr8
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.stderr7
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-missing-mut.stderr9
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-move-missing-mut.stderr9
-rw-r--r--src/test/ui/writing-to-immutable-vec.stderr7
63 files changed, 547 insertions, 266 deletions
diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs
index 01be379120d..e4942f9b666 100644
--- a/compiler/rustc_borrowck/src/borrowck_errors.rs
+++ b/compiler/rustc_borrowck/src/borrowck_errors.rs
@@ -12,7 +12,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         place: &str,
         borrow_place: &str,
         value_place: &str,
-    ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
+    ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
         self.infcx.tcx.sess.create_err(crate::session_diagnostics::MoveBorrow {
             place,
             span,
@@ -28,7 +28,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         desc: &str,
         borrow_span: Span,
         borrow_desc: &str,
-    ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
+    ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
         let mut err = struct_span_err!(
             self,
             span,
@@ -50,7 +50,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         old_loan_span: Span,
         old_opt_via: &str,
         old_load_end_span: Option<Span>,
-    ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
+    ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
         let via =
             |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {})", msg) };
         let mut err = struct_span_err!(
@@ -98,7 +98,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         desc: &str,
         old_loan_span: Span,
         old_load_end_span: Option<Span>,
-    ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
+    ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
         let mut err = struct_span_err!(
             self,
             new_loan_span,
@@ -269,7 +269,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         &self,
         span: Span,
         desc: &str,
-    ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
+    ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
         struct_span_err!(self, span, E0594, "cannot assign to {}", desc)
     }
 
@@ -348,7 +348,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         span: Span,
         path: &str,
         reason: &str,
-    ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
+    ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
         struct_span_err!(self, span, E0596, "cannot borrow {} as mutable{}", path, reason,)
     }
 
@@ -359,7 +359,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         immutable_place: &str,
         immutable_section: &str,
         action: &str,
-    ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
+    ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
         let mut err = struct_span_err!(
             self,
             mutate_span,
@@ -378,7 +378,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         &self,
         span: Span,
         yield_span: Span,
-    ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
+    ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
         let mut err = struct_span_err!(
             self,
             span,
@@ -392,7 +392,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
     pub(crate) fn cannot_borrow_across_destructor(
         &self,
         borrow_span: Span,
-    ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
+    ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
         struct_span_err!(
             self,
             borrow_span,
@@ -405,7 +405,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         &self,
         span: Span,
         path: &str,
-    ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
+    ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
         struct_span_err!(self, span, E0597, "{} does not live long enough", path,)
     }
 
@@ -415,7 +415,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         return_kind: &str,
         reference_desc: &str,
         path_desc: &str,
-    ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
+    ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
         let mut err = struct_span_err!(
             self,
             span,
@@ -440,7 +440,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         closure_kind: &str,
         borrowed_path: &str,
         capture_span: Span,
-    ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
+    ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
         let mut err = struct_span_err!(
             self,
             closure_span,
@@ -458,14 +458,14 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
     pub(crate) fn thread_local_value_does_not_live_long_enough(
         &self,
         span: Span,
-    ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
+    ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
         struct_span_err!(self, span, E0712, "thread-local variable borrowed past end of function",)
     }
 
     pub(crate) fn temporary_value_borrowed_for_too_long(
         &self,
         span: Span,
-    ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
+    ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
         struct_span_err!(self, span, E0716, "temporary value dropped while borrowed",)
     }
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index 99ca4c637bd..6f6d1b01bd4 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -180,6 +180,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         // the verbs used in some diagnostic messages.
         let act;
         let acted_on;
+        let mut suggest = true;
+        let mut mut_error = None;
+        let mut count = 1;
 
         let span = match error_access {
             AccessKind::Mutate => {
@@ -194,15 +197,50 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
 
                 let borrow_spans = self.borrow_spans(span, location);
                 let borrow_span = borrow_spans.args_or_use();
-                err = self.cannot_borrow_path_as_mutable_because(borrow_span, &item_msg, &reason);
-                borrow_spans.var_span_label(
-                    &mut err,
-                    format!(
-                        "mutable borrow occurs due to use of {} in closure",
-                        self.describe_any_place(access_place.as_ref()),
-                    ),
-                    "mutable",
-                );
+                match the_place_err {
+                    PlaceRef { local, projection: [] }
+                        if self.body.local_decls[local].can_be_made_mutable() =>
+                    {
+                        let span = self.body.local_decls[local].source_info.span;
+                        mut_error = Some(span);
+                        if let Some((buffer, c)) = self.get_buffered_mut_error(span) {
+                            // We've encountered a second (or more) attempt to mutably borrow an
+                            // immutable binding, so the likely problem is with the binding
+                            // declaration, not the use. We collect these in a single diagnostic
+                            // and make the binding the primary span of the error.
+                            err = buffer;
+                            count = c + 1;
+                            if count == 2 {
+                                err.replace_span_with(span, false);
+                                err.span_label(span, "not mutable");
+                            }
+                            suggest = false;
+                        } else {
+                            err = self.cannot_borrow_path_as_mutable_because(
+                                borrow_span,
+                                &item_msg,
+                                &reason,
+                            );
+                        }
+                    }
+                    _ => {
+                        err = self.cannot_borrow_path_as_mutable_because(
+                            borrow_span,
+                            &item_msg,
+                            &reason,
+                        );
+                    }
+                }
+                if suggest {
+                    borrow_spans.var_span_label(
+                        &mut err,
+                        format!(
+                            "mutable borrow occurs due to use of {} in closure",
+                            self.describe_any_place(access_place.as_ref()),
+                        ),
+                        "mutable",
+                    );
+                }
                 borrow_span
             }
         };
@@ -276,7 +314,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                                 pat_span: _,
                             },
                         )))) => {
-                            err.span_note(sp, "the binding is already a mutable borrow");
+                            if suggest {
+                                err.span_note(sp, "the binding is already a mutable borrow");
+                            }
                         }
                         _ => {
                             err.span_note(
@@ -333,16 +373,20 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                 let local_decl = &self.body.local_decls[local];
                 assert_eq!(local_decl.mutability, Mutability::Not);
 
-                err.span_label(span, format!("cannot {act}"));
-                err.span_suggestion(
-                    local_decl.source_info.span,
-                    "consider changing this to be mutable",
-                    format!("mut {}", self.local_names[local].unwrap()),
-                    Applicability::MachineApplicable,
-                );
-                let tcx = self.infcx.tcx;
-                if let ty::Closure(id, _) = *the_place_err.ty(self.body, tcx).ty.kind() {
-                    self.show_mutating_upvar(tcx, id.expect_local(), the_place_err, &mut err);
+                if count < 10 {
+                    err.span_label(span, format!("cannot {act}"));
+                }
+                if suggest {
+                    err.span_suggestion_verbose(
+                        local_decl.source_info.span.shrink_to_lo(),
+                        "consider changing this to be mutable",
+                        "mut ".to_string(),
+                        Applicability::MachineApplicable,
+                    );
+                    let tcx = self.infcx.tcx;
+                    if let ty::Closure(id, _) = *the_place_err.ty(self.body, tcx).ty.kind() {
+                        self.show_mutating_upvar(tcx, id.expect_local(), the_place_err, &mut err);
+                    }
                 }
             }
 
@@ -615,7 +659,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             }
         }
 
-        self.buffer_error(err);
+        if let Some(span) = mut_error {
+            self.buffer_mut_error(span, err, count);
+        } else {
+            self.buffer_error(err);
+        }
     }
 
     fn suggest_map_index_mut_alternatives(&self, ty: Ty<'tcx>, err: &mut Diagnostic, span: Span) {
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 168b798788b..ae1bea008b6 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -2270,6 +2270,7 @@ mod error {
         /// same primary span come out in a consistent order.
         buffered_move_errors:
             BTreeMap<Vec<MoveOutIndex>, (PlaceRef<'tcx>, DiagnosticBuilder<'tcx, ErrorGuaranteed>)>,
+        buffered_mut_errors: FxHashMap<Span, (DiagnosticBuilder<'tcx, ErrorGuaranteed>, usize)>,
         /// Diagnostics to be reported buffer.
         buffered: Vec<Diagnostic>,
         /// Set to Some if we emit an error during borrowck
@@ -2281,6 +2282,7 @@ mod error {
             BorrowckErrors {
                 tcx,
                 buffered_move_errors: BTreeMap::new(),
+                buffered_mut_errors: Default::default(),
                 buffered: Default::default(),
                 tainted_by_errors: None,
             }
@@ -2331,12 +2333,34 @@ mod error {
             }
         }
 
+        pub fn get_buffered_mut_error(
+            &mut self,
+            span: Span,
+        ) -> Option<(DiagnosticBuilder<'tcx, ErrorGuaranteed>, usize)> {
+            self.errors.buffered_mut_errors.remove(&span)
+        }
+
+        pub fn buffer_mut_error(
+            &mut self,
+            span: Span,
+            t: DiagnosticBuilder<'tcx, ErrorGuaranteed>,
+            count: usize,
+        ) {
+            self.errors.buffered_mut_errors.insert(span, (t, count));
+        }
+
         pub fn emit_errors(&mut self) -> Option<ErrorGuaranteed> {
             // Buffer any move errors that we collected and de-duplicated.
             for (_, (_, diag)) in std::mem::take(&mut self.errors.buffered_move_errors) {
                 // We have already set tainted for this error, so just buffer it.
                 diag.buffer(&mut self.errors.buffered);
             }
+            for (_, (mut diag, count)) in std::mem::take(&mut self.errors.buffered_mut_errors) {
+                if count > 10 {
+                    diag.note(&format!("...and {} other attempted mutable borrows", count - 10));
+                }
+                diag.buffer(&mut self.errors.buffered);
+            }
 
             if !self.errors.buffered.is_empty() {
                 self.errors.buffered.sort_by_key(|diag| diag.sort_span);
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 585a54308c6..e19a6fe0ee9 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -365,12 +365,12 @@ impl Diagnostic {
         self
     }
 
-    pub fn replace_span_with(&mut self, after: Span) -> &mut Self {
+    pub fn replace_span_with(&mut self, after: Span, keep_label: bool) -> &mut Self {
         let before = self.span.clone();
         self.set_span(after);
         for span_label in before.span_labels() {
             if let Some(label) = span_label.label {
-                if span_label.is_primary {
+                if span_label.is_primary && keep_label {
                     self.span.push_span_label(after, label);
                 } else {
                     self.span.push_span_label(span_label.span, label);
diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs
index 40aa64d9d40..3a38d7a9669 100644
--- a/compiler/rustc_expand/src/mbe/diagnostics.rs
+++ b/compiler/rustc_expand/src/mbe/diagnostics.rs
@@ -198,12 +198,12 @@ pub(super) fn emit_frag_parse_err(
         );
         if !e.span.is_dummy() {
             // early end of macro arm (#52866)
-            e.replace_span_with(parser.token.span.shrink_to_hi());
+            e.replace_span_with(parser.token.span.shrink_to_hi(), true);
         }
     }
     if e.span.is_dummy() {
         // Get around lack of span in error (#30128)
-        e.replace_span_with(site_span);
+        e.replace_span_with(site_span, true);
         if !parser.sess.source_map().is_imported(arm_span) {
             e.span_label(arm_span, "in this macro arm");
         }
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 06ab0e8d944..7c21a1047bc 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -3237,7 +3237,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         })) = call_node
         {
             if Some(rcvr.span) == err.span.primary_span() {
-                err.replace_span_with(path.ident.span);
+                err.replace_span_with(path.ident.span, true);
             }
         }
         if let Some(Node::Expr(hir::Expr {
diff --git a/src/test/ui/asm/aarch64/type-check-2-2.rs b/src/test/ui/asm/aarch64/type-check-2-2.rs
index 0ce1f1d8f7f..89f2b3bb7d0 100644
--- a/src/test/ui/asm/aarch64/type-check-2-2.rs
+++ b/src/test/ui/asm/aarch64/type-check-2-2.rs
@@ -25,12 +25,10 @@ fn main() {
 
         // Outputs require mutable places
 
-        let v: Vec<u64> = vec![0, 1, 2];
+        let v: Vec<u64> = vec![0, 1, 2]; //~ ERROR cannot borrow `v` as mutable
         asm!("{}", in(reg) v[0]);
         asm!("{}", out(reg) v[0]);
-        //~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable
         asm!("{}", inout(reg) v[0]);
-        //~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable
 
         // Sym operands must point to a function or static
     }
diff --git a/src/test/ui/asm/aarch64/type-check-2-2.stderr b/src/test/ui/asm/aarch64/type-check-2-2.stderr
index eef16a165a8..41f7c01dc82 100644
--- a/src/test/ui/asm/aarch64/type-check-2-2.stderr
+++ b/src/test/ui/asm/aarch64/type-check-2-2.stderr
@@ -25,24 +25,22 @@ LL |         let mut y: u64 = 0;
    |                        +++
 
 error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
-  --> $DIR/type-check-2-2.rs:30:29
+  --> $DIR/type-check-2-2.rs:28:13
    |
 LL |         let v: Vec<u64> = vec![0, 1, 2];
-   |             - help: consider changing this to be mutable: `mut v`
+   |             ^ not mutable
 LL |         asm!("{}", in(reg) v[0]);
 LL |         asm!("{}", out(reg) v[0]);
-   |                             ^ cannot borrow as mutable
-
-error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
-  --> $DIR/type-check-2-2.rs:32:31
-   |
-LL |         let v: Vec<u64> = vec![0, 1, 2];
-   |             - help: consider changing this to be mutable: `mut v`
-...
+   |                             - cannot borrow as mutable
 LL |         asm!("{}", inout(reg) v[0]);
-   |                               ^ cannot borrow as mutable
+   |                               - cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |         let mut v: Vec<u64> = vec![0, 1, 2];
+   |             +++
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0381, E0596.
 For more information about an error, try `rustc --explain E0381`.
diff --git a/src/test/ui/asm/x86_64/type-check-5.rs b/src/test/ui/asm/x86_64/type-check-5.rs
index 8198df91095..1d579ccc90e 100644
--- a/src/test/ui/asm/x86_64/type-check-5.rs
+++ b/src/test/ui/asm/x86_64/type-check-5.rs
@@ -22,11 +22,10 @@ fn main() {
         // Outputs require mutable places
 
         let v: Vec<u64> = vec![0, 1, 2];
+        //~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable
         asm!("{}", in(reg) v[0]);
         asm!("{}", out(reg) v[0]);
-        //~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable
         asm!("{}", inout(reg) v[0]);
-        //~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable
 
         // Sym operands must point to a function or static
 
diff --git a/src/test/ui/asm/x86_64/type-check-5.stderr b/src/test/ui/asm/x86_64/type-check-5.stderr
index bd90461e52c..7970e76d6a1 100644
--- a/src/test/ui/asm/x86_64/type-check-5.stderr
+++ b/src/test/ui/asm/x86_64/type-check-5.stderr
@@ -25,24 +25,22 @@ LL |         let mut y: u64 = 0;
    |                        +++
 
 error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
-  --> $DIR/type-check-5.rs:26:29
+  --> $DIR/type-check-5.rs:24:13
    |
 LL |         let v: Vec<u64> = vec![0, 1, 2];
-   |             - help: consider changing this to be mutable: `mut v`
-LL |         asm!("{}", in(reg) v[0]);
-LL |         asm!("{}", out(reg) v[0]);
-   |                             ^ cannot borrow as mutable
-
-error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
-  --> $DIR/type-check-5.rs:28:31
-   |
-LL |         let v: Vec<u64> = vec![0, 1, 2];
-   |             - help: consider changing this to be mutable: `mut v`
+   |             ^ not mutable
 ...
+LL |         asm!("{}", out(reg) v[0]);
+   |                             - cannot borrow as mutable
 LL |         asm!("{}", inout(reg) v[0]);
-   |                               ^ cannot borrow as mutable
+   |                               - cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |         let mut v: Vec<u64> = vec![0, 1, 2];
+   |             +++
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0381, E0596.
 For more information about an error, try `rustc --explain E0381`.
diff --git a/src/test/ui/async-await/issue-61452.stderr b/src/test/ui/async-await/issue-61452.stderr
index 2d3bb48e03b..bf504432880 100644
--- a/src/test/ui/async-await/issue-61452.stderr
+++ b/src/test/ui/async-await/issue-61452.stderr
@@ -1,10 +1,13 @@
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/issue-61452.rs:4:5
    |
-LL | pub async fn f(x: Option<usize>) {
-   |                - help: consider changing this to be mutable: `mut x`
 LL |     x.take();
    |     ^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL | pub async fn f(mut x: Option<usize>) {
+   |                +++
 
 error[E0384]: cannot assign twice to immutable variable `x`
   --> $DIR/issue-61452.rs:9:5
diff --git a/src/test/ui/async-await/issues/issue-61187.stderr b/src/test/ui/async-await/issues/issue-61187.stderr
index 163053471b5..e58f7454689 100644
--- a/src/test/ui/async-await/issues/issue-61187.stderr
+++ b/src/test/ui/async-await/issues/issue-61187.stderr
@@ -1,10 +1,13 @@
 error[E0596]: cannot borrow `data` as mutable, as it is not declared as mutable
   --> $DIR/issue-61187.rs:6:5
    |
-LL | async fn response(data: Vec<u8>) {
-   |                   ---- help: consider changing this to be mutable: `mut data`
 LL |     data.reverse();
    |     ^^^^^^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL | async fn response(mut data: Vec<u8>) {
+   |                   +++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/augmented-assignments.rs b/src/test/ui/augmented-assignments.rs
index 1b4ac6edcb0..20c7fb3a983 100644
--- a/src/test/ui/augmented-assignments.rs
+++ b/src/test/ui/augmented-assignments.rs
@@ -19,7 +19,7 @@ fn main() {
 
     let y = Int(2);
     //~^ HELP consider changing this to be mutable
-    //~| SUGGESTION mut y
+    //~| SUGGESTION mut
     y   //~ ERROR cannot borrow `y` as mutable, as it is not declared as mutable
         //~| cannot borrow as mutable
     +=
diff --git a/src/test/ui/augmented-assignments.stderr b/src/test/ui/augmented-assignments.stderr
index ce555da8975..2910c910d55 100644
--- a/src/test/ui/augmented-assignments.stderr
+++ b/src/test/ui/augmented-assignments.stderr
@@ -10,11 +10,13 @@ LL |     x;
 error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable
   --> $DIR/augmented-assignments.rs:23:5
    |
-LL |     let y = Int(2);
-   |         - help: consider changing this to be mutable: `mut y`
-...
 LL |     y
    |     ^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut y = Int(2);
+   |         +++
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/borrowck/borrow-raw-address-of-mutability.stderr b/src/test/ui/borrowck/borrow-raw-address-of-mutability.stderr
index 869375cb2c6..a7748209187 100644
--- a/src/test/ui/borrowck/borrow-raw-address-of-mutability.stderr
+++ b/src/test/ui/borrowck/borrow-raw-address-of-mutability.stderr
@@ -1,10 +1,13 @@
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/borrow-raw-address-of-mutability.rs:5:13
    |
-LL |     let x = 0;
-   |         - help: consider changing this to be mutable: `mut x`
 LL |     let y = &raw mut x;
    |             ^^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut x = 0;
+   |         +++
 
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/borrow-raw-address-of-mutability.rs:11:17
@@ -18,13 +21,16 @@ LL |         let y = &raw mut x;
 error[E0596]: cannot borrow `f` as mutable, as it is not declared as mutable
   --> $DIR/borrow-raw-address-of-mutability.rs:21:5
    |
-LL |     let f = || {
-   |         - help: consider changing this to be mutable: `mut f`
 LL |         let y = &raw mut x;
    |                          - calling `f` requires mutable binding due to mutable borrow of `x`
 LL |     };
 LL |     f();
    |     ^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut f = || {
+   |         +++
 
 error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
   --> $DIR/borrow-raw-address-of-mutability.rs:29:17
diff --git a/src/test/ui/borrowck/borrowck-access-permissions.stderr b/src/test/ui/borrowck/borrowck-access-permissions.stderr
index 31272089847..26f3e2bbdb7 100644
--- a/src/test/ui/borrowck/borrowck-access-permissions.stderr
+++ b/src/test/ui/borrowck/borrowck-access-permissions.stderr
@@ -1,11 +1,13 @@
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/borrowck-access-permissions.rs:9:19
    |
-LL |     let x = 1;
-   |         - help: consider changing this to be mutable: `mut x`
-...
 LL |         let _y1 = &mut x;
    |                   ^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut x = 1;
+   |         +++
 
 error[E0596]: cannot borrow immutable static item `static_x` as mutable
   --> $DIR/borrowck-access-permissions.rs:14:19
@@ -16,11 +18,13 @@ LL |         let _y1 = &mut static_x;
 error[E0596]: cannot borrow `*box_x` as mutable, as `box_x` is not declared as mutable
   --> $DIR/borrowck-access-permissions.rs:22:19
    |
-LL |         let box_x = Box::new(1);
-   |             ----- help: consider changing this to be mutable: `mut box_x`
-...
 LL |         let _y1 = &mut *box_x;
    |                   ^^^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |         let mut box_x = Box::new(1);
+   |             +++
 
 error[E0596]: cannot borrow `*ref_x` as mutable, as it is behind a `&` reference
   --> $DIR/borrowck-access-permissions.rs:30:19
diff --git a/src/test/ui/borrowck/borrowck-argument.stderr b/src/test/ui/borrowck/borrowck-argument.stderr
index d4d646e390c..1c992dfcceb 100644
--- a/src/test/ui/borrowck/borrowck-argument.stderr
+++ b/src/test/ui/borrowck/borrowck-argument.stderr
@@ -1,34 +1,46 @@
 error[E0596]: cannot borrow `arg` as mutable, as it is not declared as mutable
   --> $DIR/borrowck-argument.rs:10:5
    |
-LL | fn func(arg: S) {
-   |         --- help: consider changing this to be mutable: `mut arg`
 LL |     arg.mutate();
    |     ^^^^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL | fn func(mut arg: S) {
+   |         +++
 
 error[E0596]: cannot borrow `arg` as mutable, as it is not declared as mutable
   --> $DIR/borrowck-argument.rs:15:9
    |
-LL |     fn method(&self, arg: S) {
-   |                      --- help: consider changing this to be mutable: `mut arg`
 LL |         arg.mutate();
    |         ^^^^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     fn method(&self, mut arg: S) {
+   |                      +++
 
 error[E0596]: cannot borrow `arg` as mutable, as it is not declared as mutable
   --> $DIR/borrowck-argument.rs:21:9
    |
-LL |     fn default(&self, arg: S) {
-   |                       --- help: consider changing this to be mutable: `mut arg`
 LL |         arg.mutate();
    |         ^^^^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     fn default(&self, mut arg: S) {
+   |                       +++
 
 error[E0596]: cannot borrow `arg` as mutable, as it is not declared as mutable
   --> $DIR/borrowck-argument.rs:32:17
    |
 LL |     (|arg: S| { arg.mutate() })(s);
-   |       ---       ^^^^^^^^^^^^ cannot borrow as mutable
-   |       |
-   |       help: consider changing this to be mutable: `mut arg`
+   |                 ^^^^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     (|mut arg: S| { arg.mutate() })(s);
+   |       +++
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/borrowck/borrowck-auto-mut-ref-to-immut-var.stderr b/src/test/ui/borrowck/borrowck-auto-mut-ref-to-immut-var.stderr
index 186ecddd6d6..19ef0301a2d 100644
--- a/src/test/ui/borrowck/borrowck-auto-mut-ref-to-immut-var.stderr
+++ b/src/test/ui/borrowck/borrowck-auto-mut-ref-to-immut-var.stderr
@@ -1,10 +1,13 @@
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/borrowck-auto-mut-ref-to-immut-var.rs:15:5
    |
-LL |     let x = Foo { x: 3 };
-   |         - help: consider changing this to be mutable: `mut x`
 LL |     x.printme();
    |     ^^^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut x = Foo { x: 3 };
+   |         +++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-borrow-from-owned-ptr.stderr b/src/test/ui/borrowck/borrowck-borrow-from-owned-ptr.stderr
index e00d69f89d3..c2351aacdae 100644
--- a/src/test/ui/borrowck/borrowck-borrow-from-owned-ptr.stderr
+++ b/src/test/ui/borrowck/borrowck-borrow-from-owned-ptr.stderr
@@ -105,10 +105,13 @@ LL |     *bar1;
 error[E0596]: cannot borrow `foo.bar1` as mutable, as `foo` is not declared as mutable
   --> $DIR/borrowck-borrow-from-owned-ptr.rs:122:16
    |
-LL |     let foo = make_foo();
-   |         --- help: consider changing this to be mutable: `mut foo`
 LL |     let bar1 = &mut foo.bar1;
    |                ^^^^^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut foo = make_foo();
+   |         +++
 
 error: aborting due to 11 previous errors
 
diff --git a/src/test/ui/borrowck/borrowck-borrow-from-stack-variable.stderr b/src/test/ui/borrowck/borrowck-borrow-from-stack-variable.stderr
index ce5ce56dea2..8fcaaa883b2 100644
--- a/src/test/ui/borrowck/borrowck-borrow-from-stack-variable.stderr
+++ b/src/test/ui/borrowck/borrowck-borrow-from-stack-variable.stderr
@@ -105,10 +105,13 @@ LL |     *bar1;
 error[E0596]: cannot borrow `foo.bar1` as mutable, as `foo` is not declared as mutable
   --> $DIR/borrowck-borrow-from-stack-variable.rs:120:16
    |
-LL |     let foo = make_foo();
-   |         --- help: consider changing this to be mutable: `mut foo`
 LL |     let bar1 = &mut foo.bar1;
    |                ^^^^^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut foo = make_foo();
+   |         +++
 
 error: aborting due to 11 previous errors
 
diff --git a/src/test/ui/borrowck/borrowck-borrow-immut-deref-of-box-as-mut.stderr b/src/test/ui/borrowck/borrowck-borrow-immut-deref-of-box-as-mut.stderr
index 237071e16fc..3c28ff56e41 100644
--- a/src/test/ui/borrowck/borrowck-borrow-immut-deref-of-box-as-mut.stderr
+++ b/src/test/ui/borrowck/borrowck-borrow-immut-deref-of-box-as-mut.stderr
@@ -1,10 +1,13 @@
 error[E0596]: cannot borrow `*a` as mutable, as `a` is not declared as mutable
   --> $DIR/borrowck-borrow-immut-deref-of-box-as-mut.rs:12:5
    |
-LL |     let a: Box<_> = Box::new(A);
-   |         - help: consider changing this to be mutable: `mut a`
 LL |     a.foo();
    |     ^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut a: Box<_> = Box::new(A);
+   |         +++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-mut-addr-of-imm-var.stderr b/src/test/ui/borrowck/borrowck-mut-addr-of-imm-var.stderr
index d58548f2204..20528e3f0ee 100644
--- a/src/test/ui/borrowck/borrowck-mut-addr-of-imm-var.stderr
+++ b/src/test/ui/borrowck/borrowck-mut-addr-of-imm-var.stderr
@@ -1,10 +1,13 @@
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/borrowck-mut-addr-of-imm-var.rs:3:25
    |
-LL |     let x: isize = 3;
-   |         - help: consider changing this to be mutable: `mut x`
 LL |     let y: &mut isize = &mut x;
    |                         ^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut x: isize = 3;
+   |         +++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-mut-slice-of-imm-vec.stderr b/src/test/ui/borrowck/borrowck-mut-slice-of-imm-vec.stderr
index 8e7ffdc6819..8ab472e64c7 100644
--- a/src/test/ui/borrowck/borrowck-mut-slice-of-imm-vec.stderr
+++ b/src/test/ui/borrowck/borrowck-mut-slice-of-imm-vec.stderr
@@ -1,10 +1,13 @@
 error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
   --> $DIR/borrowck-mut-slice-of-imm-vec.rs:7:11
    |
-LL |     let v = vec![1, 2, 3];
-   |         - help: consider changing this to be mutable: `mut v`
 LL |     write(&mut v);
    |           ^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut v = vec![1, 2, 3];
+   |         +++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-overloaded-call.stderr b/src/test/ui/borrowck/borrowck-overloaded-call.stderr
index ddb63b5ec0f..723b19f4124 100644
--- a/src/test/ui/borrowck/borrowck-overloaded-call.stderr
+++ b/src/test/ui/borrowck/borrowck-overloaded-call.stderr
@@ -11,11 +11,13 @@ LL |     use_mut(sp);
 error[E0596]: cannot borrow `s` as mutable, as it is not declared as mutable
   --> $DIR/borrowck-overloaded-call.rs:67:5
    |
-LL |     let s = SFnMut {
-   |         - help: consider changing this to be mutable: `mut s`
-...
 LL |     s(3);
    |     ^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut s = SFnMut {
+   |         +++
 
 error[E0382]: use of moved value: `s`
   --> $DIR/borrowck-overloaded-call.rs:75:5
diff --git a/src/test/ui/borrowck/borrowck-ref-mut-of-imm.stderr b/src/test/ui/borrowck/borrowck-ref-mut-of-imm.stderr
index e744fc6b54b..5cfd81bd004 100644
--- a/src/test/ui/borrowck/borrowck-ref-mut-of-imm.stderr
+++ b/src/test/ui/borrowck/borrowck-ref-mut-of-imm.stderr
@@ -1,11 +1,13 @@
 error[E0596]: cannot borrow `x.0` as mutable, as `x` is not declared as mutable
   --> $DIR/borrowck-ref-mut-of-imm.rs:4:12
    |
-LL | fn destructure(x: Option<isize>) -> isize {
-   |                - help: consider changing this to be mutable: `mut x`
-...
 LL |       Some(ref mut v) => *v
    |            ^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL | fn destructure(mut x: Option<isize>) -> isize {
+   |                +++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-unboxed-closures.stderr b/src/test/ui/borrowck/borrowck-unboxed-closures.stderr
index d46ef126da4..3634676463c 100644
--- a/src/test/ui/borrowck/borrowck-unboxed-closures.stderr
+++ b/src/test/ui/borrowck/borrowck-unboxed-closures.stderr
@@ -11,10 +11,13 @@ LL |     use_mut(g);
 error[E0596]: cannot borrow `f` as mutable, as it is not declared as mutable
   --> $DIR/borrowck-unboxed-closures.rs:7:5
    |
-LL | fn b<F:FnMut(isize, isize) -> isize>(f: F) {
-   |                                      - help: consider changing this to be mutable: `mut f`
 LL |     f(1, 2);
    |     ^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL | fn b<F:FnMut(isize, isize) -> isize>(mut f: F) {
+   |                                      +++
 
 error[E0382]: use of moved value: `f`
   --> $DIR/borrowck-unboxed-closures.rs:12:5
diff --git a/src/test/ui/borrowck/immut-function-arguments.stderr b/src/test/ui/borrowck/immut-function-arguments.stderr
index 7238dd14433..d5392e7d66f 100644
--- a/src/test/ui/borrowck/immut-function-arguments.stderr
+++ b/src/test/ui/borrowck/immut-function-arguments.stderr
@@ -1,18 +1,24 @@
 error[E0594]: cannot assign to `*y`, as `y` is not declared as mutable
   --> $DIR/immut-function-arguments.rs:2:5
    |
-LL | fn f(y: Box<isize>) {
-   |      - help: consider changing this to be mutable: `mut y`
 LL |     *y = 5;
    |     ^^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL | fn f(mut y: Box<isize>) {
+   |      +++
 
 error[E0594]: cannot assign to `*q`, as `q` is not declared as mutable
   --> $DIR/immut-function-arguments.rs:6:35
    |
 LL |     let _frob = |q: Box<isize>| { *q = 2; };
-   |                  -                ^^^^^^ cannot assign
-   |                  |
-   |                  help: consider changing this to be mutable: `mut q`
+   |                                   ^^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |     let _frob = |mut q: Box<isize>| { *q = 2; };
+   |                  +++
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out.stderr b/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out.stderr
index b7623a54056..774b6cf0ea6 100644
--- a/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out.stderr
+++ b/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out.stderr
@@ -1,11 +1,13 @@
 error[E0594]: cannot assign to `t.0`, as `t` is not declared as mutable
   --> $DIR/issue-54499-field-mutation-of-moved-out.rs:13:9
    |
-LL |         let t: Tuple = (S(0), 0);
-   |             - help: consider changing this to be mutable: `mut t`
-LL |         drop(t);
 LL |         t.0 = S(1);
    |         ^^^^^^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |         let mut t: Tuple = (S(0), 0);
+   |             +++
 
 error[E0382]: assign to part of moved value: `t`
   --> $DIR/issue-54499-field-mutation-of-moved-out.rs:13:9
@@ -20,20 +22,24 @@ LL |         t.0 = S(1);
 error[E0594]: cannot assign to `t.1`, as `t` is not declared as mutable
   --> $DIR/issue-54499-field-mutation-of-moved-out.rs:16:9
    |
-LL |         let t: Tuple = (S(0), 0);
-   |             - help: consider changing this to be mutable: `mut t`
-...
 LL |         t.1 = 2;
    |         ^^^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |         let mut t: Tuple = (S(0), 0);
+   |             +++
 
 error[E0594]: cannot assign to `u.0`, as `u` is not declared as mutable
   --> $DIR/issue-54499-field-mutation-of-moved-out.rs:24:9
    |
-LL |         let u: Tpair = Tpair(S(0), 0);
-   |             - help: consider changing this to be mutable: `mut u`
-LL |         drop(u);
 LL |         u.0 = S(1);
    |         ^^^^^^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |         let mut u: Tpair = Tpair(S(0), 0);
+   |             +++
 
 error[E0382]: assign to part of moved value: `u`
   --> $DIR/issue-54499-field-mutation-of-moved-out.rs:24:9
@@ -48,20 +54,24 @@ LL |         u.0 = S(1);
 error[E0594]: cannot assign to `u.1`, as `u` is not declared as mutable
   --> $DIR/issue-54499-field-mutation-of-moved-out.rs:27:9
    |
-LL |         let u: Tpair = Tpair(S(0), 0);
-   |             - help: consider changing this to be mutable: `mut u`
-...
 LL |         u.1 = 2;
    |         ^^^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |         let mut u: Tpair = Tpair(S(0), 0);
+   |             +++
 
 error[E0594]: cannot assign to `v.x`, as `v` is not declared as mutable
   --> $DIR/issue-54499-field-mutation-of-moved-out.rs:35:9
    |
-LL |         let v: Spair = Spair { x: S(0), y: 0 };
-   |             - help: consider changing this to be mutable: `mut v`
-LL |         drop(v);
 LL |         v.x = S(1);
    |         ^^^^^^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |         let mut v: Spair = Spair { x: S(0), y: 0 };
+   |             +++
 
 error[E0382]: assign to part of moved value: `v`
   --> $DIR/issue-54499-field-mutation-of-moved-out.rs:35:9
@@ -76,11 +86,13 @@ LL |         v.x = S(1);
 error[E0594]: cannot assign to `v.y`, as `v` is not declared as mutable
   --> $DIR/issue-54499-field-mutation-of-moved-out.rs:38:9
    |
-LL |         let v: Spair = Spair { x: S(0), y: 0 };
-   |             - help: consider changing this to be mutable: `mut v`
-...
 LL |         v.y = 2;
    |         ^^^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |         let mut v: Spair = Spair { x: S(0), y: 0 };
+   |             +++
 
 error: aborting due to 9 previous errors
 
diff --git a/src/test/ui/borrowck/many-mutable-borrows.rs b/src/test/ui/borrowck/many-mutable-borrows.rs
new file mode 100644
index 00000000000..3e6ea9d25d9
--- /dev/null
+++ b/src/test/ui/borrowck/many-mutable-borrows.rs
@@ -0,0 +1,18 @@
+fn main() {
+    let v = Vec::new(); //~ ERROR cannot borrow `v` as mutable, as it is not declared as mutable
+    v.push(0);
+    v.push(0);
+    v.push(0);
+    v.push(0);
+    v.push(0);
+    v.push(0);
+    v.push(0);
+    v.push(0);
+    v.push(0);
+    v.push(0);
+    v.push(0);
+    v.push(0);
+    v.push(0);
+    v.push(0);
+    v.push(0);
+}
diff --git a/src/test/ui/borrowck/many-mutable-borrows.stderr b/src/test/ui/borrowck/many-mutable-borrows.stderr
new file mode 100644
index 00000000000..aa0cbcffd95
--- /dev/null
+++ b/src/test/ui/borrowck/many-mutable-borrows.stderr
@@ -0,0 +1,33 @@
+error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
+  --> $DIR/many-mutable-borrows.rs:2:9
+   |
+LL |     let v = Vec::new();
+   |         ^ not mutable
+LL |     v.push(0);
+   |     --------- cannot borrow as mutable
+LL |     v.push(0);
+   |     --------- cannot borrow as mutable
+LL |     v.push(0);
+   |     --------- cannot borrow as mutable
+LL |     v.push(0);
+   |     --------- cannot borrow as mutable
+LL |     v.push(0);
+   |     --------- cannot borrow as mutable
+LL |     v.push(0);
+   |     --------- cannot borrow as mutable
+LL |     v.push(0);
+   |     --------- cannot borrow as mutable
+LL |     v.push(0);
+   |     --------- cannot borrow as mutable
+LL |     v.push(0);
+   |     --------- cannot borrow as mutable
+   |
+   = note: ...and 5 other attempted mutable borrows
+help: consider changing this to be mutable
+   |
+LL |     let mut v = Vec::new();
+   |         +++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/borrowck/mut-borrow-of-mut-ref.rs b/src/test/ui/borrowck/mut-borrow-of-mut-ref.rs
index 7cdb16b282d..477a2aa48d5 100644
--- a/src/test/ui/borrowck/mut-borrow-of-mut-ref.rs
+++ b/src/test/ui/borrowck/mut-borrow-of-mut-ref.rs
@@ -2,15 +2,14 @@
 #![crate_type = "rlib"]
 
 pub fn f(b: &mut i32) {
-    //~^ NOTE the binding is already a mutable borrow
+    //~^ ERROR cannot borrow
+    //~| NOTE not mutable
     //~| NOTE the binding is already a mutable borrow
     h(&mut b);
-    //~^ ERROR cannot borrow
-    //~| NOTE cannot borrow as mutable
+    //~^ NOTE cannot borrow as mutable
     //~| HELP try removing `&mut` here
     g(&mut &mut b);
-    //~^ ERROR cannot borrow
-    //~| NOTE cannot borrow as mutable
+    //~^ NOTE cannot borrow as mutable
     //~| HELP try removing `&mut` here
 }
 
diff --git a/src/test/ui/borrowck/mut-borrow-of-mut-ref.stderr b/src/test/ui/borrowck/mut-borrow-of-mut-ref.stderr
index 7782047574c..c6f75b1c0d0 100644
--- a/src/test/ui/borrowck/mut-borrow-of-mut-ref.stderr
+++ b/src/test/ui/borrowck/mut-borrow-of-mut-ref.stderr
@@ -1,8 +1,14 @@
 error[E0596]: cannot borrow `b` as mutable, as it is not declared as mutable
-  --> $DIR/mut-borrow-of-mut-ref.rs:7:7
+  --> $DIR/mut-borrow-of-mut-ref.rs:4:10
    |
+LL | pub fn f(b: &mut i32) {
+   |          ^ not mutable
+...
 LL |     h(&mut b);
-   |       ^^^^^^ cannot borrow as mutable
+   |       ------ cannot borrow as mutable
+...
+LL |     g(&mut &mut b);
+   |            ------ cannot borrow as mutable
    |
 note: the binding is already a mutable borrow
   --> $DIR/mut-borrow-of-mut-ref.rs:4:13
@@ -14,18 +20,6 @@ help: try removing `&mut` here
 LL -     h(&mut b);
 LL +     h(b);
    |
-
-error[E0596]: cannot borrow `b` as mutable, as it is not declared as mutable
-  --> $DIR/mut-borrow-of-mut-ref.rs:11:12
-   |
-LL |     g(&mut &mut b);
-   |            ^^^^^^ cannot borrow as mutable
-   |
-note: the binding is already a mutable borrow
-  --> $DIR/mut-borrow-of-mut-ref.rs:4:13
-   |
-LL | pub fn f(b: &mut i32) {
-   |             ^^^^^^^^
 help: try removing `&mut` here
    |
 LL -     g(&mut &mut b);
@@ -33,13 +27,13 @@ LL +     g(&mut b);
    |
 
 error[E0596]: cannot borrow `b` as mutable, as it is not declared as mutable
-  --> $DIR/mut-borrow-of-mut-ref.rs:18:12
+  --> $DIR/mut-borrow-of-mut-ref.rs:17:12
    |
 LL |     h(&mut &mut b);
    |            ^^^^^^ cannot borrow as mutable
    |
 note: the binding is already a mutable borrow
-  --> $DIR/mut-borrow-of-mut-ref.rs:17:13
+  --> $DIR/mut-borrow-of-mut-ref.rs:16:13
    |
 LL | pub fn g(b: &mut i32) {
    |             ^^^^^^^^
@@ -50,7 +44,7 @@ LL +     h(&mut b);
    |
 
 error[E0596]: cannot borrow `f` as mutable, as it is not declared as mutable
-  --> $DIR/mut-borrow-of-mut-ref.rs:35:5
+  --> $DIR/mut-borrow-of-mut-ref.rs:34:5
    |
 LL |     f.bar();
    |     ^^^^^^^ cannot borrow as mutable
@@ -60,6 +54,6 @@ help: consider making the binding mutable
 LL | pub fn baz(mut f: &mut String) {
    |            +++
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/borrowck/mutability-errors.rs b/src/test/ui/borrowck/mutability-errors.rs
index 5be0df13761..82116425f06 100644
--- a/src/test/ui/borrowck/mutability-errors.rs
+++ b/src/test/ui/borrowck/mutability-errors.rs
@@ -50,9 +50,9 @@ fn ref_closure(mut x: (i32,)) {
     });
 }
 
-fn imm_local(x: (i32,)) {
-    &mut x; //~ ERROR
-    &mut x.0; //~ ERROR
+fn imm_local(x: (i32,)) { //~ ERROR
+    &mut x;
+    &mut x.0;
 }
 
 fn imm_capture(x: (i32,)) {
diff --git a/src/test/ui/borrowck/mutability-errors.stderr b/src/test/ui/borrowck/mutability-errors.stderr
index 7a00ace3bb2..d7c602718f1 100644
--- a/src/test/ui/borrowck/mutability-errors.stderr
+++ b/src/test/ui/borrowck/mutability-errors.stderr
@@ -245,21 +245,19 @@ LL |         &mut x.0;
    |         ^^^^^^^^ cannot borrow as mutable
 
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
-  --> $DIR/mutability-errors.rs:54:5
+  --> $DIR/mutability-errors.rs:53:14
    |
 LL | fn imm_local(x: (i32,)) {
-   |              - help: consider changing this to be mutable: `mut x`
-LL |     &mut x;
-   |     ^^^^^^ cannot borrow as mutable
-
-error[E0596]: cannot borrow `x.0` as mutable, as `x` is not declared as mutable
-  --> $DIR/mutability-errors.rs:55:5
-   |
-LL | fn imm_local(x: (i32,)) {
-   |              - help: consider changing this to be mutable: `mut x`
+   |              ^ not mutable
 LL |     &mut x;
+   |     ------ cannot borrow as mutable
 LL |     &mut x.0;
-   |     ^^^^^^^^ cannot borrow as mutable
+   |     -------- cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL | fn imm_local(mut x: (i32,)) {
+   |              +++
 
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
   --> $DIR/mutability-errors.rs:60:9
@@ -357,7 +355,7 @@ error[E0596]: cannot borrow `X.0` as mutable, as `X` is an immutable static item
 LL |     &mut X.0;
    |     ^^^^^^^^ cannot borrow as mutable
 
-error: aborting due to 38 previous errors
+error: aborting due to 37 previous errors
 
 Some errors have detailed explanations: E0594, E0596.
 For more information about an error, try `rustc --explain E0594`.
diff --git a/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.stderr b/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.stderr
index a3885b5f5ca..81e5bc45d4d 100644
--- a/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.stderr
+++ b/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.stderr
@@ -11,11 +11,13 @@ LL |     x.a = 1;
 error[E0594]: cannot assign to `x.b`, as `x` is not declared as mutable
   --> $DIR/reassignment_immutable_fields_overlapping.rs:13:5
    |
-LL |     let x: Foo;
-   |         - help: consider changing this to be mutable: `mut x`
-LL |     x.a = 1;
 LL |     x.b = 22;
    |     ^^^^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut x: Foo;
+   |         +++
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/borrowck/reassignment_immutable_fields_twice.stderr b/src/test/ui/borrowck/reassignment_immutable_fields_twice.stderr
index 49c81adad49..ba0457809ad 100644
--- a/src/test/ui/borrowck/reassignment_immutable_fields_twice.stderr
+++ b/src/test/ui/borrowck/reassignment_immutable_fields_twice.stderr
@@ -1,11 +1,13 @@
 error[E0594]: cannot assign to `x.0`, as `x` is not declared as mutable
   --> $DIR/reassignment_immutable_fields_twice.rs:7:5
    |
-LL |     let x: (u32, u32);
-   |         - help: consider changing this to be mutable: `mut x`
-LL |     x = (22, 44);
 LL |     x.0 = 1;
    |     ^^^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut x: (u32, u32);
+   |         +++
 
 error[E0381]: partially assigned binding `x` isn't fully initialized
   --> $DIR/reassignment_immutable_fields_twice.rs:12:5
diff --git a/src/test/ui/closures/issue-80313-mutable-borrow-in-closure.stderr b/src/test/ui/closures/issue-80313-mutable-borrow-in-closure.stderr
index bf9e1febdbb..239f071ca92 100644
--- a/src/test/ui/closures/issue-80313-mutable-borrow-in-closure.stderr
+++ b/src/test/ui/closures/issue-80313-mutable-borrow-in-closure.stderr
@@ -1,13 +1,16 @@
 error[E0596]: cannot borrow `callback` as mutable, as it is not declared as mutable
   --> $DIR/issue-80313-mutable-borrow-in-closure.rs:6:5
    |
-LL |     let callback = || {
-   |         -------- help: consider changing this to be mutable: `mut callback`
 LL |         &mut my_var;
    |              ------ calling `callback` requires mutable binding due to mutable borrow of `my_var`
 LL |     };
 LL |     callback();
    |     ^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut callback = || {
+   |         +++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/closures/issue-80313-mutable-borrow-in-move-closure.stderr b/src/test/ui/closures/issue-80313-mutable-borrow-in-move-closure.stderr
index b67cec6a609..1ec279f03ef 100644
--- a/src/test/ui/closures/issue-80313-mutable-borrow-in-move-closure.stderr
+++ b/src/test/ui/closures/issue-80313-mutable-borrow-in-move-closure.stderr
@@ -1,13 +1,16 @@
 error[E0596]: cannot borrow `callback` as mutable, as it is not declared as mutable
   --> $DIR/issue-80313-mutable-borrow-in-move-closure.rs:6:5
    |
-LL |     let callback = move || {
-   |         -------- help: consider changing this to be mutable: `mut callback`
 LL |         &mut my_var;
    |              ------ calling `callback` requires mutable binding due to possible mutation of `my_var`
 LL |     };
 LL |     callback();
    |     ^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut callback = move || {
+   |         +++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/closures/issue-80313-mutation-in-closure.stderr b/src/test/ui/closures/issue-80313-mutation-in-closure.stderr
index 6e98549f6b8..22a62ce7350 100644
--- a/src/test/ui/closures/issue-80313-mutation-in-closure.stderr
+++ b/src/test/ui/closures/issue-80313-mutation-in-closure.stderr
@@ -1,13 +1,16 @@
 error[E0596]: cannot borrow `callback` as mutable, as it is not declared as mutable
   --> $DIR/issue-80313-mutation-in-closure.rs:6:5
    |
-LL |     let callback = || {
-   |         -------- help: consider changing this to be mutable: `mut callback`
 LL |         my_var = true;
    |         ------ calling `callback` requires mutable binding due to mutable borrow of `my_var`
 LL |     };
 LL |     callback();
    |     ^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut callback = || {
+   |         +++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/closures/issue-80313-mutation-in-move-closure.stderr b/src/test/ui/closures/issue-80313-mutation-in-move-closure.stderr
index edd55422a0b..a2222f8cc95 100644
--- a/src/test/ui/closures/issue-80313-mutation-in-move-closure.stderr
+++ b/src/test/ui/closures/issue-80313-mutation-in-move-closure.stderr
@@ -1,13 +1,16 @@
 error[E0596]: cannot borrow `callback` as mutable, as it is not declared as mutable
   --> $DIR/issue-80313-mutation-in-move-closure.rs:6:5
    |
-LL |     let callback = move || {
-   |         -------- help: consider changing this to be mutable: `mut callback`
 LL |         my_var = true;
    |         ------ calling `callback` requires mutable binding due to possible mutation of `my_var`
 LL |     };
 LL |     callback();
    |     ^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut callback = move || {
+   |         +++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/closures/issue-81700-mut-borrow.stderr b/src/test/ui/closures/issue-81700-mut-borrow.stderr
index 3f564afff58..03b18c3f70c 100644
--- a/src/test/ui/closures/issue-81700-mut-borrow.stderr
+++ b/src/test/ui/closures/issue-81700-mut-borrow.stderr
@@ -2,11 +2,14 @@ error[E0596]: cannot borrow `bar` as mutable, as it is not declared as mutable
   --> $DIR/issue-81700-mut-borrow.rs:3:5
    |
 LL |     let bar = || { foo(x); };
-   |         ---            - calling `bar` requires mutable binding due to mutable borrow of `x`
-   |         |
-   |         help: consider changing this to be mutable: `mut bar`
+   |                        - calling `bar` requires mutable binding due to mutable borrow of `x`
 LL |     bar();
    |     ^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut bar = || { foo(x); };
+   |         +++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/closures/issue-82438-mut-without-upvar.stderr b/src/test/ui/closures/issue-82438-mut-without-upvar.stderr
index 802284b2658..f0951b7d108 100644
--- a/src/test/ui/closures/issue-82438-mut-without-upvar.stderr
+++ b/src/test/ui/closures/issue-82438-mut-without-upvar.stderr
@@ -1,11 +1,13 @@
 error[E0596]: cannot borrow `c` as mutable, as it is not declared as mutable
   --> $DIR/issue-82438-mut-without-upvar.rs:27:27
    |
-LL |     let c = |a, b, c, d| {};
-   |         - help: consider changing this to be mutable: `mut c`
-LL |
 LL |     A.f(participant_name, &mut c);
    |                           ^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut c = |a, b, c, d| {};
+   |         +++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/closures/issue-84044-drop-non-mut.stderr b/src/test/ui/closures/issue-84044-drop-non-mut.stderr
index c0bfad263f1..5335a056cd8 100644
--- a/src/test/ui/closures/issue-84044-drop-non-mut.stderr
+++ b/src/test/ui/closures/issue-84044-drop-non-mut.stderr
@@ -1,10 +1,13 @@
 error[E0596]: cannot borrow `f` as mutable, as it is not declared as mutable
   --> $DIR/issue-84044-drop-non-mut.rs:5:10
    |
-LL |     let f = || {};
-   |         - help: consider changing this to be mutable: `mut f`
 LL |     drop(&mut f);
    |          ^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut f = || {};
+   |         +++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/codemap_tests/huge_multispan_highlight.stderr b/src/test/ui/codemap_tests/huge_multispan_highlight.stderr
index a60f1c77a58..9f8ce3b6183 100644
--- a/src/test/ui/codemap_tests/huge_multispan_highlight.stderr
+++ b/src/test/ui/codemap_tests/huge_multispan_highlight.stderr
@@ -1,11 +1,13 @@
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/huge_multispan_highlight.rs:90:13
    |
-LL |     let x = "foo";
-   |         - help: consider changing this to be mutable: `mut x`
-...
 LL |     let y = &mut x;
    |             ^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut x = "foo";
+   |         +++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/did_you_mean/issue-35937.stderr b/src/test/ui/did_you_mean/issue-35937.stderr
index 9562d94509e..1670da55957 100644
--- a/src/test/ui/did_you_mean/issue-35937.stderr
+++ b/src/test/ui/did_you_mean/issue-35937.stderr
@@ -1,26 +1,35 @@
 error[E0596]: cannot borrow `f.v` as mutable, as `f` is not declared as mutable
   --> $DIR/issue-35937.rs:7:5
    |
-LL |     let f = Foo { v: Vec::new() };
-   |         - help: consider changing this to be mutable: `mut f`
 LL |     f.v.push("cat".to_string());
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut f = Foo { v: Vec::new() };
+   |         +++
 
 error[E0594]: cannot assign to `s.x`, as `s` is not declared as mutable
   --> $DIR/issue-35937.rs:16:5
    |
-LL |     let s = S { x: 42 };
-   |         - help: consider changing this to be mutable: `mut s`
 LL |     s.x += 1;
    |     ^^^^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut s = S { x: 42 };
+   |         +++
 
 error[E0594]: cannot assign to `s.x`, as `s` is not declared as mutable
   --> $DIR/issue-35937.rs:20:5
    |
-LL | fn bar(s: S) {
-   |        - help: consider changing this to be mutable: `mut s`
 LL |     s.x += 1;
    |     ^^^^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL | fn bar(mut s: S) {
+   |        +++
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/did_you_mean/issue-39544.stderr b/src/test/ui/did_you_mean/issue-39544.stderr
index b16309af041..8dc0512a945 100644
--- a/src/test/ui/did_you_mean/issue-39544.stderr
+++ b/src/test/ui/did_you_mean/issue-39544.stderr
@@ -1,10 +1,13 @@
 error[E0596]: cannot borrow `z.x` as mutable, as `z` is not declared as mutable
   --> $DIR/issue-39544.rs:11:13
    |
-LL |     let z = Z { x: X::Y };
-   |         - help: consider changing this to be mutable: `mut z`
 LL |     let _ = &mut z.x;
    |             ^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut z = Z { x: X::Y };
+   |         +++
 
 error[E0596]: cannot borrow `self.x` as mutable, as it is behind a `&` reference
   --> $DIR/issue-39544.rs:16:17
@@ -97,10 +100,13 @@ LL |     fn foo4(other: &mut Z) {
 error[E0596]: cannot borrow `z.x` as mutable, as `z` is not declared as mutable
   --> $DIR/issue-39544.rs:41:13
    |
-LL | pub fn with_arg(z: Z, w: &Z) {
-   |                 - help: consider changing this to be mutable: `mut z`
 LL |     let _ = &mut z.x;
    |             ^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL | pub fn with_arg(mut z: Z, w: &Z) {
+   |                 +++
 
 error[E0596]: cannot borrow `w.x` as mutable, as it is behind a `&` reference
   --> $DIR/issue-39544.rs:42:13
diff --git a/src/test/ui/error-codes/E0596.stderr b/src/test/ui/error-codes/E0596.stderr
index 79bc258f1fa..3f9aebcc8ae 100644
--- a/src/test/ui/error-codes/E0596.stderr
+++ b/src/test/ui/error-codes/E0596.stderr
@@ -1,10 +1,13 @@
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/E0596.rs:3:13
    |
-LL |     let x = 1;
-   |         - help: consider changing this to be mutable: `mut x`
 LL |     let y = &mut x;
    |             ^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut x = 1;
+   |         +++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-36400.stderr b/src/test/ui/issues/issue-36400.stderr
index 3b37578f3c4..5b753c69d5d 100644
--- a/src/test/ui/issues/issue-36400.stderr
+++ b/src/test/ui/issues/issue-36400.stderr
@@ -1,10 +1,13 @@
 error[E0596]: cannot borrow `*x` as mutable, as `x` is not declared as mutable
   --> $DIR/issue-36400.rs:5:7
    |
-LL |     let x = Box::new(3);
-   |         - help: consider changing this to be mutable: `mut x`
 LL |     f(&mut *x);
    |       ^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut x = Box::new(3);
+   |         +++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.stderr
index a909c5fa823..cc2447b1877 100644
--- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.stderr
+++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.stderr
@@ -16,10 +16,13 @@ LL | fn foo<'a>(x:fn(&u8, &u8), y: Vec<&'a u8>, z: &'a u8) {
 error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable
   --> $DIR/ex3-both-anon-regions-using-fn-items.rs:2:3
    |
-LL | fn foo(x:fn(&u8, &u8), y: Vec<&u8>, z: &u8) {
-   |                        - help: consider changing this to be mutable: `mut y`
 LL |   y.push(z);
    |   ^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL | fn foo(x:fn(&u8, &u8), mut y: Vec<&u8>, z: &u8) {
+   |                        +++
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.stderr
index d85ea6529f6..2ba5afa808d 100644
--- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.stderr
+++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.stderr
@@ -16,10 +16,13 @@ LL | fn foo<'a>(x:Box<dyn Fn(&u8, &u8)> , y: Vec<&'a u8>, z: &'a u8) {
 error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable
   --> $DIR/ex3-both-anon-regions-using-trait-objects.rs:2:3
    |
-LL | fn foo(x:Box<dyn Fn(&u8, &u8)> , y: Vec<&u8>, z: &u8) {
-   |                                  - help: consider changing this to be mutable: `mut y`
 LL |   y.push(z);
    |   ^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL | fn foo(x:Box<dyn Fn(&u8, &u8)> , mut y: Vec<&u8>, z: &u8) {
+   |                                  +++
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/macros/span-covering-argument-1.stderr b/src/test/ui/macros/span-covering-argument-1.stderr
index ce3424a8b15..e57347b362d 100644
--- a/src/test/ui/macros/span-covering-argument-1.stderr
+++ b/src/test/ui/macros/span-covering-argument-1.stderr
@@ -1,8 +1,6 @@
 error[E0596]: cannot borrow `foo` as mutable, as it is not declared as mutable
   --> $DIR/span-covering-argument-1.rs:5:14
    |
-LL |             let $s = 0;
-   |                 -- help: consider changing this to be mutable: `mut foo`
 LL |             *&mut $s = 0;
    |              ^^^^^^^ cannot borrow as mutable
 ...
@@ -10,6 +8,10 @@ LL |     bad!(foo whatever);
    |     ------------------ in this macro invocation
    |
    = note: this error originates in the macro `bad` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider changing this to be mutable
+   |
+LL |             let mut $s = 0;
+   |                 +++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/mut/mut-suggestion.rs b/src/test/ui/mut/mut-suggestion.rs
index 3104b20aca4..8c269d1e727 100644
--- a/src/test/ui/mut/mut-suggestion.rs
+++ b/src/test/ui/mut/mut-suggestion.rs
@@ -8,7 +8,7 @@ impl S {
 
 fn func(arg: S) {
     //~^ HELP consider changing this to be mutable
-    //~| SUGGESTION mut arg
+    //~| SUGGESTION mut
     arg.mutate();
     //~^ ERROR cannot borrow `arg` as mutable, as it is not declared as mutable
 }
@@ -16,7 +16,7 @@ fn func(arg: S) {
 fn main() {
     let local = S;
     //~^ HELP consider changing this to be mutable
-    //~| SUGGESTION mut local
+    //~| SUGGESTION mut
     local.mutate();
     //~^ ERROR cannot borrow `local` as mutable, as it is not declared as mutable
 }
diff --git a/src/test/ui/mut/mut-suggestion.stderr b/src/test/ui/mut/mut-suggestion.stderr
index cba284550b9..d89c8b41304 100644
--- a/src/test/ui/mut/mut-suggestion.stderr
+++ b/src/test/ui/mut/mut-suggestion.stderr
@@ -1,20 +1,24 @@
 error[E0596]: cannot borrow `arg` as mutable, as it is not declared as mutable
   --> $DIR/mut-suggestion.rs:12:5
    |
-LL | fn func(arg: S) {
-   |         --- help: consider changing this to be mutable: `mut arg`
-...
 LL |     arg.mutate();
    |     ^^^^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL | fn func(mut arg: S) {
+   |         +++
 
 error[E0596]: cannot borrow `local` as mutable, as it is not declared as mutable
   --> $DIR/mut-suggestion.rs:20:5
    |
-LL |     let local = S;
-   |         ----- help: consider changing this to be mutable: `mut local`
-...
 LL |     local.mutate();
    |     ^^^^^^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut local = S;
+   |         +++
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/mut/mutable-class-fields.stderr b/src/test/ui/mut/mutable-class-fields.stderr
index 40a0dc9b29c..1d731be8a85 100644
--- a/src/test/ui/mut/mutable-class-fields.stderr
+++ b/src/test/ui/mut/mutable-class-fields.stderr
@@ -1,10 +1,13 @@
 error[E0594]: cannot assign to `nyan.how_hungry`, as `nyan` is not declared as mutable
   --> $DIR/mutable-class-fields.rs:15:3
    |
-LL |   let nyan : Cat = cat(52, 99);
-   |       ---- help: consider changing this to be mutable: `mut nyan`
 LL |   nyan.how_hungry = 0;
    |   ^^^^^^^^^^^^^^^^^^^ cannot assign
+   |
+help: consider changing this to be mutable
+   |
+LL |   let mut nyan : Cat = cat(52, 99);
+   |       +++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/issue-51191.stderr b/src/test/ui/nll/issue-51191.stderr
index 63ca6ae5c28..27b1f8705ff 100644
--- a/src/test/ui/nll/issue-51191.stderr
+++ b/src/test/ui/nll/issue-51191.stderr
@@ -30,10 +30,13 @@ LL |         (&mut self).bar();
 error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
   --> $DIR/issue-51191.rs:13:9
    |
-LL |     fn imm(self) {
-   |            ---- help: consider changing this to be mutable: `mut self`
 LL |         (&mut self).bar();
    |         ^^^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     fn imm(mut self) {
+   |            +++
 
 error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
   --> $DIR/issue-51191.rs:22:9
diff --git a/src/test/ui/pattern/bindings-after-at/nested-binding-modes-mut.stderr b/src/test/ui/pattern/bindings-after-at/nested-binding-modes-mut.stderr
index 70beb5d4232..54118dc3677 100644
--- a/src/test/ui/pattern/bindings-after-at/nested-binding-modes-mut.stderr
+++ b/src/test/ui/pattern/bindings-after-at/nested-binding-modes-mut.stderr
@@ -1,20 +1,24 @@
 error[E0596]: cannot borrow `not_mut` as mutable, as it is not declared as mutable
   --> $DIR/nested-binding-modes-mut.rs:4:5
    |
-LL |     let mut is_mut @ not_mut = 42;
-   |                      ------- help: consider changing this to be mutable: `mut not_mut`
-LL |     &mut is_mut;
 LL |     &mut not_mut;
    |     ^^^^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut is_mut @ mut not_mut = 42;
+   |                      +++
 
 error[E0596]: cannot borrow `not_mut` as mutable, as it is not declared as mutable
   --> $DIR/nested-binding-modes-mut.rs:9:5
    |
-LL |     let not_mut @ mut is_mut = 42;
-   |         ------- help: consider changing this to be mutable: `mut not_mut`
-LL |     &mut is_mut;
 LL |     &mut not_mut;
    |     ^^^^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut not_mut @ mut is_mut = 42;
+   |         +++
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr b/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr
index 20330c92325..570328fc211 100644
--- a/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr
+++ b/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr
@@ -1,10 +1,13 @@
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:53:24
    |
-LL | fn deref_mut_field1(x: Own<Point>) {
-   |                     - help: consider changing this to be mutable: `mut x`
 LL |     let __isize = &mut x.y;
    |                        ^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL | fn deref_mut_field1(mut x: Own<Point>) {
+   |                     +++
 
 error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
   --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:65:10
@@ -30,10 +33,13 @@ LL |     use_mut(_x);
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:88:5
    |
-LL | fn assign_field1<'a>(x: Own<Point>) {
-   |                      - help: consider changing this to be mutable: `mut x`
 LL |     x.y = 3;
    |     ^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL | fn assign_field1<'a>(mut x: Own<Point>) {
+   |                      +++
 
 error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
   --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:92:5
@@ -59,10 +65,13 @@ LL |     use_mut(_p);
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:109:5
    |
-LL | fn deref_mut_method1(x: Own<Point>) {
-   |                      - help: consider changing this to be mutable: `mut x`
 LL |     x.set(0, 0);
    |     ^^^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL | fn deref_mut_method1(mut x: Own<Point>) {
+   |                      +++
 
 error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
   --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:121:5
@@ -78,10 +87,13 @@ LL | fn deref_extend_mut_method1(x: &mut Own<Point>) -> &mut isize {
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:129:6
    |
-LL | fn assign_method1<'a>(x: Own<Point>) {
-   |                       - help: consider changing this to be mutable: `mut x`
 LL |     *x.y_mut() = 3;
    |      ^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL | fn assign_method1<'a>(mut x: Own<Point>) {
+   |                       +++
 
 error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
   --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:133:6
diff --git a/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr b/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr
index 6d34909e43b..3fed7b3f4dc 100644
--- a/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr
+++ b/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr
@@ -1,10 +1,13 @@
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/borrowck-borrow-overloaded-deref-mut.rs:29:25
    |
-LL | fn deref_mut1(x: Own<isize>) {
-   |               - help: consider changing this to be mutable: `mut x`
 LL |     let __isize = &mut *x;
    |                         ^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL | fn deref_mut1(mut x: Own<isize>) {
+   |               +++
 
 error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
   --> $DIR/borrowck-borrow-overloaded-deref-mut.rs:41:11
@@ -20,10 +23,13 @@ LL | fn deref_extend_mut1<'a>(x: &'a mut Own<isize>) -> &'a mut isize {
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/borrowck-borrow-overloaded-deref-mut.rs:49:6
    |
-LL | fn assign1<'a>(x: Own<isize>) {
-   |                - help: consider changing this to be mutable: `mut x`
 LL |     *x = 3;
    |      ^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL | fn assign1<'a>(mut x: Own<isize>) {
+   |                +++
 
 error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
   --> $DIR/borrowck-borrow-overloaded-deref-mut.rs:53:6
diff --git a/src/test/ui/span/borrowck-object-mutability.stderr b/src/test/ui/span/borrowck-object-mutability.stderr
index e63ca95eff0..b6517e0b309 100644
--- a/src/test/ui/span/borrowck-object-mutability.stderr
+++ b/src/test/ui/span/borrowck-object-mutability.stderr
@@ -12,11 +12,13 @@ LL | fn borrowed_receiver(x: &mut dyn Foo) {
 error[E0596]: cannot borrow `*x` as mutable, as `x` is not declared as mutable
   --> $DIR/borrowck-object-mutability.rs:18:5
    |
-LL | fn owned_receiver(x: Box<dyn Foo>) {
-   |                   - help: consider changing this to be mutable: `mut x`
-LL |     x.borrowed();
 LL |     x.borrowed_mut();
    |     ^^^^^^^^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL | fn owned_receiver(mut x: Box<dyn Foo>) {
+   |                   +++
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.stderr b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.stderr
index a0ed56d4bcf..5c93ed6d7f7 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.stderr
@@ -12,13 +12,16 @@ LL |         tick1();
 error[E0596]: cannot borrow `tick2` as mutable, as it is not declared as mutable
   --> $DIR/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.rs:19:5
    |
-LL |     let tick2 = || {
-   |         ----- help: consider changing this to be mutable: `mut tick2`
 LL |         tick1();
    |         ----- calling `tick2` requires mutable binding due to mutable borrow of `tick1`
 ...
 LL |     tick2();
    |     ^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut tick2 = || {
+   |         +++
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-missing-mut.stderr b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-missing-mut.stderr
index 27d23e3fa04..3f539c42d9b 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-missing-mut.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-missing-mut.stderr
@@ -2,11 +2,14 @@ error[E0596]: cannot borrow `tick` as mutable, as it is not declared as mutable
   --> $DIR/unboxed-closures-infer-fnmut-missing-mut.rs:7:5
    |
 LL |     let tick = || counter += 1;
-   |         ----      ------- calling `tick` requires mutable binding due to mutable borrow of `counter`
-   |         |
-   |         help: consider changing this to be mutable: `mut tick`
+   |                   ------- calling `tick` requires mutable binding due to mutable borrow of `counter`
 LL |     tick();
    |     ^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut tick = || counter += 1;
+   |         +++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-move-missing-mut.stderr b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-move-missing-mut.stderr
index c00f986c397..e3b19297b9c 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-move-missing-mut.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-move-missing-mut.stderr
@@ -2,11 +2,14 @@ error[E0596]: cannot borrow `tick` as mutable, as it is not declared as mutable
   --> $DIR/unboxed-closures-infer-fnmut-move-missing-mut.rs:7:5
    |
 LL |     let tick = move || counter += 1;
-   |         ----           ------- calling `tick` requires mutable binding due to possible mutation of `counter`
-   |         |
-   |         help: consider changing this to be mutable: `mut tick`
+   |                        ------- calling `tick` requires mutable binding due to possible mutation of `counter`
 LL |     tick();
    |     ^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut tick = move || counter += 1;
+   |         +++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/writing-to-immutable-vec.stderr b/src/test/ui/writing-to-immutable-vec.stderr
index a65765c86c8..286267c3834 100644
--- a/src/test/ui/writing-to-immutable-vec.stderr
+++ b/src/test/ui/writing-to-immutable-vec.stderr
@@ -1,10 +1,13 @@
 error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
   --> $DIR/writing-to-immutable-vec.rs:3:5
    |
-LL |     let v: Vec<isize> = vec![1, 2, 3];
-   |         - help: consider changing this to be mutable: `mut v`
 LL |     v[1] = 4;
    |     ^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL |     let mut v: Vec<isize> = vec![1, 2, 3];
+   |         +++
 
 error: aborting due to previous error