Auto merge of #119650 - chenyukang:yukang-fix-118596-ref-mut, r=wesleywiser

Suggest ref mut for pattern matching assignment

Fixes #118596
This commit is contained in:
bors 2024-04-25 08:52:19 +00:00
commit 31e6e8c6c5
8 changed files with 164 additions and 41 deletions

View File

@ -3743,7 +3743,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
| None => (self.describe_any_place(place.as_ref()), assigned_span), | None => (self.describe_any_place(place.as_ref()), assigned_span),
Some(decl) => (self.describe_any_place(err_place.as_ref()), decl.source_info.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 mut err = self.cannot_reassign_immutable(span, &place_description, from_arg);
let msg = if from_arg { let msg = if from_arg {
"cannot assign to immutable argument" "cannot assign to immutable argument"
@ -3763,6 +3762,22 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
format!("mut {name}"), format!("mut {name}"),
Applicability::MachineApplicable, 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); err.span_label(span, msg);
self.buffer_error(err); self.buffer_error(err);

View File

@ -2,56 +2,86 @@ error[E0384]: cannot assign twice to immutable variable `x`
--> $DIR/borrowck-match-binding-is-assignment.rs:14:13 --> $DIR/borrowck-match-binding-is-assignment.rs:14:13
| |
LL | x => { LL | x => {
| - | - first assignment to `x`
| |
| first assignment to `x`
| help: consider making this binding mutable: `mut x`
LL | x += 1; LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable | ^^^^^^ 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` error[E0384]: cannot assign twice to immutable variable `x`
--> $DIR/borrowck-match-binding-is-assignment.rs:20:13 --> $DIR/borrowck-match-binding-is-assignment.rs:20:13
| |
LL | E::Foo(x) => { LL | E::Foo(x) => {
| - | - first assignment to `x`
| |
| first assignment to `x`
| help: consider making this binding mutable: `mut x`
LL | x += 1; LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable | ^^^^^^ 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` error[E0384]: cannot assign twice to immutable variable `x`
--> $DIR/borrowck-match-binding-is-assignment.rs:26:13 --> $DIR/borrowck-match-binding-is-assignment.rs:26:13
| |
LL | S { bar: x } => { LL | S { bar: x } => {
| - | - first assignment to `x`
| |
| first assignment to `x`
| help: consider making this binding mutable: `mut x`
LL | x += 1; LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable | ^^^^^^ 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` error[E0384]: cannot assign twice to immutable variable `x`
--> $DIR/borrowck-match-binding-is-assignment.rs:32:13 --> $DIR/borrowck-match-binding-is-assignment.rs:32:13
| |
LL | (x,) => { LL | (x,) => {
| - | - first assignment to `x`
| |
| first assignment to `x`
| help: consider making this binding mutable: `mut x`
LL | x += 1; LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable | ^^^^^^ 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` error[E0384]: cannot assign twice to immutable variable `x`
--> $DIR/borrowck-match-binding-is-assignment.rs:38:13 --> $DIR/borrowck-match-binding-is-assignment.rs:38:13
| |
LL | [x,_,_] => { LL | [x,_,_] => {
| - | - first assignment to `x`
| |
| first assignment to `x`
| help: consider making this binding mutable: `mut x`
LL | x += 1; LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable | ^^^^^^ 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 error: aborting due to 5 previous errors

View File

@ -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);
}

View File

@ -0,0 +1,37 @@
error[E0384]: cannot assign twice to immutable variable `x`
--> $DIR/suggest-ref-mut-issue-118596.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/suggest-ref-mut-issue-118596.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`.

View File

@ -2,12 +2,18 @@ error[E0384]: cannot assign twice to immutable variable `x`
--> $DIR/mut-pattern-internal-mutability.rs:5:5 --> $DIR/mut-pattern-internal-mutability.rs:5:5
| |
LL | let &mut x = foo; LL | let &mut x = foo;
| - | - first assignment to `x`
| |
| first assignment to `x`
| help: consider making this binding mutable: `mut x`
LL | x += 1; LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable | ^^^^^^ 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 error[E0506]: cannot assign to `*foo` because it is borrowed
--> $DIR/mut-pattern-internal-mutability.rs:13:5 --> $DIR/mut-pattern-internal-mutability.rs:13:5

View File

@ -70,13 +70,19 @@ error[E0384]: cannot assign twice to immutable variable `a`
--> $DIR/pat-at-same-name-both.rs:13:15 --> $DIR/pat-at-same-name-both.rs:13:15
| |
LL | Ok(a @ b @ a) LL | Ok(a @ b @ a)
| - | - first assignment to `a`
| |
| first assignment to `a`
| help: consider making this binding mutable: `mut a`
LL | LL |
LL | | Err(a @ b @ a) LL | | Err(a @ b @ a)
| ^ cannot assign twice to immutable variable | ^ 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 error: aborting due to 12 previous errors

View File

@ -15,12 +15,18 @@ error[E0384]: cannot assign twice to immutable variable `_x1`
--> $DIR/borrowck-move-ref-pattern.rs:9:5 --> $DIR/borrowck-move-ref-pattern.rs:9:5
| |
LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr; LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr;
| --- | --- first assignment to `_x1`
| |
| first assignment to `_x1`
| help: consider making this binding mutable: `mut _x1`
LL | _x1 = U; LL | _x1 = U;
| ^^^^^^^ cannot assign twice to immutable variable | ^^^^^^^ 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 error[E0505]: cannot move out of `arr[..]` because it is borrowed
--> $DIR/borrowck-move-ref-pattern.rs:11:10 --> $DIR/borrowck-move-ref-pattern.rs:11:10
@ -73,12 +79,18 @@ error[E0384]: cannot assign twice to immutable variable `_x1`
--> $DIR/borrowck-move-ref-pattern.rs:23:5 --> $DIR/borrowck-move-ref-pattern.rs:23:5
| |
LL | let (ref _x0, _x1, ref _x2, ..) = tup; LL | let (ref _x0, _x1, ref _x2, ..) = tup;
| --- | --- first assignment to `_x1`
| |
| first assignment to `_x1`
| help: consider making this binding mutable: `mut _x1`
LL | _x1 = U; LL | _x1 = U;
| ^^^^^^^ cannot assign twice to immutable variable | ^^^^^^^ 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 error[E0502]: cannot borrow `tup.0` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-move-ref-pattern.rs:24:20 --> $DIR/borrowck-move-ref-pattern.rs:24:20

View File

@ -2,12 +2,18 @@ error[E0384]: cannot assign twice to immutable variable `a`
--> $DIR/mut-ref-mut-2021.rs:9:5 --> $DIR/mut-ref-mut-2021.rs:9:5
| |
LL | let Foo(a) = Foo(0); LL | let Foo(a) = Foo(0);
| - | - first assignment to `a`
| |
| first assignment to `a`
| help: consider making this binding mutable: `mut a`
LL | a = 42; LL | a = 42;
| ^^^^^^ cannot assign twice to immutable variable | ^^^^^^ cannot assign twice to immutable variable
|
help: consider making this binding mutable
|
LL | let Foo(mut a) = Foo(0);
| ~~~~~
help: to modify the original value, take a borrow instead
|
LL | let Foo(ref mut a) = Foo(0);
| ~~~~~~~~~
error[E0384]: cannot assign twice to immutable variable `a` error[E0384]: cannot assign twice to immutable variable `a`
--> $DIR/mut-ref-mut-2021.rs:15:5 --> $DIR/mut-ref-mut-2021.rs:15:5