Suggest ref mut for pattern matching assignment

This commit is contained in:
yukang 2024-01-06 13:13:18 +08:00
parent 7bb4f0889e
commit be9dbe9102
8 changed files with 164 additions and 41 deletions

View file

@ -3706,7 +3706,6 @@ pub(crate) fn report_illegal_reassignment(
| 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"
@ -3726,6 +3725,22 @@ pub(crate) fn report_illegal_reassignment(
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);

View file

@ -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

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
|
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

View file

@ -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

View file

@ -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
@ -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

View file

@ -2,12 +2,18 @@ error[E0384]: cannot assign twice to immutable variable `a`
--> $DIR/mut-ref-mut-2021.rs:9:5
|
LL | let Foo(a) = Foo(0);
| -
| |
| first assignment to `a`
| help: consider making this binding mutable: `mut a`
| - first assignment to `a`
LL | a = 42;
| ^^^^^^ 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`
--> $DIR/mut-ref-mut-2021.rs:15:5