Skip to content

Commit 0bc642e

Browse files
committed
Mention split_at_mut when mixing mutability in indexing ops
Emit suggestion when encountering ```rust let a = &mut foo[0]; let b = &foo[1]; a.use_mut(); ```
1 parent 8c586cc commit 0bc642e

File tree

4 files changed

+106
-4
lines changed

4 files changed

+106
-4
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1490,7 +1490,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
14901490
BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow },
14911491
) => {
14921492
first_borrow_desc = "mutable ";
1493-
self.cannot_reborrow_already_borrowed(
1493+
let mut err = self.cannot_reborrow_already_borrowed(
14941494
span,
14951495
&desc_place,
14961496
&msg_place,
@@ -1500,7 +1500,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
15001500
"mutable",
15011501
&msg_borrow,
15021502
None,
1503-
)
1503+
);
1504+
self.suggest_slice_method_if_applicable(
1505+
&mut err,
1506+
place,
1507+
issued_borrow.borrowed_place,
1508+
span,
1509+
issued_span,
1510+
);
1511+
err
15041512
}
15051513
(
15061514
BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow },
@@ -1518,6 +1526,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
15181526
&msg_borrow,
15191527
None,
15201528
);
1529+
self.suggest_slice_method_if_applicable(
1530+
&mut err,
1531+
place,
1532+
issued_borrow.borrowed_place,
1533+
span,
1534+
issued_span,
1535+
);
15211536
self.suggest_binding_for_closure_capture_self(&mut err, &issued_spans);
15221537
self.suggest_using_closure_argument_instead_of_capture(
15231538
&mut err,

tests/ui/borrowck/borrowck-assign-comp-idx.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ LL | p[0] = 5;
99
LL |
1010
LL | println!("{}", *q);
1111
| -- immutable borrow later used here
12+
|
13+
= help: use `.split_at_mut(position)` to obtain two mutable non-overlapping sub-slices
1214

1315
error[E0502]: cannot borrow `p` as mutable because it is also borrowed as immutable
1416
--> $DIR/borrowck-assign-comp-idx.rs:27:9

tests/ui/suggestions/suggest-split-at-mut.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,38 @@ fn bar() {
1616
println!("{:?} {:?}", a, b);
1717
}
1818

19+
fn baz() {
20+
let mut foo = [1,2,3,4];
21+
let a = &foo[..2];
22+
let b = &mut foo[2..]; //~ ERROR cannot borrow `foo` as mutable because it is also borrowed as immutable
23+
b[0] = 6;
24+
println!("{:?} {:?}", a, b);
25+
}
26+
27+
fn qux() {
28+
let mut foo = [1,2,3,4];
29+
let a = &mut foo[..2];
30+
let b = &foo[2..]; //~ ERROR cannot borrow `foo` as immutable because it is also borrowed as mutable
31+
a[0] = 5;
32+
println!("{:?} {:?}", a, b);
33+
}
34+
35+
fn bad() {
36+
let mut foo = [1,2,3,4];
37+
let a = &foo[1];
38+
let b = &mut foo[2]; //~ ERROR cannot borrow `foo[_]` as mutable because it is also borrowed as immutable
39+
*b = 6;
40+
println!("{:?} {:?}", a, b);
41+
}
42+
43+
fn bat() {
44+
let mut foo = [1,2,3,4];
45+
let a = &mut foo[1];
46+
let b = &foo[2]; //~ ERROR cannot borrow `foo[_]` as immutable because it is also borrowed as mutable
47+
*a = 5;
48+
println!("{:?} {:?}", a, b);
49+
}
50+
1951
fn main() {
2052
foo();
2153
bar();

tests/ui/suggestions/suggest-split-at-mut.stderr

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,59 @@ LL | a[0] = 5;
2323
|
2424
= help: use `.split_at_mut(position)` to obtain two mutable non-overlapping sub-slices
2525

26-
error: aborting due to 2 previous errors
26+
error[E0502]: cannot borrow `foo` as mutable because it is also borrowed as immutable
27+
--> $DIR/suggest-split-at-mut.rs:22:18
28+
|
29+
LL | let a = &foo[..2];
30+
| --- immutable borrow occurs here
31+
LL | let b = &mut foo[2..];
32+
| ^^^ mutable borrow occurs here
33+
LL | b[0] = 6;
34+
LL | println!("{:?} {:?}", a, b);
35+
| - immutable borrow later used here
36+
|
37+
= help: use `.split_at_mut(position)` to obtain two mutable non-overlapping sub-slices
38+
39+
error[E0502]: cannot borrow `foo` as immutable because it is also borrowed as mutable
40+
--> $DIR/suggest-split-at-mut.rs:30:14
41+
|
42+
LL | let a = &mut foo[..2];
43+
| --- mutable borrow occurs here
44+
LL | let b = &foo[2..];
45+
| ^^^ immutable borrow occurs here
46+
LL | a[0] = 5;
47+
| ---- mutable borrow later used here
48+
|
49+
= help: use `.split_at_mut(position)` to obtain two mutable non-overlapping sub-slices
50+
51+
error[E0502]: cannot borrow `foo[_]` as mutable because it is also borrowed as immutable
52+
--> $DIR/suggest-split-at-mut.rs:38:13
53+
|
54+
LL | let a = &foo[1];
55+
| ------- immutable borrow occurs here
56+
LL | let b = &mut foo[2];
57+
| ^^^^^^^^^^^ mutable borrow occurs here
58+
LL | *b = 6;
59+
LL | println!("{:?} {:?}", a, b);
60+
| - immutable borrow later used here
61+
|
62+
= help: consider using `.split_at_mut(position)` or similar method to obtain two mutable non-overlapping sub-slices
63+
= help: consider using `.swap(index_1, index_2)` to swap elements at the specified indices
64+
65+
error[E0502]: cannot borrow `foo[_]` as immutable because it is also borrowed as mutable
66+
--> $DIR/suggest-split-at-mut.rs:46:13
67+
|
68+
LL | let a = &mut foo[1];
69+
| ----------- mutable borrow occurs here
70+
LL | let b = &foo[2];
71+
| ^^^^^^^ immutable borrow occurs here
72+
LL | *a = 5;
73+
| ------ mutable borrow later used here
74+
|
75+
= help: consider using `.split_at_mut(position)` or similar method to obtain two mutable non-overlapping sub-slices
76+
= help: consider using `.swap(index_1, index_2)` to swap elements at the specified indices
77+
78+
error: aborting due to 6 previous errors
2779

28-
For more information about this error, try `rustc --explain E0499`.
80+
Some errors have detailed explanations: E0499, E0502.
81+
For more information about an error, try `rustc --explain E0499`.

0 commit comments

Comments
 (0)