Skip to content

Commit 0f73133

Browse files
committed
Suggest split_at_mut on multiple mutable index access
1 parent 994e5e7 commit 0f73133

File tree

3 files changed

+48
-2
lines changed

3 files changed

+48
-2
lines changed

src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs

+25-2
Original file line numberDiff line numberDiff line change
@@ -395,14 +395,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
395395

396396
(BorrowKind::Mut { .. }, BorrowKind::Mut { .. }) => {
397397
first_borrow_desc = "first ";
398-
self.cannot_mutably_borrow_multiply(
398+
let mut err = self.cannot_mutably_borrow_multiply(
399399
span,
400400
&desc_place,
401401
&msg_place,
402402
issued_span,
403403
&msg_borrow,
404404
None,
405-
)
405+
);
406+
self.suggest_split_at_mut_if_applicable(
407+
&mut err,
408+
&place,
409+
&issued_borrow.borrowed_place,
410+
);
411+
err
406412
}
407413

408414
(BorrowKind::Unique, BorrowKind::Unique) => {
@@ -547,6 +553,23 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
547553
err
548554
}
549555

556+
fn suggest_split_at_mut_if_applicable(
557+
&self,
558+
err: &mut DiagnosticBuilder<'_>,
559+
place: &Place<'tcx>,
560+
borrowed_place: &Place<'tcx>,
561+
) {
562+
match (&place.projection[..], &borrowed_place.projection[..]) {
563+
([ProjectionElem::Index(_)], [ProjectionElem::Index(_)]) => {
564+
err.help(
565+
"consider using `.split_at_mut(position)` or similar method to obtain \
566+
two mutable non-overlapping sub-slices",
567+
);
568+
}
569+
_ => {}
570+
}
571+
}
572+
550573
/// Returns the description of the root place for a conflicting borrow and the full
551574
/// descriptions of the places that caused the conflict.
552575
///
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
fn main() {
2+
let mut foo = [1, 2, 3, 4];
3+
let a = &mut foo[2];
4+
let b = &mut foo[3]; //~ ERROR cannot borrow `foo[_]` as mutable more than once at a time
5+
*a = 5;
6+
*b = 6;
7+
println!("{:?} {:?}", a, b);
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0499]: cannot borrow `foo[_]` as mutable more than once at a time
2+
--> $DIR/suggest-split-at-mut.rs:4:13
3+
|
4+
LL | let a = &mut foo[2];
5+
| ----------- first mutable borrow occurs here
6+
LL | let b = &mut foo[3];
7+
| ^^^^^^^^^^^ second mutable borrow occurs here
8+
LL | *a = 5;
9+
| ------ first borrow later used here
10+
|
11+
= help: consider using `.split_at_mut(position)` or similar method to obtain two mutable non-overlapping sub-slices
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0499`.

0 commit comments

Comments
 (0)