diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2024-04-24 18:14:37 +0000 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2024-04-25 16:55:33 +0000 |
| commit | 9f9f0aa534384e84f92daa2ebe250318e58049a2 (patch) | |
| tree | e074fd4c9ef017a8f5c7e1aa1f3006eb9657ba85 | |
| parent | dbaa4e21483e0e767c2746f0351d11be6361e20a (diff) | |
| download | rust-9f9f0aa534384e84f92daa2ebe250318e58049a2.tar.gz rust-9f9f0aa534384e84f92daa2ebe250318e58049a2.zip | |
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(); ```
| -rw-r--r-- | compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs | 19 | ||||
| -rw-r--r-- | tests/ui/borrowck/borrowck-assign-comp-idx.stderr | 2 | ||||
| -rw-r--r-- | tests/ui/suggestions/suggest-split-at-mut.rs | 32 | ||||
| -rw-r--r-- | tests/ui/suggestions/suggest-split-at-mut.stderr | 57 |
4 files changed, 106 insertions, 4 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 832f3b92fa9..9216f9e4971 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1527,7 +1527,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow }, ) => { first_borrow_desc = "mutable "; - self.cannot_reborrow_already_borrowed( + let mut err = self.cannot_reborrow_already_borrowed( span, &desc_place, &msg_place, @@ -1537,7 +1537,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { "mutable", &msg_borrow, 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 }, @@ -1555,6 +1563,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &msg_borrow, 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_using_closure_argument_instead_of_capture( &mut err, diff --git a/tests/ui/borrowck/borrowck-assign-comp-idx.stderr b/tests/ui/borrowck/borrowck-assign-comp-idx.stderr index b80174ae687..914c79ecee5 100644 --- a/tests/ui/borrowck/borrowck-assign-comp-idx.stderr +++ b/tests/ui/borrowck/borrowck-assign-comp-idx.stderr @@ -9,6 +9,8 @@ LL | p[0] = 5; LL | LL | println!("{}", *q); | -- 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 --> $DIR/borrowck-assign-comp-idx.rs:27:9 diff --git a/tests/ui/suggestions/suggest-split-at-mut.rs b/tests/ui/suggestions/suggest-split-at-mut.rs index a80d35b1951..93f9120048b 100644 --- a/tests/ui/suggestions/suggest-split-at-mut.rs +++ b/tests/ui/suggestions/suggest-split-at-mut.rs @@ -16,6 +16,38 @@ fn bar() { 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() { foo(); bar(); diff --git a/tests/ui/suggestions/suggest-split-at-mut.stderr b/tests/ui/suggestions/suggest-split-at-mut.stderr index 1bae7dc475e..68b1ddc45c7 100644 --- a/tests/ui/suggestions/suggest-split-at-mut.stderr +++ b/tests/ui/suggestions/suggest-split-at-mut.stderr @@ -23,6 +23,59 @@ LL | a[0] = 5; | = 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 + +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 -For more information about this error, try `rustc --explain E0499`. +Some errors have detailed explanations: E0499, E0502. +For more information about an error, try `rustc --explain E0499`. |
