Skip to content

Commit 31e6e8c

Browse files
committed
Auto merge of #119650 - chenyukang:yukang-fix-118596-ref-mut, r=wesleywiser
Suggest ref mut for pattern matching assignment Fixes #118596
2 parents 865808b + be9dbe9 commit 31e6e8c

8 files changed

+164
-41
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -3743,7 +3743,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
37433743
| None => (self.describe_any_place(place.as_ref()), assigned_span),
37443744
Some(decl) => (self.describe_any_place(err_place.as_ref()), decl.source_info.span),
37453745
};
3746-
37473746
let mut err = self.cannot_reassign_immutable(span, &place_description, from_arg);
37483747
let msg = if from_arg {
37493748
"cannot assign to immutable argument"
@@ -3763,6 +3762,22 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
37633762
format!("mut {name}"),
37643763
Applicability::MachineApplicable,
37653764
);
3765+
if !from_arg
3766+
&& matches!(
3767+
decl.local_info(),
3768+
LocalInfo::User(BindingForm::Var(VarBindingForm {
3769+
opt_match_place: Some((Some(_), _)),
3770+
..
3771+
}))
3772+
)
3773+
{
3774+
err.span_suggestion(
3775+
decl.source_info.span,
3776+
"to modify the original value, take a borrow instead",
3777+
format!("ref mut {name}"),
3778+
Applicability::MaybeIncorrect,
3779+
);
3780+
}
37663781
}
37673782
err.span_label(span, msg);
37683783
self.buffer_error(err);

tests/ui/borrowck/borrowck-match-binding-is-assignment.stderr

