Skip to content

Commit

Permalink
Auto merge of #119650 - chenyukang:yukang-fix-118596-ref-mut, r=wesle…
Browse files Browse the repository at this point in the history
…ywiser

Suggest ref mut for pattern matching assignment

Fixes #118596
  • Loading branch information
bors committed Apr 24, 2024
2 parents 29a56a3 + 5b26c10 commit 8e84124
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 37 deletions.
17 changes: 16 additions & 1 deletion compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3706,7 +3706,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
| None => (self.describe_any_place(place.as_ref()), assigned_span),
Some(decl) => (self.describe_any_place(err_place.as_ref()), decl.source_info.span),
};

let mut err = self.cannot_reassign_immutable(span, &place_description, from_arg);
let msg = if from_arg {
"cannot assign to immutable argument"
Expand All @@ -3726,6 +3725,22 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
format!("mut {name}"),
Applicability::MachineApplicable,
);
if !from_arg
&& matches!(
decl.local_info(),
LocalInfo::User(BindingForm::Var(VarBindingForm {
opt_match_place: Some((Some(_), _)),
..
}))
)
{
err.span_suggestion(
decl.source_info.span,
"to modify the original value, take a borrow instead",
format!("ref mut {name}"),
Applicability::MaybeIncorrect,
);
}
}
err.span_label(span, msg);
self.buffer_error(err);
Expand Down
70 changes: 50 additions & 20 deletions tests/ui/borrowck/borrowck-match-binding-is-assignment.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,86 @@ error[E0384]: cannot assign twice to immutable variable `x`
--> $DIR/borrowck-match-binding-is-assignment.rs:14:13
|
LL | x => {
| -
| |
| first assignment to `x`
| help: consider making this binding mutable: `mut x`
| - first assignment to `x`
LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable
|
help: consider making this binding mutable
|
LL | mut x => {
| ~~~~~
help: to modify the original value, take a borrow instead
|
LL | ref mut x => {
| ~~~~~~~~~

error[E0384]: cannot assign twice to immutable variable `x`
--> $DIR/borrowck-match-binding-is-assignment.rs:20:13
|
LL | E::Foo(x) => {
| -
| |
| first assignment to `x`
| help: consider making this binding mutable: `mut x`
| - first assignment to `x`
LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable
|
help: consider making this binding mutable
|
LL | E::Foo(mut x) => {
| ~~~~~
help: to modify the original value, take a borrow instead
|
LL | E::Foo(ref mut x) => {
| ~~~~~~~~~

error[E0384]: cannot assign twice to immutable variable `x`
--> $DIR/borrowck-match-binding-is-assignment.rs:26:13
|
LL | S { bar: x } => {
| -
| |
| first assignment to `x`
| help: consider making this binding mutable: `mut x`
| - first assignment to `x`
LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable
|
help: consider making this binding mutable
|
LL | S { bar: mut x } => {
| ~~~~~
help: to modify the original value, take a borrow instead
|
LL | S { bar: ref mut x } => {
| ~~~~~~~~~

error[E0384]: cannot assign twice to immutable variable `x`
--> $DIR/borrowck-match-binding-is-assignment.rs:32:13
|
LL | (x,) => {
| -
| |
| first assignment to `x`
| help: consider making this binding mutable: `mut x`
| - first assignment to `x`
LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable
|
help: consider making this binding mutable
|
LL | (mut x,) => {
| ~~~~~
help: to modify the original value, take a borrow instead
|
LL | (ref mut x,) => {
| ~~~~~~~~~

error[E0384]: cannot assign twice to immutable variable `x`
--> $DIR/borrowck-match-binding-is-assignment.rs:38:13
|
LL | [x,_,_] => {
| -
| |
| first assignment to `x`
| help: consider making this binding mutable: `mut x`
| - first assignment to `x`
LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable
|
help: consider making this binding mutable
|
LL | [mut x,_,_] => {
| ~~~~~
help: to modify the original value, take a borrow instead
|
LL | [ref mut x,_,_] => {
| ~~~~~~~~~

error: aborting due to 5 previous errors

Expand Down
11 changes: 11 additions & 0 deletions tests/ui/borrowck/issue-118596-suggest-ref-mut.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
fn main() {
let y = Some(0);
if let Some(x) = y {
x = 2; //~ ERROR cannot assign twice to immutable variable `x`
}

let mut arr = [1, 2, 3];
let [x, ref xs_hold @ ..] = arr;
x = 0; //~ ERROR cannot assign twice to immutable variable `x`
eprintln!("{:?}", arr);
}
37 changes: 37 additions & 0 deletions tests/ui/borrowck/issue-118596-suggest-ref-mut.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
error[E0384]: cannot assign twice to immutable variable `x`
--> $DIR/issue-118596-suggest-ref-mut.rs:4:9
|
LL | if let Some(x) = y {
| - first assignment to `x`
LL | x = 2;
| ^^^^^ cannot assign twice to immutable variable
|
help: consider making this binding mutable
|
LL | if let Some(mut x) = y {
| ~~~~~
help: to modify the original value, take a borrow instead
|
LL | if let Some(ref mut x) = y {
| ~~~~~~~~~

error[E0384]: cannot assign twice to immutable variable `x`
--> $DIR/issue-118596-suggest-ref-mut.rs:9:5
|
LL | let [x, ref xs_hold @ ..] = arr;
| - first assignment to `x`
LL | x = 0;
| ^^^^^ cannot assign twice to immutable variable
|
help: consider making this binding mutable
|
LL | let [mut x, ref xs_hold @ ..] = arr;
| ~~~~~
help: to modify the original value, take a borrow instead
|
LL | let [ref mut x, ref xs_hold @ ..] = arr;
| ~~~~~~~~~

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0384`.
14 changes: 10 additions & 4 deletions tests/ui/mut/mut-pattern-internal-mutability.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@ error[E0384]: cannot assign twice to immutable variable `x`
--> $DIR/mut-pattern-internal-mutability.rs:5:5
|
LL | let &mut x = foo;
| -
| |
| first assignment to `x`
| help: consider making this binding mutable: `mut x`
| - first assignment to `x`
LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable
|
help: consider making this binding mutable
|
LL | let &mut mut x = foo;
| ~~~~~
help: to modify the original value, take a borrow instead
|
LL | let &mut ref mut x = foo;
| ~~~~~~~~~

error[E0506]: cannot assign to `*foo` because it is borrowed
--> $DIR/mut-pattern-internal-mutability.rs:13:5
Expand Down
14 changes: 10 additions & 4 deletions tests/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,19 @@ error[E0384]: cannot assign twice to immutable variable `a`
--> $DIR/pat-at-same-name-both.rs:13:15
|
LL | Ok(a @ b @ a)
| -
| |
| first assignment to `a`
| help: consider making this binding mutable: `mut a`
| - first assignment to `a`
LL |
LL | | Err(a @ b @ a)
| ^ cannot assign twice to immutable variable
|
help: consider making this binding mutable
|
LL | Ok(a @ b @ mut a)
| ~~~~~
help: to modify the original value, take a borrow instead
|
LL | Ok(a @ b @ ref mut a)
| ~~~~~~~~~

error: aborting due to 12 previous errors

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,18 @@ error[E0384]: cannot assign twice to immutable variable `_x1`
--> $DIR/borrowck-move-ref-pattern.rs:9:5
|
LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr;
| ---
| |
| first assignment to `_x1`
| help: consider making this binding mutable: `mut _x1`
| --- first assignment to `_x1`
LL | _x1 = U;
| ^^^^^^^ cannot assign twice to immutable variable
|
help: consider making this binding mutable
|
LL | let [ref _x0_hold, mut _x1, ref xs_hold @ ..] = arr;
| ~~~~~~~
help: to modify the original value, take a borrow instead
|
LL | let [ref _x0_hold, ref mut _x1, ref xs_hold @ ..] = arr;
| ~~~~~~~~~~~

error[E0505]: cannot move out of `arr[..]` because it is borrowed
--> $DIR/borrowck-move-ref-pattern.rs:11:10
Expand Down Expand Up @@ -73,12 +79,18 @@ error[E0384]: cannot assign twice to immutable variable `_x1`
--> $DIR/borrowck-move-ref-pattern.rs:23:5
|
LL | let (ref _x0, _x1, ref _x2, ..) = tup;
| ---
| |
| first assignment to `_x1`
| help: consider making this binding mutable: `mut _x1`
| --- first assignment to `_x1`
LL | _x1 = U;
| ^^^^^^^ cannot assign twice to immutable variable
|
help: consider making this binding mutable
|
LL | let (ref _x0, mut _x1, ref _x2, ..) = tup;
| ~~~~~~~
help: to modify the original value, take a borrow instead
|
LL | let (ref _x0, ref mut _x1, ref _x2, ..) = tup;
| ~~~~~~~~~~~

error[E0502]: cannot borrow `tup.0` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-move-ref-pattern.rs:24:20
Expand Down

0 comments on commit 8e84124

Please sign in to comment.