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();
```
This commit is contained in:
Esteban Küber 2024-04-24 18:14:37 +00:00
parent dbaa4e2148
commit 9f9f0aa534
4 changed files with 106 additions and 4 deletions

View File

@ -1527,7 +1527,7 @@ pub(crate) fn report_conflicting_borrow(
BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow }, BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow },
) => { ) => {
first_borrow_desc = "mutable "; first_borrow_desc = "mutable ";
self.cannot_reborrow_already_borrowed( let mut err = self.cannot_reborrow_already_borrowed(
span, span,
&desc_place, &desc_place,
&msg_place, &msg_place,
@ -1537,7 +1537,15 @@ pub(crate) fn report_conflicting_borrow(
"mutable", "mutable",
&msg_borrow, &msg_borrow,
None, None,
) );
self.suggest_slice_method_if_applicable(
&mut err,
place,
issued_borrow.borrowed_place,
span,
issued_span,
);
err
} }
( (
BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow }, BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow },
@ -1555,6 +1563,13 @@ pub(crate) fn report_conflicting_borrow(
&msg_borrow, &msg_borrow,
None, None,
); );
self.suggest_slice_method_if_applicable(
&mut err,
place,
issued_borrow.borrowed_place,
span,
issued_span,
);
self.suggest_binding_for_closure_capture_self(&mut err, &issued_spans); self.suggest_binding_for_closure_capture_self(&mut err, &issued_spans);
self.suggest_using_closure_argument_instead_of_capture( self.suggest_using_closure_argument_instead_of_capture(
&mut err, &mut err,

View File

@ -9,6 +9,8 @@ LL | p[0] = 5;
LL | LL |
LL | println!("{}", *q); LL | println!("{}", *q);
| -- immutable borrow later used here | -- immutable borrow later used here
|
= help: use `.split_at_mut(position)` to obtain two mutable non-overlapping sub-slices
error[E0502]: cannot borrow `p` as mutable because it is also borrowed as immutable error[E0502]: cannot borrow `p` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-assign-comp-idx.rs:27:9 --> $DIR/borrowck-assign-comp-idx.rs:27:9

View File

@ -16,6 +16,38 @@ fn bar() {
println!("{:?} {:?}", a, b); println!("{:?} {:?}", a, b);
} }
fn baz() {
let mut foo = [1,2,3,4];
let a = &foo[..2];
let b = &mut foo[2..]; //~ ERROR cannot borrow `foo` as mutable because it is also borrowed as immutable
b[0] = 6;
println!("{:?} {:?}", a, b);
}
fn qux() {
let mut foo = [1,2,3,4];
let a = &mut foo[..2];
let b = &foo[2..]; //~ ERROR cannot borrow `foo` as immutable because it is also borrowed as mutable
a[0] = 5;
println!("{:?} {:?}", a, b);
}
fn bad() {
let mut foo = [1,2,3,4];
let a = &foo[1];
let b = &mut foo[2]; //~ ERROR cannot borrow `foo[_]` as mutable because it is also borrowed as immutable
*b = 6;
println!("{:?} {:?}", a, b);
}
fn bat() {
let mut foo = [1,2,3,4];
let a = &mut foo[1];
let b = &foo[2]; //~ ERROR cannot borrow `foo[_]` as immutable because it is also borrowed as mutable
*a = 5;
println!("{:?} {:?}", a, b);
}
fn main() { fn main() {
foo(); foo();
bar(); bar();

View File

@ -23,6 +23,59 @@ LL | a[0] = 5;
| |
= help: use `.split_at_mut(position)` to obtain two mutable non-overlapping sub-slices = help: use `.split_at_mut(position)` to obtain two mutable non-overlapping sub-slices
error: aborting due to 2 previous errors error[E0502]: cannot borrow `foo` as mutable because it is also borrowed as immutable
--> $DIR/suggest-split-at-mut.rs:22:18
|
LL | let a = &foo[..2];
| --- immutable borrow occurs here
LL | let b = &mut foo[2..];
| ^^^ mutable borrow occurs here
LL | b[0] = 6;
LL | println!("{:?} {:?}", a, b);
| - immutable borrow later used here
|
= help: use `.split_at_mut(position)` to obtain two mutable non-overlapping sub-slices
For more information about this error, try `rustc --explain E0499`. error[E0502]: cannot borrow `foo` as immutable because it is also borrowed as mutable
--> $DIR/suggest-split-at-mut.rs:30:14
|
LL | let a = &mut foo[..2];
| --- mutable borrow occurs here
LL | let b = &foo[2..];
| ^^^ immutable borrow occurs here
LL | a[0] = 5;
| ---- mutable borrow later used here
|
= help: use `.split_at_mut(position)` to obtain two mutable non-overlapping sub-slices
error[E0502]: cannot borrow `foo[_]` as mutable because it is also borrowed as immutable
--> $DIR/suggest-split-at-mut.rs:38:13
|
LL | let a = &foo[1];
| ------- immutable borrow occurs here
LL | let b = &mut foo[2];
| ^^^^^^^^^^^ mutable borrow occurs here
LL | *b = 6;
LL | println!("{:?} {:?}", a, b);
| - immutable borrow later used here
|
= help: consider using `.split_at_mut(position)` or similar method to obtain two mutable non-overlapping sub-slices
= help: consider using `.swap(index_1, index_2)` to swap elements at the specified indices
error[E0502]: cannot borrow `foo[_]` as immutable because it is also borrowed as mutable
--> $DIR/suggest-split-at-mut.rs:46:13
|
LL | let a = &mut foo[1];
| ----------- mutable borrow occurs here
LL | let b = &foo[2];
| ^^^^^^^ immutable borrow occurs here
LL | *a = 5;
| ------ mutable borrow later used here
|
= help: consider using `.split_at_mut(position)` or similar method to obtain two mutable non-overlapping sub-slices
= help: consider using `.swap(index_1, index_2)` to swap elements at the specified indices
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0499, E0502.
For more information about an error, try `rustc --explain E0499`.