+50-20
Original file line numberDiff line numberDiff line change
@@ -2,56 +2,86 @@ error[E0384]: cannot assign twice to immutable variable `x`
22
--> $DIR/borrowck-match-binding-is-assignment.rs:14:13
33
|
44
LL | x => {
5-
| -
6-
| |
7-
| first assignment to `x`
8-
| help: consider making this binding mutable: `mut x`
5+
| - first assignment to `x`
96
LL | x += 1;
107
| ^^^^^^ cannot assign twice to immutable variable
8+
|
9+
help: consider making this binding mutable
10+
|
11+
LL | mut x => {
12+
| ~~~~~
13+
help: to modify the original value, take a borrow instead
14+
|
15+
LL | ref mut x => {
16+
| ~~~~~~~~~
1117

1218
error[E0384]: cannot assign twice to immutable variable `x`
1319
--> $DIR/borrowck-match-binding-is-assignment.rs:20:13
1420
|
1521
LL | E::Foo(x) => {
16-
| -
17-
| |
18-
| first assignment to `x`
19-
| help: consider making this binding mutable: `mut x`
22+
| - first assignment to `x`
2023
LL | x += 1;
2124
| ^^^^^^ cannot assign twice to immutable variable
25+
|
26+
help: consider making this binding mutable
27+
|
28+
LL | E::Foo(mut x) => {
29+
| ~~~~~
30+
help: to modify the original value, take a borrow instead
31+
|
32+
LL | E::Foo(ref mut x) => {
33+
| ~~~~~~~~~
2234

2335
error[E0384]: cannot assign twice to immutable variable `x`
2436
--> $DIR/borrowck-match-binding-is-assignment.rs:26:13
2537
|
2638
LL | S { bar: x } => {
27-
| -
28-
| |
29-
| first assignment to `x`
30-
| help: consider making this binding mutable: `mut x`
39+
| - first assignment to `x`
3140
LL | x += 1;
3241
| ^^^^^^ cannot assign twice to immutable variable
42+
|
43+
help: consider making this binding mutable
44+
|
45+
LL | S { bar: mut x } => {
46+
| ~~~~~
47+
help: to modify the original value, take a borrow instead
48+
|
49+
LL | S { bar: ref mut x } => {
50+
| ~~~~~~~~~
3351

3452
error[E0384]: cannot assign twice to immutable variable `x`
3553
--> $DIR/borrowck-match-binding-is-assignment.rs:32:13
3654
|
3755
LL | (x,) => {
38-
| -
39-
| |
40-
| first assignment to `x`
41-
| help: consider making this binding mutable: `mut x`
56+
| - first assignment to `x`
4257
LL | x += 1;
4358
| ^^^^^^ cannot assign twice to immutable variable
59+
|
60+
help: consider making this binding mutable
61+
|
62+
LL | (mut x,) => {
63+
| ~~~~~
64+
help: to modify the original value, take a borrow instead
65+
|
66+
LL | (ref mut x,) => {
67+
| ~~~~~~~~~
4468

4569
error[E0384]: cannot assign twice to immutable variable `x`
4670
--> $DIR/borrowck-match-binding-is-assignment.rs:38:13
4771
|
4872
LL | [x,_,_] => {
49-
| -
50-
| |
51-
| first assignment to `x`
52-
| help: consider making this binding mutable: `mut x`
73+
| - first assignment to `x`
5374
LL | x += 1;
5475
| ^^^^^^ cannot assign twice to immutable variable
76+
|
77+
help: consider making this binding mutable
78+
|
79+
LL | [mut x,_,_] => {
80+
| ~~~~~
81+
help: to modify the original value, take a borrow instead
82+
|
83+
LL | [ref mut x,_,_] => {
84+
| ~~~~~~~~~
5585

5686
error: aborting due to 5 previous errors
5787

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
fn main() {
2+
let y = Some(0);
3+
if let Some(x) = y {
4+
x = 2; //~ ERROR cannot assign twice to immutable variable `x`
5+
}
6+
7+
let mut arr = [1, 2, 3];
8+
let [x, ref xs_hold @ ..] = arr;
9+
x = 0; //~ ERROR cannot assign twice to immutable variable `x`
10+
eprintln!("{:?}", arr);
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
error[E0384]: cannot assign twice to immutable variable `x`
2+
--> $DIR/suggest-ref-mut-issue-118596.rs:4:9
3+
|
4+
LL | if let Some(x) = y {
5+
| - first assignment to `x`
6+
LL | x = 2;
7+
| ^^^^^ cannot assign twice to immutable variable
8+
|
9+
help: consider making this binding mutable
10+
|
11+
LL | if let Some(mut x) = y {
12+
| ~~~~~
13+
help: to modify the original value, take a borrow instead
14+
|
15+
LL | if let Some(ref mut x) = y {
16+
| ~~~~~~~~~
17+
18+
error[E0384]: cannot assign twice to immutable variable `x`
19+
--> $DIR/suggest-ref-mut-issue-118596.rs:9:5
20+
|
21+
LL | let [x, ref xs_hold @ ..] = arr;
22+
| - first assignment to `x`
23+
LL | x = 0;
24+
| ^^^^^ cannot assign twice to immutable variable
25+
|
26+
help: consider making this binding mutable
27+
|
28+
LL | let [mut x, ref xs_hold @ ..] = arr;
29+
| ~~~~~
30+
help: to modify the original value, take a borrow instead
31+
|
32+
LL | let [ref mut x, ref xs_hold @ ..] = arr;
33+
| ~~~~~~~~~
34+
35+
error: aborting due to 2 previous errors
36+
37+
For more information about this error, try `rustc --explain E0384`.

tests/ui/mut/mut-pattern-internal-mutability.stderr

+10-4
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,18 @@ error[E0384]: cannot assign twice to immutable variable `x`
22
--> $DIR/mut-pattern-internal-mutability.rs:5:5
33
|
44
LL | let &mut x = foo;
5-
| -
6-
| |
7-
| first assignment to `x`
8-
| help: consider making this binding mutable: `mut x`
5+
| - first assignment to `x`
96
LL | x += 1;
107
| ^^^^^^ cannot assign twice to immutable variable
8+
|
9+
help: consider making this binding mutable
10+
|
11+
LL | let &mut mut x = foo;
12+
| ~~~~~
13+
help: to modify the original value, take a borrow instead
14+
|
15+
LL | let &mut ref mut x = foo;
16+
| ~~~~~~~~~
1117

1218
error[E0506]: cannot assign to `*foo` because it is borrowed
1319
--> $DIR/mut-pattern-internal-mutability.rs:13:5

tests/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr

+10-4
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,19 @@ error[E0384]: cannot assign twice to immutable variable `a`
7070
--> $DIR/pat-at-same-name-both.rs:13:15
7171
|
7272
LL | Ok(a @ b @ a)
73-
| -
74-
| |
75-
| first assignment to `a`
76-
| help: consider making this binding mutable: `mut a`
73+
| - first assignment to `a`
7774
LL |
7875
LL | | Err(a @ b @ a)
7976
| ^ cannot assign twice to immutable variable
77+
|
78+
help: consider making this binding mutable
79+
|
80+
LL | Ok(a @ b @ mut a)
81+
| ~~~~~
82+
help: to modify the original value, take a borrow instead
83+
|
84+
LL | Ok(a @ b @ ref mut a)
85+
| ~~~~~~~~~
8086

8187
error: aborting due to 12 previous errors
8288

tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr

+20-8
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,18 @@ error[E0384]: cannot assign twice to immutable variable `_x1`
1515
--> $DIR/borrowck-move-ref-pattern.rs:9:5
1616
|
1717
LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr;
18-
| ---
19-
| |
20-
| first assignment to `_x1`
21-
| help: consider making this binding mutable: `mut _x1`
18+
| --- first assignment to `_x1`
2219
LL | _x1 = U;
2320
| ^^^^^^^ cannot assign twice to immutable variable
21+
|
22+
help: consider making this binding mutable
23+
|
24+
LL | let [ref _x0_hold, mut _x1, ref xs_hold @ ..] = arr;
25+
| ~~~~~~~
26+
help: to modify the original value, take a borrow instead
27+
|
28+
LL | let [ref _x0_hold, ref mut _x1, ref xs_hold @ ..] = arr;
29+
| ~~~~~~~~~~~
2430

2531
error[E0505]: cannot move out of `arr[..]` because it is borrowed
2632
--> $DIR/borrowck-move-ref-pattern.rs:11:10
@@ -73,12 +79,18 @@ error[E0384]: cannot assign twice to immutable variable `_x1`
7379
--> $DIR/borrowck-move-ref-pattern.rs:23:5
7480
|
7581
LL | let (ref _x0, _x1, ref _x2, ..) = tup;
76-
| ---
77-
| |
78-
| first assignment to `_x1`
79-
| help: consider making this binding mutable: `mut _x1`
82+
| --- first assignment to `_x1`
8083
LL | _x1 = U;
8184
| ^^^^^^^ cannot assign twice to immutable variable
85+
|
86+
help: consider making this binding mutable
87+
|
88+
LL | let (ref _x0, mut _x1, ref _x2, ..) = tup;
89+
| ~~~~~~~
90+
help: to modify the original value, take a borrow instead
91+
|
92+
LL | let (ref _x0, ref mut _x1, ref _x2, ..) = tup;
93+
| ~~~~~~~~~~~
8294

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

tests/ui/pattern/mut-ref-mut-2021.stderr

+10-4
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,18 @@ error[E0384]: cannot assign twice to immutable variable `a`
22
--> $DIR/mut-ref-mut-2021.rs:9:5
33
|
44
LL | let Foo(a) = Foo(0);
5-
| -
6-
| |
7-
| first assignment to `a`
8-
| help: consider making this binding mutable: `mut a`
5+
| - first assignment to `a`
96
LL | a = 42;
107
| ^^^^^^ cannot assign twice to immutable variable
8+
|
9+
help: consider making this binding mutable
10+
|
11+
LL | let Foo(mut a) = Foo(0);
12+
| ~~~~~
13+
help: to modify the original value, take a borrow instead
14+
|
15+
LL | let Foo(ref mut a) = Foo(0);
16+
| ~~~~~~~~~
1117

1218
error[E0384]: cannot assign twice to immutable variable `a`
1319
--> $DIR/mut-ref-mut-2021.rs:15:5

0 commit comments

Comments
 (0)