about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-06-19 21:31:36 +0000
committerbors <bors@rust-lang.org>2018-06-19 21:31:36 +0000
commitf28c7aef7fbff1909c2d0257186cd7a5f0c6aa4b (patch)
tree3ae6e0cd22a8003311fed08d61a54ef369b2ef9a /src/test
parentd692ab406ebab720f99f950ac3e9aba1e01296af (diff)
parent46846496ed6194d4cacf1fbd52b9c76b5c83b96c (diff)
Auto merge of #51275 - pnkfelix:nll-diagnostics-revise-check-access-permissions, r=nikomatsakis
NLL diagnostics: revise `fn check_access_permissions`

NLL: revise `fn check_access_permissions` so that its (still branchy) shares more code paths between the different cases, and also provide more diagnostics in more cases (though the added diagnostics still do not always meet the quality bar established by AST-borrowck)

----

Transcribing "checklist" suggested by Niko, except I am rendering it as a table to make it clear that I do not regard every item in the list to be a "must have" for landing this PR.

goal | does this PR do it?
-----|------------------------------
no suggestions for `ref mut` |  yes
suggestions for direct local assignment (`{ let x = 3; x = 4; }`) | yes (see commits at end)
suggestions for direct field assignment (`{ let x = (3, 4); x.0 = 5; }` | yes (see commits at end)
suggestions for upvars (`let x = 3; let c = \|\| { &mut x; }`) | yes

Note that I added support for a couple of rows via changes that are not strictly part of `fn check_access_permissions`. If desired I can remove those commits from this PR and leave them for a later PR.

Fix #51031
Fix #51032
(bug #51191 needs a little more investigation before closing.)
Fix #51578
Diffstat (limited to 'src/test')
-rw-r--r--src/test/compile-fail/assign-imm-local-twice.rs1
-rw-r--r--src/test/compile-fail/borrowck/borrowck-issue-14498.rs2
-rw-r--r--src/test/compile-fail/borrowck/borrowck-overloaded-index-ref-index.rs2
-rw-r--r--src/test/compile-fail/issue-45199.rs4
-rw-r--r--src/test/compile-fail/liveness-assign-imm-local-in-loop.rs1
-rw-r--r--src/test/compile-fail/liveness-assign-imm-local-in-op-eq.rs1
-rw-r--r--src/test/compile-fail/liveness-assign-imm-local-with-drop.rs1
-rw-r--r--src/test/compile-fail/liveness-assign-imm-local-with-init.rs1
-rw-r--r--src/test/compile-fail/unboxed-closures-mutated-upvar-from-fn-closure.rs2
-rw-r--r--src/test/ui/asm-out-assign-imm.nll.stderr14
-rw-r--r--src/test/ui/augmented-assignments.nll.stderr3
-rw-r--r--src/test/ui/borrowck/immutable-arg.stderr2
-rw-r--r--src/test/ui/borrowck/issue-45983.nll.stderr6
-rw-r--r--src/test/ui/borrowck/mut-borrow-of-mut-ref.nll.stderr2
-rw-r--r--src/test/ui/codemap_tests/huge_multispan_highlight.nll.stderr3
-rw-r--r--src/test/ui/command-line-diagnostics.nll.stderr4
-rw-r--r--src/test/ui/did_you_mean/issue-31424.nll.stderr2
-rw-r--r--src/test/ui/did_you_mean/issue-34126.nll.stderr5
-rw-r--r--src/test/ui/did_you_mean/issue-34337.nll.stderr5
-rw-r--r--src/test/ui/did_you_mean/issue-35937.nll.stderr13
-rw-r--r--src/test/ui/did_you_mean/issue-37139.nll.stderr5
-rw-r--r--src/test/ui/did_you_mean/issue-38147-1.nll.stderr6
-rw-r--r--src/test/ui/did_you_mean/issue-38147-4.nll.stderr6
-rw-r--r--src/test/ui/did_you_mean/issue-39544.nll.stderr70
-rw-r--r--src/test/ui/did_you_mean/issue-40823.nll.stderr4
-rw-r--r--src/test/ui/error-codes/E0389.nll.stderr2
-rw-r--r--src/test/ui/issue-36400.nll.stderr4
-rw-r--r--src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.nll.stderr2
-rw-r--r--src/test/ui/lifetime-errors/ex3-both-anon-regions-using-fn-items.nll.stderr2
-rw-r--r--src/test/ui/lifetime-errors/ex3-both-anon-regions-using-trait-objects.nll.stderr2
-rw-r--r--src/test/ui/lifetime-errors/liveness-assign-imm-local-notes.stderr12
-rw-r--r--src/test/ui/macros/span-covering-argument-1.nll.stderr2
-rw-r--r--src/test/ui/nll/issue-47388.stderr2
-rw-r--r--src/test/ui/reassign-ref-mut.rs26
-rw-r--r--src/test/ui/reassign-ref-mut.stderr20
-rw-r--r--src/test/ui/rfc-2005-default-binding-mode/enum.nll.stderr18
-rw-r--r--src/test/ui/rfc-2005-default-binding-mode/explicit-mut.nll.stderr18
-rw-r--r--src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.nll.stderr24
-rw-r--r--src/test/ui/span/borrowck-borrow-overloaded-deref-mut.nll.stderr12
-rw-r--r--src/test/ui/span/borrowck-call-is-borrow-issue-12224.nll.stderr10
-rw-r--r--src/test/ui/span/borrowck-call-method-from-mut-aliasable.nll.stderr5
-rw-r--r--src/test/ui/span/borrowck-fn-in-const-b.nll.stderr4
-rw-r--r--src/test/ui/span/borrowck-object-mutability.nll.stderr10
-rw-r--r--src/test/ui/span/mut-arg-hint.nll.stderr12
-rw-r--r--src/test/ui/suggestions/closure-immutable-outer-variable.nll.stderr2
-rw-r--r--src/test/ui/suggestions/fn-closure-mutable-capture.nll.stderr4
-rw-r--r--src/test/ui/trivial-bounds-inconsistent-copy-reborrow.nll.stderr12
47 files changed, 258 insertions, 112 deletions
diff --git a/src/test/compile-fail/assign-imm-local-twice.rs b/src/test/compile-fail/assign-imm-local-twice.rs
index d5e412c3745..ee9dafdd49e 100644
--- a/src/test/compile-fail/assign-imm-local-twice.rs
+++ b/src/test/compile-fail/assign-imm-local-twice.rs
@@ -13,6 +13,7 @@
 
 fn test() {
     let v: isize;
+    //[mir]~^ NOTE consider changing this to `mut v`
     v = 1; //[ast]~ NOTE first assignment
            //[mir]~^ NOTE first assignment
     println!("v={}", v);
diff --git a/src/test/compile-fail/borrowck/borrowck-issue-14498.rs b/src/test/compile-fail/borrowck/borrowck-issue-14498.rs
index fbdd013024d..3c5f932af47 100644
--- a/src/test/compile-fail/borrowck/borrowck-issue-14498.rs
+++ b/src/test/compile-fail/borrowck/borrowck-issue-14498.rs
@@ -27,7 +27,7 @@ fn indirect_write_to_imm_box() {
     let y: Box<_> = box &mut x;
     let p = &y;
     ***p = 2; //[ast]~ ERROR cannot assign to data in a `&` reference
-              //[mir]~^ ERROR cannot assign to data in a `&` reference
+              //[mir]~^ ERROR cannot assign to `***p`
     drop(p);
 }
 
diff --git a/src/test/compile-fail/borrowck/borrowck-overloaded-index-ref-index.rs b/src/test/compile-fail/borrowck/borrowck-overloaded-index-ref-index.rs
index 109fe3d1128..f4f40e0407f 100644
--- a/src/test/compile-fail/borrowck/borrowck-overloaded-index-ref-index.rs
+++ b/src/test/compile-fail/borrowck/borrowck-overloaded-index-ref-index.rs
@@ -70,6 +70,6 @@ fn main() {
     };
     s[2] = 20;
     //[ast]~^ ERROR cannot assign to immutable indexed content
-    //[mir]~^^ ERROR cannot assign to immutable item
+    //[mir]~^^ ERROR cannot assign to data in a `&` reference
     drop(rs);
 }
diff --git a/src/test/compile-fail/issue-45199.rs b/src/test/compile-fail/issue-45199.rs
index ecddb4c101f..61e19ffc0d2 100644
--- a/src/test/compile-fail/issue-45199.rs
+++ b/src/test/compile-fail/issue-45199.rs
@@ -13,6 +13,7 @@
 
 fn test_drop_replace() {
     let b: Box<isize>;
+    //[mir]~^ NOTE consider changing this to `mut b`
     b = Box::new(1);    //[ast]~ NOTE first assignment
                         //[mir]~^ NOTE first assignment
     b = Box::new(2);    //[ast]~ ERROR cannot assign twice to immutable variable
@@ -24,6 +25,7 @@ fn test_drop_replace() {
 fn test_call() {
     let b = Box::new(1);    //[ast]~ NOTE first assignment
                             //[mir]~^ NOTE first assignment
+                            //[mir]~| NOTE consider changing this to `mut b`
     b = Box::new(2);        //[ast]~ ERROR cannot assign twice to immutable variable
                             //[mir]~^ ERROR cannot assign twice to immutable variable `b`
                             //[ast]~| NOTE cannot assign twice to immutable
@@ -31,7 +33,7 @@ fn test_call() {
 }
 
 fn test_args(b: Box<i32>) {  //[ast]~ NOTE first assignment
-                                //[mir]~^ NOTE argument not declared as `mut`
+                                //[mir]~^ NOTE consider changing this to `mut b`
     b = Box::new(2);            //[ast]~ ERROR cannot assign twice to immutable variable
                                 //[mir]~^ ERROR cannot assign to immutable argument `b`
                                 //[ast]~| NOTE cannot assign twice to immutable
diff --git a/src/test/compile-fail/liveness-assign-imm-local-in-loop.rs b/src/test/compile-fail/liveness-assign-imm-local-in-loop.rs
index f28906ddb95..7bc3680ca77 100644
--- a/src/test/compile-fail/liveness-assign-imm-local-in-loop.rs
+++ b/src/test/compile-fail/liveness-assign-imm-local-in-loop.rs
@@ -13,6 +13,7 @@
 
 fn test() {
     let v: isize;
+    //[mir]~^ NOTE consider changing this to `mut v`
     loop {
         v = 1; //[ast]~ ERROR cannot assign twice to immutable variable
                //[mir]~^ ERROR cannot assign twice to immutable variable `v`
diff --git a/src/test/compile-fail/liveness-assign-imm-local-in-op-eq.rs b/src/test/compile-fail/liveness-assign-imm-local-in-op-eq.rs
index 594cc076121..7812cdd8684 100644
--- a/src/test/compile-fail/liveness-assign-imm-local-in-op-eq.rs
+++ b/src/test/compile-fail/liveness-assign-imm-local-in-op-eq.rs
@@ -13,6 +13,7 @@
 
 fn test() {
     let v: isize;
+    //[mir]~^ NOTE consider changing this to `mut v`
     v = 2;  //[ast]~ NOTE first assignment
             //[mir]~^ NOTE first assignment
     v += 1; //[ast]~ ERROR cannot assign twice to immutable variable
diff --git a/src/test/compile-fail/liveness-assign-imm-local-with-drop.rs b/src/test/compile-fail/liveness-assign-imm-local-with-drop.rs
index b4fb33ca15e..bb61a9037d9 100644
--- a/src/test/compile-fail/liveness-assign-imm-local-with-drop.rs
+++ b/src/test/compile-fail/liveness-assign-imm-local-with-drop.rs
@@ -14,6 +14,7 @@
 fn test() {
     let b = Box::new(1); //[ast]~ NOTE first assignment
                          //[mir]~^ NOTE first assignment
+                         //[mir]~| NOTE consider changing this to `mut b`
     drop(b);
     b = Box::new(2); //[ast]~ ERROR cannot assign twice to immutable variable
                      //[mir]~^ ERROR cannot assign twice to immutable variable `b`
diff --git a/src/test/compile-fail/liveness-assign-imm-local-with-init.rs b/src/test/compile-fail/liveness-assign-imm-local-with-init.rs
index 7204b5d5f2e..672e9fab837 100644
--- a/src/test/compile-fail/liveness-assign-imm-local-with-init.rs
+++ b/src/test/compile-fail/liveness-assign-imm-local-with-init.rs
@@ -14,6 +14,7 @@
 fn test() {
     let v: isize = 1; //[ast]~ NOTE first assignment
                       //[mir]~^ NOTE first assignment
+                      //[mir]~| NOTE consider changing this to `mut v`
     v.clone();
     v = 2; //[ast]~ ERROR cannot assign twice to immutable variable
            //[mir]~^ ERROR cannot assign twice to immutable variable `v`
diff --git a/src/test/compile-fail/unboxed-closures-mutated-upvar-from-fn-closure.rs b/src/test/compile-fail/unboxed-closures-mutated-upvar-from-fn-closure.rs
index 0dbd61413e0..f20719ec7fa 100644
--- a/src/test/compile-fail/unboxed-closures-mutated-upvar-from-fn-closure.rs
+++ b/src/test/compile-fail/unboxed-closures-mutated-upvar-from-fn-closure.rs
@@ -23,6 +23,6 @@ fn main() {
     call(|| {
         counter += 1;
         //[ast]~^ ERROR cannot assign to data in a captured outer variable in an `Fn` closure
-        //[mir]~^^ ERROR cannot assign to immutable item `counter`
+        //[mir]~^^ ERROR cannot assign to `counter`
     });
 }
diff --git a/src/test/ui/asm-out-assign-imm.nll.stderr b/src/test/ui/asm-out-assign-imm.nll.stderr
new file mode 100644
index 00000000000..fbd58cd4c22
--- /dev/null
+++ b/src/test/ui/asm-out-assign-imm.nll.stderr
@@ -0,0 +1,14 @@
+error[E0384]: cannot assign twice to immutable variable `x`
+  --> $DIR/asm-out-assign-imm.rs:33:9
+   |
+LL |     let x: isize;
+   |         - consider changing this to `mut x`
+LL |     x = 1;
+   |     ----- first assignment to `x`
+...
+LL |         asm!("mov $1, $0" : "=r"(x) : "r"(5));
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot assign twice to immutable variable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0384`.
diff --git a/src/test/ui/augmented-assignments.nll.stderr b/src/test/ui/augmented-assignments.nll.stderr
index deb2e7ed4a3..592f666eff8 100644
--- a/src/test/ui/augmented-assignments.nll.stderr
+++ b/src/test/ui/augmented-assignments.nll.stderr
@@ -17,6 +17,9 @@ LL | |     x;  //~ value moved here
 error[E0596]: cannot borrow immutable item `y` as mutable
   --> $DIR/augmented-assignments.rs:30:5
    |
+LL |     let y = Int(2);
+   |         - help: consider changing this to be mutable: `mut y`
+LL |     //~^ consider changing this to `mut y`
 LL |     y   //~ error: cannot borrow immutable local variable `y` as mutable
    |     ^ cannot borrow as mutable
 
diff --git a/src/test/ui/borrowck/immutable-arg.stderr b/src/test/ui/borrowck/immutable-arg.stderr
index b7506849b81..1cf68795bf0 100644
--- a/src/test/ui/borrowck/immutable-arg.stderr
+++ b/src/test/ui/borrowck/immutable-arg.stderr
@@ -10,7 +10,7 @@ error[E0384]: cannot assign to immutable argument `_x` (Mir)
   --> $DIR/immutable-arg.rs:14:5
    |
 LL | fn foo(_x: u32) {
-   |        -- argument not declared as `mut`
+   |        -- consider changing this to `mut _x`
 LL |     _x = 4;
    |     ^^^^^^ cannot assign to immutable argument
 
diff --git a/src/test/ui/borrowck/issue-45983.nll.stderr b/src/test/ui/borrowck/issue-45983.nll.stderr
index 1aec71fee34..a008a408d97 100644
--- a/src/test/ui/borrowck/issue-45983.nll.stderr
+++ b/src/test/ui/borrowck/issue-45983.nll.stderr
@@ -14,13 +14,13 @@ error[E0594]: cannot assign to immutable item `x`
   --> $DIR/issue-45983.rs:17:18
    |
 LL |     give_any(|y| x = Some(y));
-   |                  ^^^^^^^^^^^ cannot mutate
-   |
-   = note: the value which is causing this path not to be mutable is...: `x`
+   |                  ^^^^^^^^^^^ cannot assign
 
 error[E0596]: cannot borrow immutable item `x` as mutable
   --> $DIR/issue-45983.rs:17:14
    |
+LL |     let x = None;
+   |         - help: consider changing this to be mutable: `mut x`
 LL |     give_any(|y| x = Some(y));
    |              ^^^^^^^^^^^^^^^ cannot borrow as mutable
 
diff --git a/src/test/ui/borrowck/mut-borrow-of-mut-ref.nll.stderr b/src/test/ui/borrowck/mut-borrow-of-mut-ref.nll.stderr
index f8b84bce04e..0674c823016 100644
--- a/src/test/ui/borrowck/mut-borrow-of-mut-ref.nll.stderr
+++ b/src/test/ui/borrowck/mut-borrow-of-mut-ref.nll.stderr
@@ -1,6 +1,8 @@
 error[E0596]: cannot borrow immutable item `b` as mutable
   --> $DIR/mut-borrow-of-mut-ref.rs:18:7
    |
+LL | fn f(b: &mut i32) {
+   |      - help: consider changing this to be mutable: `mut b`
 LL |     g(&mut b) //~ ERROR cannot borrow
    |       ^^^^^^ cannot borrow as mutable
 
diff --git a/src/test/ui/codemap_tests/huge_multispan_highlight.nll.stderr b/src/test/ui/codemap_tests/huge_multispan_highlight.nll.stderr
index 4526616e488..da0b201f5d4 100644
--- a/src/test/ui/codemap_tests/huge_multispan_highlight.nll.stderr
+++ b/src/test/ui/codemap_tests/huge_multispan_highlight.nll.stderr
@@ -1,6 +1,9 @@
 error[E0596]: cannot borrow immutable item `x` as mutable
   --> $DIR/huge_multispan_highlight.rs:100:13
    |
+LL |     let x = "foo";
+   |         - help: consider changing this to be mutable: `mut x`
+...
 LL |     let y = &mut x; //~ ERROR cannot borrow
    |             ^^^^^^ cannot borrow as mutable
 
diff --git a/src/test/ui/command-line-diagnostics.nll.stderr b/src/test/ui/command-line-diagnostics.nll.stderr
index 2d5a31f0586..10dcf7d0e65 100644
--- a/src/test/ui/command-line-diagnostics.nll.stderr
+++ b/src/test/ui/command-line-diagnostics.nll.stderr
@@ -2,7 +2,9 @@ error[E0384]: cannot assign twice to immutable variable `x`
   --> $DIR/command-line-diagnostics.rs:16:5
    |
 LL |     let x = 42;
-   |             -- first assignment to `x`
+   |         -   -- first assignment to `x`
+   |         |
+   |         consider changing this to `mut x`
 LL |     x = 43;
    |     ^^^^^^ cannot assign twice to immutable variable
 
diff --git a/src/test/ui/did_you_mean/issue-31424.nll.stderr b/src/test/ui/did_you_mean/issue-31424.nll.stderr
index 6b63f64c699..21c5e3608c0 100644
--- a/src/test/ui/did_you_mean/issue-31424.nll.stderr
+++ b/src/test/ui/did_you_mean/issue-31424.nll.stderr
@@ -7,6 +7,8 @@ LL |         (&mut self).bar(); //~ ERROR cannot borrow
 error[E0596]: cannot borrow immutable item `self` as mutable
   --> $DIR/issue-31424.rs:23:9
    |
+LL |     fn bar(self: &mut Self) {
+   |            ---- help: consider changing this to be mutable: `mut self`
 LL |         (&mut self).bar(); //~ ERROR cannot borrow
    |         ^^^^^^^^^^^ cannot borrow as mutable
 
diff --git a/src/test/ui/did_you_mean/issue-34126.nll.stderr b/src/test/ui/did_you_mean/issue-34126.nll.stderr
index 81f858f6bfc..8dedb6ec4db 100644
--- a/src/test/ui/did_you_mean/issue-34126.nll.stderr
+++ b/src/test/ui/did_you_mean/issue-34126.nll.stderr
@@ -2,7 +2,10 @@ error[E0596]: cannot borrow immutable item `self` as mutable
   --> $DIR/issue-34126.rs:16:18
    |
 LL |         self.run(&mut self); //~ ERROR cannot borrow
-   |                  ^^^^^^^^^ cannot borrow as mutable
+   |                  ^^^^^^^^^
+   |                  |
+   |                  cannot borrow as mutable
+   |                  try removing `&mut` here
 
 error[E0502]: cannot borrow `self` as mutable because it is also borrowed as immutable
   --> $DIR/issue-34126.rs:16:18
diff --git a/src/test/ui/did_you_mean/issue-34337.nll.stderr b/src/test/ui/did_you_mean/issue-34337.nll.stderr
index 258e1bb1ad7..d2271e8e7de 100644
--- a/src/test/ui/did_you_mean/issue-34337.nll.stderr
+++ b/src/test/ui/did_you_mean/issue-34337.nll.stderr
@@ -2,7 +2,10 @@ error[E0596]: cannot borrow immutable item `key` as mutable
   --> $DIR/issue-34337.rs:16:9
    |
 LL |     get(&mut key); //~ ERROR cannot borrow
-   |         ^^^^^^^^ cannot borrow as mutable
+   |         ^^^^^^^^
+   |         |
+   |         cannot borrow as mutable
+   |         try removing `&mut` here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/did_you_mean/issue-35937.nll.stderr b/src/test/ui/did_you_mean/issue-35937.nll.stderr
index 40b640b63cf..0c1dcb29d4d 100644
--- a/src/test/ui/did_you_mean/issue-35937.nll.stderr
+++ b/src/test/ui/did_you_mean/issue-35937.nll.stderr
@@ -1,16 +1,18 @@
 error[E0596]: cannot borrow immutable item `f.v` as mutable
   --> $DIR/issue-35937.rs:17:5
    |
+LL |     let f = Foo { v: Vec::new() };
+   |         - help: consider changing this to be mutable: `mut f`
 LL |     f.v.push("cat".to_string()); //~ ERROR cannot borrow
    |     ^^^ cannot borrow as mutable
-   |
-   = note: the value which is causing this path not to be mutable is...: `f`
 
 error[E0384]: cannot assign twice to immutable variable `s.x`
   --> $DIR/issue-35937.rs:26:5
    |
 LL |     let s = S { x: 42 };
-   |             ----------- first assignment to `s.x`
+   |         -   ----------- first assignment to `s.x`
+   |         |
+   |         consider changing this to `mut s`
 LL |     s.x += 1; //~ ERROR cannot assign
    |     ^^^^^^^^ cannot assign twice to immutable variable
 
@@ -18,7 +20,10 @@ error[E0384]: cannot assign twice to immutable variable `s.x`
   --> $DIR/issue-35937.rs:30:5
    |
 LL | fn bar(s: S) {
-   |        - first assignment to `s.x`
+   |        -
+   |        |
+   |        first assignment to `s.x`
+   |        consider changing this to `mut s`
 LL |     s.x += 1; //~ ERROR cannot assign
    |     ^^^^^^^^ cannot assign twice to immutable variable
 
diff --git a/src/test/ui/did_you_mean/issue-37139.nll.stderr b/src/test/ui/did_you_mean/issue-37139.nll.stderr
index 29c7192a98b..e51a1baad25 100644
--- a/src/test/ui/did_you_mean/issue-37139.nll.stderr
+++ b/src/test/ui/did_you_mean/issue-37139.nll.stderr
@@ -2,7 +2,10 @@ error[E0596]: cannot borrow immutable item `x` as mutable
   --> $DIR/issue-37139.rs:22:18
    |
 LL |             test(&mut x); //~ ERROR cannot borrow immutable
-   |                  ^^^^^^ cannot borrow as mutable
+   |                  ^^^^^^
+   |                  |
+   |                  cannot borrow as mutable
+   |                  try removing `&mut` here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/did_you_mean/issue-38147-1.nll.stderr b/src/test/ui/did_you_mean/issue-38147-1.nll.stderr
index 8e442677951..76b8c8ebf60 100644
--- a/src/test/ui/did_you_mean/issue-38147-1.nll.stderr
+++ b/src/test/ui/did_you_mean/issue-38147-1.nll.stderr
@@ -1,10 +1,10 @@
 error[E0596]: cannot borrow immutable item `*self.s` as mutable
   --> $DIR/issue-38147-1.rs:27:9
    |
+LL |     fn f(&self) {
+   |          ----- help: consider changing this to be a mutable reference: `&mut Foo<'_>`
 LL |         self.s.push('x'); //~ ERROR cannot borrow data mutably
-   |         ^^^^^^ cannot borrow as mutable
-   |
-   = note: the value which is causing this path not to be mutable is...: `*self`
+   |         ^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/did_you_mean/issue-38147-4.nll.stderr b/src/test/ui/did_you_mean/issue-38147-4.nll.stderr
index 6808222cc32..c875957623b 100644
--- a/src/test/ui/did_you_mean/issue-38147-4.nll.stderr
+++ b/src/test/ui/did_you_mean/issue-38147-4.nll.stderr
@@ -1,10 +1,10 @@
 error[E0596]: cannot borrow immutable item `*f.s` as mutable
   --> $DIR/issue-38147-4.rs:16:5
    |
+LL | fn f(x: usize, f: &Foo) {
+   |                   ---- help: consider changing this to be a mutable reference: `&mut Foo<'_>`
 LL |     f.s.push('x'); //~ ERROR cannot borrow data mutably
-   |     ^^^ cannot borrow as mutable
-   |
-   = note: the value which is causing this path not to be mutable is...: `*f`
+   |     ^^^ `f` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/did_you_mean/issue-39544.nll.stderr b/src/test/ui/did_you_mean/issue-39544.nll.stderr
index f5f5b675e77..02c1debca69 100644
--- a/src/test/ui/did_you_mean/issue-39544.nll.stderr
+++ b/src/test/ui/did_you_mean/issue-39544.nll.stderr
@@ -1,96 +1,100 @@
 error[E0596]: cannot borrow immutable item `z.x` as mutable
   --> $DIR/issue-39544.rs:21:13
    |
+LL |     let z = Z { x: X::Y };
+   |         - help: consider changing this to be mutable: `mut z`
 LL |     let _ = &mut z.x; //~ ERROR cannot borrow
    |             ^^^^^^^^ cannot borrow as mutable
-   |
-   = note: the value which is causing this path not to be mutable is...: `z`
 
 error[E0596]: cannot borrow immutable item `self.x` as mutable
   --> $DIR/issue-39544.rs:26:17
    |
+LL |     fn foo<'z>(&'z self) {
+   |                -------- help: consider changing this to be a mutable reference: `&mut Z`
 LL |         let _ = &mut self.x; //~ ERROR cannot borrow
-   |                 ^^^^^^^^^^^ cannot borrow as mutable
-   |
-   = note: the value which is causing this path not to be mutable is...: `*self`
+   |                 ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error[E0596]: cannot borrow immutable item `self.x` as mutable
   --> $DIR/issue-39544.rs:30:17
    |
+LL |     fn foo1(&self, other: &Z) {
+   |             ----- help: consider changing this to be a mutable reference: `&mut Z`
 LL |         let _ = &mut self.x; //~ ERROR cannot borrow
-   |                 ^^^^^^^^^^^ cannot borrow as mutable
-   |
-   = note: the value which is causing this path not to be mutable is...: `*self`
+   |                 ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error[E0596]: cannot borrow immutable item `other.x` as mutable
   --> $DIR/issue-39544.rs:31:17
    |
+LL |     fn foo1(&self, other: &Z) {
+   |                           -- help: consider changing this to be a mutable reference: `&mut Z`
+LL |         let _ = &mut self.x; //~ ERROR cannot borrow
 LL |         let _ = &mut other.x; //~ ERROR cannot borrow
-   |                 ^^^^^^^^^^^^ cannot borrow as mutable
-   |
-   = note: the value which is causing this path not to be mutable is...: `*other`
+   |                 ^^^^^^^^^^^^ `other` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error[E0596]: cannot borrow immutable item `self.x` as mutable
   --> $DIR/issue-39544.rs:35:17
    |
+LL |     fn foo2<'a>(&'a self, other: &Z) {
+   |                 -------- help: consider changing this to be a mutable reference: `&mut Z`
 LL |         let _ = &mut self.x; //~ ERROR cannot borrow
-   |                 ^^^^^^^^^^^ cannot borrow as mutable
-   |
-   = note: the value which is causing this path not to be mutable is...: `*self`
+   |                 ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error[E0596]: cannot borrow immutable item `other.x` as mutable
   --> $DIR/issue-39544.rs:36:17
    |
+LL |     fn foo2<'a>(&'a self, other: &Z) {
+   |                                  -- help: consider changing this to be a mutable reference: `&mut Z`
+LL |         let _ = &mut self.x; //~ ERROR cannot borrow
 LL |         let _ = &mut other.x; //~ ERROR cannot borrow
-   |                 ^^^^^^^^^^^^ cannot borrow as mutable
-   |
-   = note: the value which is causing this path not to be mutable is...: `*other`
+   |                 ^^^^^^^^^^^^ `other` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error[E0596]: cannot borrow immutable item `self.x` as mutable
   --> $DIR/issue-39544.rs:40:17
    |
+LL |     fn foo3<'a>(self: &'a Self, other: &Z) {
+   |                       -------- help: consider changing this to be a mutable reference: `&mut Z`
 LL |         let _ = &mut self.x; //~ ERROR cannot borrow
-   |                 ^^^^^^^^^^^ cannot borrow as mutable
-   |
-   = note: the value which is causing this path not to be mutable is...: `*self`
+   |                 ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error[E0596]: cannot borrow immutable item `other.x` as mutable
   --> $DIR/issue-39544.rs:41:17
    |
+LL |     fn foo3<'a>(self: &'a Self, other: &Z) {
+   |                                        -- help: consider changing this to be a mutable reference: `&mut Z`
+LL |         let _ = &mut self.x; //~ ERROR cannot borrow
 LL |         let _ = &mut other.x; //~ ERROR cannot borrow
-   |                 ^^^^^^^^^^^^ cannot borrow as mutable
-   |
-   = note: the value which is causing this path not to be mutable is...: `*other`
+   |                 ^^^^^^^^^^^^ `other` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error[E0596]: cannot borrow immutable item `other.x` as mutable
   --> $DIR/issue-39544.rs:45:17
    |
+LL |     fn foo4(other: &Z) {
+   |                    -- help: consider changing this to be a mutable reference: `&mut Z`
 LL |         let _ = &mut other.x; //~ ERROR cannot borrow
-   |                 ^^^^^^^^^^^^ cannot borrow as mutable
-   |
-   = note: the value which is causing this path not to be mutable is...: `*other`
+   |                 ^^^^^^^^^^^^ `other` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error[E0596]: cannot borrow immutable item `z.x` as mutable
   --> $DIR/issue-39544.rs:51:13
    |
+LL | pub fn with_arg(z: Z, w: &Z) {
+   |                 - help: consider changing this to be mutable: `mut z`
 LL |     let _ = &mut z.x; //~ ERROR cannot borrow
    |             ^^^^^^^^ cannot borrow as mutable
-   |
-   = note: the value which is causing this path not to be mutable is...: `z`
 
 error[E0596]: cannot borrow immutable item `w.x` as mutable
   --> $DIR/issue-39544.rs:52:13
    |
+LL | pub fn with_arg(z: Z, w: &Z) {
+   |                          -- help: consider changing this to be a mutable reference: `&mut Z`
+LL |     let _ = &mut z.x; //~ ERROR cannot borrow
 LL |     let _ = &mut w.x; //~ ERROR cannot borrow
-   |             ^^^^^^^^ cannot borrow as mutable
-   |
-   = note: the value which is causing this path not to be mutable is...: `*w`
+   |             ^^^^^^^^ `w` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
-error[E0594]: cannot assign to immutable item `*x.0`
+error[E0594]: cannot assign to `*x.0` which is behind a `&` reference
   --> $DIR/issue-39544.rs:58:5
    |
 LL |     *x.0 = 1;
-   |     ^^^^^^^^ cannot mutate
+   |     ^^^^^^^^ cannot assign
 
 error: aborting due to 12 previous errors
 
diff --git a/src/test/ui/did_you_mean/issue-40823.nll.stderr b/src/test/ui/did_you_mean/issue-40823.nll.stderr
index 489e1c39c46..1fd75de8128 100644
--- a/src/test/ui/did_you_mean/issue-40823.nll.stderr
+++ b/src/test/ui/did_you_mean/issue-40823.nll.stderr
@@ -1,8 +1,10 @@
 error[E0596]: cannot borrow immutable item `*buf` as mutable
   --> $DIR/issue-40823.rs:13:5
    |
+LL |     let mut buf = &[1, 2, 3, 4];
+   |                   ------------- help: consider changing this to be a mutable reference: `&mut [1, 2, 3, 4]`
 LL |     buf.iter_mut(); //~ ERROR cannot borrow immutable borrowed content
-   |     ^^^ cannot borrow as mutable
+   |     ^^^ `buf` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0389.nll.stderr b/src/test/ui/error-codes/E0389.nll.stderr
index 0525e16239d..66e46dfe29d 100644
--- a/src/test/ui/error-codes/E0389.nll.stderr
+++ b/src/test/ui/error-codes/E0389.nll.stderr
@@ -1,4 +1,4 @@
-error[E0594]: cannot assign to data in a `&` reference
+error[E0594]: cannot assign to `fancy_ref.num` which is behind a `&` reference
   --> $DIR/E0389.rs:18:5
    |
 LL |     let fancy_ref = &(&mut fancy);
diff --git a/src/test/ui/issue-36400.nll.stderr b/src/test/ui/issue-36400.nll.stderr
index 80459937479..be10b1d517b 100644
--- a/src/test/ui/issue-36400.nll.stderr
+++ b/src/test/ui/issue-36400.nll.stderr
@@ -1,10 +1,10 @@
 error[E0596]: cannot borrow immutable item `*x` as mutable
   --> $DIR/issue-36400.rs:15:7
    |
+LL |     let x = Box::new(3);
+   |         - help: consider changing this to be mutable: `mut x`
 LL |     f(&mut *x); //~ ERROR cannot borrow immutable
    |       ^^^^^^^ cannot borrow as mutable
-   |
-   = note: the value which is causing this path not to be mutable is...: `x`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.nll.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.nll.stderr
index 9d6d68f518d..93f2837c0fc 100644
--- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.nll.stderr
+++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.nll.stderr
@@ -18,7 +18,7 @@ error[E0384]: cannot assign to immutable argument `y`
   --> $DIR/ex3-both-anon-regions-one-is-struct-2.rs:14:5
    |
 LL | fn foo(mut x: Ref, y: &u32) {
-   |                    - argument not declared as `mut`
+   |                    - consider changing this to `mut y`
 LL |     y = x.b; //~ ERROR lifetime mismatch
    |     ^^^^^^^ cannot assign to immutable argument
 
diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-fn-items.nll.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-fn-items.nll.stderr
index f58f33c9a9a..01e26980323 100644
--- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-fn-items.nll.stderr
+++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-fn-items.nll.stderr
@@ -15,6 +15,8 @@ LL |   y.push(z); //~ ERROR lifetime mismatch
 error[E0596]: cannot borrow immutable item `y` as mutable
   --> $DIR/ex3-both-anon-regions-using-fn-items.rs:11: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); //~ ERROR lifetime mismatch
    |   ^ cannot borrow as mutable
 
diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-trait-objects.nll.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-trait-objects.nll.stderr
index 4bfb4ac2833..a61d49fc953 100644
--- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-trait-objects.nll.stderr
+++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-trait-objects.nll.stderr
@@ -15,6 +15,8 @@ LL |   y.push(z); //~ ERROR lifetime mismatch
 error[E0596]: cannot borrow immutable item `y` as mutable
   --> $DIR/ex3-both-anon-regions-using-trait-objects.rs:11:3
    |
+LL | fn foo(x:Box<Fn(&u8, &u8)> , y: Vec<&u8>, z: &u8) {
+   |                              - help: consider changing this to be mutable: `mut y`
 LL |   y.push(z); //~ ERROR lifetime mismatch
    |   ^ cannot borrow as mutable
 
diff --git a/src/test/ui/lifetime-errors/liveness-assign-imm-local-notes.stderr b/src/test/ui/lifetime-errors/liveness-assign-imm-local-notes.stderr
index 43743118966..0620235371a 100644
--- a/src/test/ui/lifetime-errors/liveness-assign-imm-local-notes.stderr
+++ b/src/test/ui/lifetime-errors/liveness-assign-imm-local-notes.stderr
@@ -32,6 +32,9 @@ LL |             x = 2;      //~ ERROR (Ast) [E0384]
 error[E0384]: cannot assign twice to immutable variable `x` (Mir)
   --> $DIR/liveness-assign-imm-local-notes.rs:23:9
    |
+LL |     let x;
+   |         - consider changing this to `mut x`
+...
 LL |         x = 2;
    |         ----- first assignment to `x`
 LL |         x = 3;      //~ ERROR (Ast) [E0384]
@@ -40,6 +43,9 @@ LL |         x = 3;      //~ ERROR (Ast) [E0384]
 error[E0384]: cannot assign twice to immutable variable `x` (Mir)
   --> $DIR/liveness-assign-imm-local-notes.rs:35:13
    |
+LL |         let x;
+   |             - consider changing this to `mut x`
+...
 LL |             x = 2;
    |             ----- first assignment to `x`
 LL |             x = 3;      //~ ERROR (Ast) [E0384]
@@ -48,12 +54,18 @@ LL |             x = 3;      //~ ERROR (Ast) [E0384]
 error[E0384]: cannot assign twice to immutable variable `x` (Mir)
   --> $DIR/liveness-assign-imm-local-notes.rs:45:13
    |
+LL |     let x;
+   |         - consider changing this to `mut x`
+...
 LL |             x = 1;      //~ ERROR (Ast) [E0384]
    |             ^^^^^ cannot assign twice to immutable variable
 
 error[E0384]: cannot assign twice to immutable variable `x` (Mir)
   --> $DIR/liveness-assign-imm-local-notes.rs:48:13
    |
+LL |     let x;
+   |         - consider changing this to `mut x`
+...
 LL |             x = 1;      //~ ERROR (Ast) [E0384]
    |             ----- first assignment to `x`
 ...
diff --git a/src/test/ui/macros/span-covering-argument-1.nll.stderr b/src/test/ui/macros/span-covering-argument-1.nll.stderr
index a12baab4159..213eddee720 100644
--- a/src/test/ui/macros/span-covering-argument-1.nll.stderr
+++ b/src/test/ui/macros/span-covering-argument-1.nll.stderr
@@ -1,6 +1,8 @@
 error[E0596]: cannot borrow immutable item `foo` as mutable
   --> $DIR/span-covering-argument-1.rs:15:14
    |
+LL |             let $s = 0;
+   |                 -- help: consider changing this to be mutable: `mut foo`
 LL |             *&mut $s = 0;
    |              ^^^^^^^ cannot borrow as mutable
 ...
diff --git a/src/test/ui/nll/issue-47388.stderr b/src/test/ui/nll/issue-47388.stderr
index f3952c49a2a..96e9f155414 100644
--- a/src/test/ui/nll/issue-47388.stderr
+++ b/src/test/ui/nll/issue-47388.stderr
@@ -1,4 +1,4 @@
-error[E0594]: cannot assign to data in a `&` reference
+error[E0594]: cannot assign to `fancy_ref.num` which is behind a `&` reference
   --> $DIR/issue-47388.rs:18:5
    |
 LL |     let fancy_ref = &(&mut fancy);
diff --git a/src/test/ui/reassign-ref-mut.rs b/src/test/ui/reassign-ref-mut.rs
new file mode 100644
index 00000000000..c045720a840
--- /dev/null
+++ b/src/test/ui/reassign-ref-mut.rs
@@ -0,0 +1,26 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Tests how we behave when the user attempts to mutate an immutable
+// binding that was introduced by either `ref` or `ref mut`
+// patterns.
+//
+// Such bindings cannot be made mutable via the mere addition of the
+// `mut` keyword, and thus we want to check that the compiler does not
+// suggest doing so.
+
+fn main() {
+    let (mut one_two, mut three_four) = ((1, 2), (3, 4));
+    let &mut (ref a, ref mut b) = &mut one_two;
+    a = &three_four.0;
+    //~^ ERROR cannot assign twice to immutable variable `a` [E0384]
+    b = &mut three_four.1;
+    //~^ ERROR cannot assign twice to immutable variable `b` [E0384]
+}
diff --git a/src/test/ui/reassign-ref-mut.stderr b/src/test/ui/reassign-ref-mut.stderr
new file mode 100644
index 00000000000..bf627dde720
--- /dev/null
+++ b/src/test/ui/reassign-ref-mut.stderr
@@ -0,0 +1,20 @@
+error[E0384]: cannot assign twice to immutable variable `a`
+  --> $DIR/reassign-ref-mut.rs:22:5
+   |
+LL |     let &mut (ref a, ref mut b) = &mut one_two;
+   |               ----- first assignment to `a`
+LL |     a = &three_four.0;
+   |     ^^^^^^^^^^^^^^^^^ cannot assign twice to immutable variable
+
+error[E0384]: cannot assign twice to immutable variable `b`
+  --> $DIR/reassign-ref-mut.rs:24:5
+   |
+LL |     let &mut (ref a, ref mut b) = &mut one_two;
+   |                      --------- first assignment to `b`
+...
+LL |     b = &mut three_four.1;
+   |     ^^^^^^^^^^^^^^^^^^^^^ cannot assign twice to immutable variable
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0384`.
diff --git a/src/test/ui/rfc-2005-default-binding-mode/enum.nll.stderr b/src/test/ui/rfc-2005-default-binding-mode/enum.nll.stderr
index b97bdeea409..8aa7e8a417c 100644
--- a/src/test/ui/rfc-2005-default-binding-mode/enum.nll.stderr
+++ b/src/test/ui/rfc-2005-default-binding-mode/enum.nll.stderr
@@ -1,26 +1,20 @@
-error[E0594]: cannot assign to data in a `&` reference
+error[E0594]: cannot assign to `*x` which is behind a `&` reference
   --> $DIR/enum.rs:19:5
    |
-LL |     let Wrap(x) = &Wrap(3);
-   |              - help: consider changing this to be a mutable reference: `&mut`
 LL |     *x += 1; //~ ERROR cannot assign to immutable
-   |     ^^^^^^^
+   |     ^^^^^^^ cannot assign
 
-error[E0594]: cannot assign to data in a `&` reference
+error[E0594]: cannot assign to `*x` which is behind a `&` reference
   --> $DIR/enum.rs:23:9
    |
-LL |     if let Some(x) = &Some(3) {
-   |                 - help: consider changing this to be a mutable reference: `&mut`
 LL |         *x += 1; //~ ERROR cannot assign to immutable
-   |         ^^^^^^^
+   |         ^^^^^^^ cannot assign
 
-error[E0594]: cannot assign to data in a `&` reference
+error[E0594]: cannot assign to `*x` which is behind a `&` reference
   --> $DIR/enum.rs:29:9
    |
-LL |     while let Some(x) = &Some(3) {
-   |                    - help: consider changing this to be a mutable reference: `&mut`
 LL |         *x += 1; //~ ERROR cannot assign to immutable
-   |         ^^^^^^^
+   |         ^^^^^^^ cannot assign
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.nll.stderr b/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.nll.stderr
index 3ee4dc07bb8..4e00dec7616 100644
--- a/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.nll.stderr
+++ b/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.nll.stderr
@@ -1,26 +1,20 @@
-error[E0594]: cannot assign to data in a `&` reference
+error[E0594]: cannot assign to `*n` which is behind a `&` reference
   --> $DIR/explicit-mut.rs:17:13
    |
-LL |         Some(n) => {
-   |              - help: consider changing this to be a mutable reference: `&mut`
 LL |             *n += 1; //~ ERROR cannot assign to immutable
-   |             ^^^^^^^
+   |             ^^^^^^^ cannot assign
 
-error[E0594]: cannot assign to data in a `&` reference
+error[E0594]: cannot assign to `*n` which is behind a `&` reference
   --> $DIR/explicit-mut.rs:25:13
    |
-LL |         Some(n) => {
-   |              - help: consider changing this to be a mutable reference: `&mut`
 LL |             *n += 1; //~ ERROR cannot assign to immutable
-   |             ^^^^^^^
+   |             ^^^^^^^ cannot assign
 
-error[E0594]: cannot assign to data in a `&` reference
+error[E0594]: cannot assign to `*n` which is behind a `&` reference
   --> $DIR/explicit-mut.rs:33:13
    |
-LL |         Some(n) => {
-   |              - help: consider changing this to be a mutable reference: `&mut`
 LL |             *n += 1; //~ ERROR cannot assign to immutable
-   |             ^^^^^^^
+   |             ^^^^^^^ cannot assign
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.nll.stderr b/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.nll.stderr
index 172828b9a40..3282fbba6c5 100644
--- a/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.nll.stderr
+++ b/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.nll.stderr
@@ -1,50 +1,66 @@
 error[E0596]: cannot borrow immutable item `x` as mutable
   --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:63:24
    |
+LL | fn deref_mut_field1(x: Own<Point>) {
+   |                     - help: consider changing this to be mutable: `mut x`
 LL |     let __isize = &mut x.y; //~ ERROR cannot borrow
    |                        ^ cannot borrow as mutable
 
 error[E0596]: cannot borrow immutable item `*x` as mutable
   --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:75:10
    |
+LL | fn deref_extend_mut_field1(x: &Own<Point>) -> &mut isize {
+   |                               ----------- help: consider changing this to be a mutable reference: `&mut Own<Point>`
 LL |     &mut x.y //~ ERROR cannot borrow
-   |          ^ cannot borrow as mutable
+   |          ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error[E0596]: cannot borrow immutable item `x` as mutable
   --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:98:5
    |
+LL | fn assign_field1<'a>(x: Own<Point>) {
+   |                      - help: consider changing this to be mutable: `mut x`
 LL |     x.y = 3; //~ ERROR cannot borrow
    |     ^ cannot borrow as mutable
 
 error[E0596]: cannot borrow immutable item `*x` as mutable
   --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:102:5
    |
+LL | fn assign_field2<'a>(x: &'a Own<Point>) {
+   |                         -------------- help: consider changing this to be a mutable reference: `&mut Own<Point>`
 LL |     x.y = 3; //~ ERROR cannot borrow
-   |     ^ cannot borrow as mutable
+   |     ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error[E0596]: cannot borrow immutable item `x` as mutable
   --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:119:5
    |
+LL | fn deref_mut_method1(x: Own<Point>) {
+   |                      - help: consider changing this to be mutable: `mut x`
 LL |     x.set(0, 0); //~ ERROR cannot borrow
    |     ^ cannot borrow as mutable
 
 error[E0596]: cannot borrow immutable item `*x` as mutable
   --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:131:5
    |
+LL | fn deref_extend_mut_method1(x: &Own<Point>) -> &mut isize {
+   |                                ----------- help: consider changing this to be a mutable reference: `&mut Own<Point>`
 LL |     x.y_mut() //~ ERROR cannot borrow
-   |     ^ cannot borrow as mutable
+   |     ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error[E0596]: cannot borrow immutable item `x` as mutable
   --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:139:6
    |
+LL | fn assign_method1<'a>(x: Own<Point>) {
+   |                       - help: consider changing this to be mutable: `mut x`
 LL |     *x.y_mut() = 3; //~ ERROR cannot borrow
    |      ^ cannot borrow as mutable
 
 error[E0596]: cannot borrow immutable item `*x` as mutable
   --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:143:6
    |
+LL | fn assign_method2<'a>(x: &'a Own<Point>) {
+   |                          -------------- help: consider changing this to be a mutable reference: `&mut Own<Point>`
 LL |     *x.y_mut() = 3; //~ ERROR cannot borrow
-   |      ^ cannot borrow as mutable
+   |      ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error: aborting due to 8 previous errors
 
diff --git a/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.nll.stderr b/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.nll.stderr
index 24abe85de76..0b1bfd8cee6 100644
--- a/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.nll.stderr
+++ b/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.nll.stderr
@@ -1,26 +1,34 @@
 error[E0596]: cannot borrow immutable item `x` as mutable
   --> $DIR/borrowck-borrow-overloaded-deref-mut.rs:39:25
    |
+LL | fn deref_mut1(x: Own<isize>) {
+   |               - help: consider changing this to be mutable: `mut x`
 LL |     let __isize = &mut *x; //~ ERROR cannot borrow
    |                         ^ cannot borrow as mutable
 
 error[E0596]: cannot borrow immutable item `*x` as mutable
   --> $DIR/borrowck-borrow-overloaded-deref-mut.rs:51:11
    |
+LL | fn deref_extend_mut1<'a>(x: &'a Own<isize>) -> &'a mut isize {
+   |                             -------------- help: consider changing this to be a mutable reference: `&mut Own<isize>`
 LL |     &mut **x //~ ERROR cannot borrow
-   |           ^^ cannot borrow as mutable
+   |           ^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error[E0596]: cannot borrow immutable item `x` as mutable
   --> $DIR/borrowck-borrow-overloaded-deref-mut.rs:59:6
    |
+LL | fn assign1<'a>(x: Own<isize>) {
+   |                - help: consider changing this to be mutable: `mut x`
 LL |     *x = 3; //~ ERROR cannot borrow
    |      ^ cannot borrow as mutable
 
 error[E0596]: cannot borrow immutable item `*x` as mutable
   --> $DIR/borrowck-borrow-overloaded-deref-mut.rs:63:6
    |
+LL | fn assign2<'a>(x: &'a Own<isize>) {
+   |                   -------------- help: consider changing this to be a mutable reference: `&mut Own<isize>`
 LL |     **x = 3; //~ ERROR cannot borrow
-   |      ^^ cannot borrow as mutable
+   |      ^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.nll.stderr b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.nll.stderr
index 26e9ea4dc0b..c4bdef21de4 100644
--- a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.nll.stderr
+++ b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.nll.stderr
@@ -15,16 +15,18 @@ LL | |     }));
 error[E0596]: cannot borrow immutable item `*f` as mutable
   --> $DIR/borrowck-call-is-borrow-issue-12224.rs:35:5
    |
+LL | fn test2<F>(f: &F) where F: FnMut() {
+   |                -- help: consider changing this to be a mutable reference: `&mut F`
 LL |     (*f)();
-   |     ^^^^ cannot borrow as mutable
+   |     ^^^^ `f` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error[E0596]: cannot borrow immutable item `*f.f` as mutable
   --> $DIR/borrowck-call-is-borrow-issue-12224.rs:44:5
    |
+LL | fn test4(f: &Test) {
+   |             ----- help: consider changing this to be a mutable reference: `&mut Test<'_>`
 LL |     f.f.call_mut(())
-   |     ^^^ cannot borrow as mutable
-   |
-   = note: the value which is causing this path not to be mutable is...: `*f`
+   |     ^^^ `f` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error[E0507]: cannot move out of borrowed content
   --> $DIR/borrowck-call-is-borrow-issue-12224.rs:66:13
diff --git a/src/test/ui/span/borrowck-call-method-from-mut-aliasable.nll.stderr b/src/test/ui/span/borrowck-call-method-from-mut-aliasable.nll.stderr
index 43934bf4aee..0bc614589e3 100644
--- a/src/test/ui/span/borrowck-call-method-from-mut-aliasable.nll.stderr
+++ b/src/test/ui/span/borrowck-call-method-from-mut-aliasable.nll.stderr
@@ -1,8 +1,11 @@
 error[E0596]: cannot borrow immutable item `*x` as mutable
   --> $DIR/borrowck-call-method-from-mut-aliasable.rs:27:5
    |
+LL | fn b(x: &Foo) {
+   |         ---- help: consider changing this to be a mutable reference: `&mut Foo`
+LL |     x.f();
 LL |     x.h(); //~ ERROR cannot borrow
-   |     ^ cannot borrow as mutable
+   |     ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/span/borrowck-fn-in-const-b.nll.stderr b/src/test/ui/span/borrowck-fn-in-const-b.nll.stderr
index d3c6fd66599..1cb2c92833c 100644
--- a/src/test/ui/span/borrowck-fn-in-const-b.nll.stderr
+++ b/src/test/ui/span/borrowck-fn-in-const-b.nll.stderr
@@ -1,8 +1,10 @@
 error[E0596]: cannot borrow immutable item `*x` as mutable
   --> $DIR/borrowck-fn-in-const-b.rs:17:9
    |
+LL |     fn broken(x: &Vec<String>) {
+   |                  ------------ help: consider changing this to be a mutable reference: `&mut std::vec::Vec<std::string::String>`
 LL |         x.push(format!("this is broken"));
-   |         ^ cannot borrow as mutable
+   |         ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/span/borrowck-object-mutability.nll.stderr b/src/test/ui/span/borrowck-object-mutability.nll.stderr
index 9b5e084bd37..cf615eed556 100644
--- a/src/test/ui/span/borrowck-object-mutability.nll.stderr
+++ b/src/test/ui/span/borrowck-object-mutability.nll.stderr
@@ -1,16 +1,20 @@
 error[E0596]: cannot borrow immutable item `*x` as mutable
   --> $DIR/borrowck-object-mutability.rs:19:5
    |
+LL | fn borrowed_receiver(x: &Foo) {
+   |                         ---- help: consider changing this to be a mutable reference: `&mut Foo`
+LL |     x.borrowed();
 LL |     x.borrowed_mut(); //~ ERROR cannot borrow
-   |     ^ cannot borrow as mutable
+   |     ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error[E0596]: cannot borrow immutable item `*x` as mutable
   --> $DIR/borrowck-object-mutability.rs:29:5
    |
+LL | fn owned_receiver(x: Box<Foo>) {
+   |                   - help: consider changing this to be mutable: `mut x`
+LL |     x.borrowed();
 LL |     x.borrowed_mut(); //~ ERROR cannot borrow
    |     ^ cannot borrow as mutable
-   |
-   = note: the value which is causing this path not to be mutable is...: `x`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/span/mut-arg-hint.nll.stderr b/src/test/ui/span/mut-arg-hint.nll.stderr
index 8e1cb9720e2..cd19059fdae 100644
--- a/src/test/ui/span/mut-arg-hint.nll.stderr
+++ b/src/test/ui/span/mut-arg-hint.nll.stderr
@@ -1,20 +1,26 @@
 error[E0596]: cannot borrow immutable item `*a` as mutable
   --> $DIR/mut-arg-hint.rs:13:9
    |
+LL |     fn foo(mut a: &String) {
+   |                   ------- help: consider changing this to be a mutable reference: `&mut std::string::String`
 LL |         a.push_str("bar"); //~ ERROR cannot borrow immutable borrowed content
-   |         ^ cannot borrow as mutable
+   |         ^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error[E0596]: cannot borrow immutable item `*a` as mutable
   --> $DIR/mut-arg-hint.rs:18:5
    |
+LL | pub fn foo<'a>(mut a: &'a String) {
+   |                       ---------- help: consider changing this to be a mutable reference: `&mut std::string::String`
 LL |     a.push_str("foo"); //~ ERROR cannot borrow immutable borrowed content
-   |     ^ cannot borrow as mutable
+   |     ^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error[E0596]: cannot borrow immutable item `*a` as mutable
   --> $DIR/mut-arg-hint.rs:25:9
    |
+LL |     pub fn foo(mut a: &String) {
+   |                       ------- help: consider changing this to be a mutable reference: `&mut std::string::String`
 LL |         a.push_str("foo"); //~ ERROR cannot borrow immutable borrowed content
-   |         ^ cannot borrow as mutable
+   |         ^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/suggestions/closure-immutable-outer-variable.nll.stderr b/src/test/ui/suggestions/closure-immutable-outer-variable.nll.stderr
index bc655114c2b..335ccefe8a0 100644
--- a/src/test/ui/suggestions/closure-immutable-outer-variable.nll.stderr
+++ b/src/test/ui/suggestions/closure-immutable-outer-variable.nll.stderr
@@ -2,7 +2,7 @@ error[E0594]: cannot assign to immutable item `y`
   --> $DIR/closure-immutable-outer-variable.rs:21:26
    |
 LL |     foo(Box::new(move || y = false) as Box<_>); //~ ERROR cannot assign to captured outer variable
-   |                          ^^^^^^^^^ cannot mutate
+   |                          ^^^^^^^^^ cannot assign
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/fn-closure-mutable-capture.nll.stderr b/src/test/ui/suggestions/fn-closure-mutable-capture.nll.stderr
index ed691843f9b..7ef21d3720d 100644
--- a/src/test/ui/suggestions/fn-closure-mutable-capture.nll.stderr
+++ b/src/test/ui/suggestions/fn-closure-mutable-capture.nll.stderr
@@ -1,8 +1,8 @@
-error[E0594]: cannot assign to immutable item `x`
+error[E0594]: cannot assign to `x` which is behind a `&` reference
   --> $DIR/fn-closure-mutable-capture.rs:15:17
    |
 LL |     bar(move || x = 1);
-   |                 ^^^^^ cannot mutate
+   |                 ^^^^^ cannot assign
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/trivial-bounds-inconsistent-copy-reborrow.nll.stderr b/src/test/ui/trivial-bounds-inconsistent-copy-reborrow.nll.stderr
index 66547863db2..1a36b0c4839 100644
--- a/src/test/ui/trivial-bounds-inconsistent-copy-reborrow.nll.stderr
+++ b/src/test/ui/trivial-bounds-inconsistent-copy-reborrow.nll.stderr
@@ -1,18 +1,18 @@
 error[E0596]: cannot borrow immutable item `**t` as mutable
   --> $DIR/trivial-bounds-inconsistent-copy-reborrow.rs:16:5
    |
+LL | fn reborrow_mut<'a>(t: &'a &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy {
+   |                        --------------- help: consider changing this to be a mutable reference: `&mut &mut i32`
 LL |     *t //~ ERROR
-   |     ^^ cannot borrow as mutable
-   |
-   = note: the value which is causing this path not to be mutable is...: `*t`
+   |     ^^ `t` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error[E0596]: cannot borrow immutable item `**t` as mutable
   --> $DIR/trivial-bounds-inconsistent-copy-reborrow.rs:20:6
    |
+LL | fn copy_reborrow_mut<'a>(t: &'a &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy {
+   |                             --------------- help: consider changing this to be a mutable reference: `&mut &mut i32`
 LL |     {*t} //~ ERROR
-   |      ^^ cannot borrow as mutable
-   |
-   = note: the value which is causing this path not to be mutable is...: `*t`
+   |      ^^ `t` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
 error: aborting due to 2 previous errors