about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2024-04-24 18:14:37 +0000
committerEsteban Küber <esteban@kuber.com.ar>2024-04-25 16:55:33 +0000
commit9f9f0aa534384e84f92daa2ebe250318e58049a2 (patch)
treee074fd4c9ef017a8f5c7e1aa1f3006eb9657ba85
parentdbaa4e21483e0e767c2746f0351d11be6361e20a (diff)
downloadrust-9f9f0aa534384e84f92daa2ebe250318e58049a2.tar.gz
rust-9f9f0aa534384e84f92daa2ebe250318e58049a2.zip
Mention `split_at_mut` when mixing mutability in indexing ops
Emit suggestion when encountering

```rust
let a = &mut foo[0];
let b = &foo[1];
a.use_mut();
```
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs19
-rw-r--r--tests/ui/borrowck/borrowck-assign-comp-idx.stderr2
-rw-r--r--tests/ui/suggestions/suggest-split-at-mut.rs32
-rw-r--r--tests/ui/suggestions/suggest-split-at-mut.stderr57
4 files changed, 106 insertions, 4 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 832f3b92fa9..9216f9e4971 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -1527,7 +1527,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow },
             ) => {
                 first_borrow_desc = "mutable ";
-                self.cannot_reborrow_already_borrowed(
+                let mut err = self.cannot_reborrow_already_borrowed(
                     span,
                     &desc_place,
                     &msg_place,
@@ -1537,7 +1537,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     "mutable",
                     &msg_borrow,
                     None,
-                )
+                );
+                self.suggest_slice_method_if_applicable(
+                    &mut err,
+                    place,
+                    issued_borrow.borrowed_place,
+                    span,
+                    issued_span,
+                );
+                err
             }
             (
                 BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow },
@@ -1555,6 +1563,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     &msg_borrow,
                     None,
                 );
