Skip to content

Commit

Permalink
Suggest split_at_mut on multiple mutable index access
Browse files Browse the repository at this point in the history
  • Loading branch information
estebank committed Feb 4, 2020
1 parent 994e5e7 commit 0f73133
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 2 deletions.
27 changes: 25 additions & 2 deletions src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,14 +395,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) => {
Expand Down Expand Up @@ -547,6 +553,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.
///
Expand Down
8 changes: 8 additions & 0 deletions src/test/ui/suggestions/suggest-split-at-mut.rs
Original file line number Diff line number Diff line change
@@ -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);
}
15 changes: 15 additions & 0 deletions src/test/ui/suggestions/suggest-split-at-mut.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 0f73133

Please sign in to comment.