about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDeadbeef <fee1-dead-beef@protonmail.com>2021-05-30 10:54:50 +0800
committerDeadbeef <fee1-dead-beef@protonmail.com>2021-05-30 10:54:50 +0800
commit0eda5098bd0931a22cb42930d0963306c92f15f2 (patch)
treec11be8a06d5bf5260c9d6c2c19c7e5576827b26c
parentce0d64e03ef9875e0935bb60e989542b7ec29579 (diff)
downloadrust-0eda5098bd0931a22cb42930d0963306c92f15f2.tar.gz
rust-0eda5098bd0931a22cb42930d0963306c92f15f2.zip
Do not suggest ampmut if rhs is already mutable
-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`.