diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs index a8e534a9f65..67254cd0c48 100644 --- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs @@ -395,14 +395,20 @@ pub(in crate::borrow_check) fn report_conflicting_borrow( (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) => { @@ -547,6 +553,23 @@ pub(in crate::borrow_check) fn report_conflicting_borrow( 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`.