about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <jtitor@2k36.org>2021-06-12 01:15:57 +0900
committerGitHub <noreply@github.com>2021-06-12 01:15:57 +0900
commit883e1a5fd4f84556ae3fcea81d795d452fca6720 (patch)
tree18530afceaa46679730088e448a2bc4dd422230f
parent3b47d337e04a24d5e8cf2d25864d7e9fa949ca0a (diff)
parent0eda5098bd0931a22cb42930d0963306c92f15f2 (diff)
downloadrust-883e1a5fd4f84556ae3fcea81d795d452fca6720.tar.gz
rust-883e1a5fd4f84556ae3fcea81d795d452fca6720.zip
Rollup merge of #85823 - fee1-dead:borrowck-0, r=jackh726
Do not suggest ampmut if rhs is already mutable

Removes invalid suggestion in #85765, although it should highlight the user type instead of the local variable.

Looking at the comments of this line:
https://github.com/rust-lang/rust/blob/84b1005bfd22e2cb2a4c13b0b81958fe72628354/compiler/rustc_mir_build/src/build/matches/mod.rs#L2107

It was intentionally set to `None`, causing it to highlight the local variable instead. I am not sure if I will be able to fix it.

Fixes #85765
-rw-r--r--compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs8
-rw-r--r--src/test/ui/borrowck/issue-85765.rs8
-rw-r--r--src/test/ui/borrowck/issue-85765.stderr12
3 files changed, 26 insertions, 2 deletions
diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs
index d2b15661047..bf5f2c0eec2 100644
--- a/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs
@@ -902,9 +902,13 @@ fn suggest_ampmut<'tcx>(
             {
                 let lt_name = &src[1..ws_pos];
                 let ty = &src[ws_pos..];
-                return (assignment_rhs_span, format!("&{} mut {}", lt_name, ty));
+                if !ty.trim_start().starts_with("mut") {
+                    return (assignment_rhs_span, format!("&{} mut {}", lt_name, ty));
+                }
             } else if let Some(stripped) = src.strip_prefix('&') {
-                return (assignment_rhs_span, format!("&mut {}", stripped));
+                if !stripped.trim_start().starts_with("mut") {
+                    return (assignment_rhs_span, format!("&mut {}", stripped));
+                }
             }
         }
     }
diff --git a/src/test/ui/borrowck/issue-85765.rs b/src/test/ui/borrowck/issue-85765.rs
new file mode 100644
index 00000000000..b82e0298158
--- /dev/null
+++ b/src/test/ui/borrowck/issue-85765.rs
@@ -0,0 +1,8 @@
+fn main() {
+    let mut test = Vec::new();
+    let rofl: &Vec<Vec<i32>> = &mut test;
+    //~^ HELP consider changing this to be a mutable reference
+    rofl.push(Vec::new());
+    //~^ ERROR cannot borrow `*rofl` as mutable, as it is behind a `&` reference
+    //~| NOTE `rofl` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+}
diff --git a/src/test/ui/borrowck/issue-85765.stderr b/src/test/ui/borrowck/issue-85765.stderr
new file mode 100644
index 00000000000..863c2e8eccc
--- /dev/null
+++ b/src/test/ui/borrowck/issue-85765.stderr
@@ -0,0 +1,12 @@
+error[E0596]: cannot borrow `*rofl` as mutable, as it is behind a `&` reference
+  --> $DIR/issue-85765.rs:5:5
+   |
+LL |     let rofl: &Vec<Vec<i32>> = &mut test;
+   |         ---- help: consider changing this to be a mutable reference: `&mut Vec<Vec<i32>>`
+LL |
+LL |     rofl.push(Vec::new());
+   |     ^^^^ `rofl` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.