diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs index b0b9790abb12a..b49e7b7f0d9f8 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 0000000000000..d294c20b8240e --- /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 0000000000000..330f012b2a9be --- /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`.