+                self.suggest_slice_method_if_applicable(
+                    &mut err,
+                    place,
+                    issued_borrow.borrowed_place,
+                    span,
+                    issued_span,
+                );
                 self.suggest_binding_for_closure_capture_self(&mut err, &issued_spans);
                 self.suggest_using_closure_argument_instead_of_capture(
                     &mut err,
diff --git a/tests/ui/borrowck/borrowck-assign-comp-idx.stderr b/tests/ui/borrowck/borrowck-assign-comp-idx.stderr
index b80174ae687..914c79ecee5 100644
--- a/tests/ui/borrowck/borrowck-assign-comp-idx.stderr
+++ b/tests/ui/borrowck/borrowck-assign-comp-idx.stderr
@@ -9,6 +9,8 @@ LL |     p[0] = 5;
 LL |
 LL |     println!("{}", *q);
    |                    -- immutable borrow later used here
+   |
+   = help: use `.split_at_mut(position)` to obtain two mutable non-overlapping sub-slices
 
 error[E0502]: cannot borrow `p` as mutable because it is also borrowed as immutable
   --> $DIR/borrowck-assign-comp-idx.rs:27:9
diff --git a/tests/ui/suggestions/suggest-split-at-mut.rs b/tests/ui/suggestions/suggest-split-at-mut.rs
index a80d35b1951..93f9120048b 100644
--- a/tests/ui/suggestions/suggest-split-at-mut.rs
+++ b/tests/ui/suggestions/suggest-split-at-mut.rs
@@ -16,6 +16,38 @@ fn bar() {
     println!("{:?} {:?}", a, b);
 }
 
+fn baz() {
+    let mut foo = [1,2,3,4];
+    let a = &foo[..2];
+    let b = &mut foo[2..]; //~ ERROR cannot borrow `foo` as mutable because it is also borrowed as immutable
+    b[0] = 6;
+    println!("{:?} {:?}", a, b);
+}
+
+fn qux() {
+    let mut foo = [1,2,3,4];
+    let a = &mut foo[..2];
+    let b = &foo[2..]; //~ ERROR cannot borrow `foo` as immutable because it is also borrowed as mutable
+    a[0] = 5;
+    println!("{:?} {:?}", a, b);
+}
+
+fn bad() {
+    let mut foo = [1,2,3,4];
+    let a = &foo[1];
+    let b = &mut foo[2]; //~ ERROR cannot borrow `foo[_]` as mutable because it is also borrowed as immutable
+    *b = 6;
+    println!("{:?} {:?}", a, b);
+}
+
+fn bat() {
+    let mut foo = [1,2,3,4];
+    let a = &mut foo[1];
+    let b = &foo[2]; //~ ERROR cannot borrow `foo[_]` as immutable because it is also borrowed as mutable
+    *a = 5;
+    println!("{:?} {:?}", a, b);
+}
+
 fn main() {
     foo();
     bar();
diff --git a/tests/ui/suggestions/suggest-split-at-mut.stderr b/tests/ui/suggestions/suggest-split-at-mut.stderr
index 1bae7dc475e..68b1ddc45c7 100644
--- a/tests/ui/suggestions/suggest-split-at-mut.stderr
+++ b/tests/ui/suggestions/suggest-split-at-mut.stderr
@@ -23,6 +23,59 @@ LL |     a[0] = 5;
    |
    = help: use `.split_at_mut(position)` to obtain two mutable non-overlapping sub-slices
 
-error: aborting due to 2 previous errors
+error[E0502]: cannot borrow `foo` as mutable because it is also borrowed as immutable
+  --> $DIR/suggest-split-at-mut.rs:22:18
+   |
+LL |     let a = &foo[..2];
+   |              --- immutable borrow occurs here
+LL |     let b = &mut foo[2..];
+   |                  ^^^ mutable borrow occurs here
+LL |     b[0] = 6;
+LL |     println!("{:?} {:?}", a, b);
+   |                           - immutable borrow later used here
+   |
+   = help: use `.split_at_mut(position)` to obtain two mutable non-overlapping sub-slices
+
+error[E0502]: cannot borrow `foo` as immutable because it is also borrowed as mutable
+  --> $DIR/suggest-split-at-mut.rs:30:14
+   |
+LL |     let a = &mut foo[..2];
+   |                  --- mutable borrow occurs here
+LL |     let b = &foo[2..];
+   |              ^^^ immutable borrow occurs here
+LL |     a[0] = 5;
+   |     ---- mutable borrow later used here
+   |
+   = help: use `.split_at_mut(position)` to obtain two mutable non-overlapping sub-slices
+
+error[E0502]: cannot borrow `foo[_]` as mutable because it is also borrowed as immutable
+  --> $DIR/suggest-split-at-mut.rs:38:13
+   |
+LL |     let a = &foo[1];
+   |             ------- immutable borrow occurs here
+LL |     let b = &mut foo[2];
+   |             ^^^^^^^^^^^ mutable borrow occurs here
+LL |     *b = 6;
+LL |     println!("{:?} {:?}", a, b);
+   |                           - immutable borrow later used here
+   |
+   = help: consider using `.split_at_mut(position)` or similar method to obtain two mutable non-overlapping sub-slices
+   = help: consider using `.swap(index_1, index_2)` to swap elements at the specified indices
+
+error[E0502]: cannot borrow `foo[_]` as immutable because it is also borrowed as mutable
+  --> $DIR/suggest-split-at-mut.rs:46:13
+   |
+LL |     let a = &mut foo[1];
+   |             ----------- mutable borrow occurs here
+LL |     let b = &foo[2];
+   |             ^^^^^^^ immutable borrow occurs here
+LL |     *a = 5;
+   |     ------ mutable borrow later used here
+   |
+   = help: consider using `.split_at_mut(position)` or similar method to obtain two mutable non-overlapping sub-slices
+   = help: consider using `.swap(index_1, index_2)` to swap elements at the specified indices
+
+error: aborting due to 6 previous errors
 
-For more information about this error, try `rustc --explain E0499`.
+Some errors have detailed explanations: E0499, E0502.
+For more information about an error, try `rustc --explain E0499`.