about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2020-02-04 21:51:58 +0100
committerGitHub <noreply@github.com>2020-02-04 21:51:58 +0100
commit793a5e68b4589d4168fa778c65ca9b92e0b85f62 (patch)
tree471915cc7224f9d29ca58fbc8975feffc92152f5
parenta25ce40bc9f0206128825676ec0e63a3c032ea4e (diff)
parent0f73133be6a6915e2d5836ce9986eaffc1b2954d (diff)
downloadrust-793a5e68b4589d4168fa778c65ca9b92e0b85f62.tar.gz
rust-793a5e68b4589d4168fa778c65ca9b92e0b85f62.zip
Rollup merge of #68819 - estebank:split_at_mut, r=oli-obk
Suggest `split_at_mut` on multiple mutable index access

cc #58792.
-rw-r--r--src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs27
-rw-r--r--src/test/ui/suggestions/suggest-split-at-mut.rs8
-rw-r--r--src/test/ui/suggestions/suggest-split-at-mut.stderr15
3 files changed, 48 insertions, 2 deletions
diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs
index b0b9790abb1..b49e7b7f0d9 100644
--- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs
@@ -397,14 +397,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
 
             (BorrowKind::Mut { .. }, BorrowKind::Mut { .. }) => {
                 first_borrow_desc = "first ";
-                self.cannot_mutably_borrow_multiply(
+                let mut err = self.cannot_mutably_borrow_multiply(
                     span,
                     &desc_place,
                     &msg_place,
                     issued_span,
                     &msg_borrow,
                     None,
-                )
+                );
+                self.suggest_split_at_mut_if_applicable(
+                    &mut err,
+                    &place,
+                    &issued_borrow.borrowed_place,
+                );
+                err
             }
 
             (BorrowKind::Unique, BorrowKind::Unique) => {
@@ -549,6 +555,23 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         err
     }
 
+    fn suggest_split_at_mut_if_applicable(
+        &self,
+        err: &mut DiagnosticBuilder<'_>,
+        place: &Place<'tcx>,
+        borrowed_place: &Place<'tcx>,
+    ) {
+        match (&place.projection[..], &borrowed_place.projection[..]) {
+            ([ProjectionElem::Index(_)], [ProjectionElem::Index(_)]) => {
+                err.help(
+                    "consider using `.split_at_mut(position)` or similar method to obtain \
+                     two mutable non-overlapping sub-slices",
+                );
+            }
+            _ => {}
+        }
+    }
+
     /// Returns the description of the root place for a conflicting borrow and the full
     /// descriptions of the places that caused the conflict.
     ///
diff --git a/src/test/ui/suggestions/suggest-split-at-mut.rs b/src/test/ui/suggestions/suggest-split-at-mut.rs
new file mode 100644
index 00000000000..d294c20b824
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-split-at-mut.rs
@@ -0,0 +1,8 @@
+fn main() {
+    let mut foo = [1, 2, 3, 4];
+    let a = &mut foo[2];
+    let b = &mut foo[3]; //~ ERROR cannot borrow `foo[_]` as mutable more than once at a time
+    *a = 5;
+    *b = 6;
+    println!("{:?} {:?}", a, b);
+}
diff --git a/src/test/ui/suggestions/suggest-split-at-mut.stderr b/src/test/ui/suggestions/suggest-split-at-mut.stderr
new file mode 100644
index 00000000000..330f012b2a9
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-split-at-mut.stderr
@@ -0,0 +1,15 @@
+error[E0499]: cannot borrow `foo[_]` as mutable more than once at a time
+  --> $DIR/suggest-split-at-mut.rs:4:13
+   |
+LL |     let a = &mut foo[2];
+   |             ----------- first mutable borrow occurs here
+LL |     let b = &mut foo[3];
+   |             ^^^^^^^^^^^ second mutable borrow occurs here
+LL |     *a = 5;
+   |     ------ first borrow later used here
+   |
+   = help: consider using `.split_at_mut(position)` or similar method to obtain two mutable non-overlapping sub-slices
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0499`.