Skip to content

Commit 549846e

Browse files
authored
Rollup merge of #147141 - estebank:issue-81059, r=jackh726
Suggest making binding `mut` on `&mut` reborrow When a binding needs to be mutably reborrowed multiple times, suggesting removing `&mut` will lead to follow up errors. Instead suggest both making the binding mutable and removing the reborrow. ``` error[E0596]: cannot borrow `outer` as mutable, as it is not declared as mutable --> f14.rs:2:12 | 2 | match (&mut outer, 23) { | ^^^^^^^^^^ cannot borrow as mutable | note: the binding is already a mutable borrow --> f14.rs:1:16 | 1 | fn test(outer: &mut Option<i32>) { | ^^^^^^^^^^^^^^^^ help: consider making the binding mutable if you need to reborrow multiple times | 1 | fn test(mut outer: &mut Option<i32>) { | +++ help: if there is only one mutable reborrow, remove the `&mut` | 2 - match (&mut outer, 23) { 2 + match (outer, 23) { | ``` Address #81059.
2 parents 1f880d9 + 516a273 commit 549846e

File tree

9 files changed

+75
-47
lines changed

9 files changed

+75
-47
lines changed

compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,10 +335,18 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
335335
LocalInfo::User(BindingForm::Var(mir::VarBindingForm {
336336
binding_mode: BindingMode(ByRef::No, Mutability::Not),
337337
opt_ty_info: Some(sp),
338+
pat_span,
338339
..
339340
})) => {
340341
if suggest {
341342
err.span_note(sp, "the binding is already a mutable borrow");
343+
err.span_suggestion_verbose(
344+
pat_span.shrink_to_lo(),
345+
"consider making the binding mutable if you need to reborrow \
346+
multiple times",
347+
"mut ".to_string(),
348+
Applicability::MaybeIncorrect,
349+
);
342350
}
343351
}
344352
_ => {
@@ -356,9 +364,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
356364
// give a best effort structured suggestion.
357365
err.span_suggestion_verbose(
358366
source_info.span.with_hi(source_info.span.lo() + BytePos(5)),
359-
"try removing `&mut` here",
367+
"if there is only one mutable reborrow, remove the `&mut`",
360368
"",
361-
Applicability::MachineApplicable,
369+
Applicability::MaybeIncorrect,
362370
);
363371
} else {
364372
// This can occur with things like `(&mut self).foo()`.

tests/ui/borrowck/mut-borrow-of-mut-ref.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,24 @@
22
#![crate_type = "rlib"]
33

44
pub fn f(b: &mut i32) {
5-
//~^ ERROR cannot borrow
6-
//~| NOTE not mutable
7-
//~| NOTE the binding is already a mutable borrow
5+
//~^ ERROR: cannot borrow
6+
//~| NOTE: not mutable
7+
//~| NOTE: the binding is already a mutable borrow
8+
//~| HELP: consider making the binding mutable if you need to reborrow multiple times
89
h(&mut b);
9-
//~^ NOTE cannot borrow as mutable
10-
//~| HELP try removing `&mut` here
10+
//~^ NOTE: cannot borrow as mutable
11+
//~| HELP: if there is only one mutable reborrow, remove the `&mut`
1112
g(&mut &mut b);
12-
//~^ NOTE cannot borrow as mutable
13-
//~| HELP try removing `&mut` here
13+
//~^ NOTE: cannot borrow as mutable
14+
//~| HELP: if there is only one mutable reborrow, remove the `&mut`
1415
}
1516

16-
pub fn g(b: &mut i32) { //~ NOTE the binding is already a mutable borrow
17+
pub fn g(b: &mut i32) { //~ NOTE: the binding is already a mutable borrow
18+
//~^ HELP: consider making the binding mutable if you need to reborrow multiple times
1719
h(&mut &mut b);
18-
//~^ ERROR cannot borrow
19-
//~| NOTE cannot borrow as mutable
20-
//~| HELP try removing `&mut` here
20+
//~^ ERROR: cannot borrow
21+
//~| NOTE: cannot borrow as mutable
22+
//~| HELP: if there is only one mutable reborrow, remove the `&mut`
2123
}
2224

2325
pub fn h(_: &mut i32) {}

tests/ui/borrowck/mut-borrow-of-mut-ref.stderr

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,36 +15,44 @@ note: the binding is already a mutable borrow
1515
|
1616
LL | pub fn f(b: &mut i32) {
1717
| ^^^^^^^^
18-
help: try removing `&mut` here
18+
help: consider making the binding mutable if you need to reborrow multiple times
19+
|
20+
LL | pub fn f(mut b: &mut i32) {
21+
| +++
22+
help: if there is only one mutable reborrow, remove the `&mut`
1923
|
2024
LL - h(&mut b);
2125
LL + h(b);
2226
|
23-
help: try removing `&mut` here
27+
help: if there is only one mutable reborrow, remove the `&mut`
2428
|
2529
LL - g(&mut &mut b);
2630
LL + g(&mut b);
2731
|
2832

2933
error[E0596]: cannot borrow `b` as mutable, as it is not declared as mutable
30-
--> $DIR/mut-borrow-of-mut-ref.rs:17:12
34+
--> $DIR/mut-borrow-of-mut-ref.rs:19:12
3135
|
3236
LL | h(&mut &mut b);
3337
| ^^^^^^ cannot borrow as mutable
3438
|
3539
note: the binding is already a mutable borrow
36-
--> $DIR/mut-borrow-of-mut-ref.rs:16:13
40+
--> $DIR/mut-borrow-of-mut-ref.rs:17:13
3741
|
3842
LL | pub fn g(b: &mut i32) {
3943
| ^^^^^^^^
40-
help: try removing `&mut` here
44+
help: consider making the binding mutable if you need to reborrow multiple times
45+
|
46+
LL | pub fn g(mut b: &mut i32) {
47+
| +++
48+
help: if there is only one mutable reborrow, remove the `&mut`
4149
|
4250
LL - h(&mut &mut b);
4351
LL + h(&mut b);
4452
|
4553

4654
error[E0596]: cannot borrow `f` as mutable, as it is not declared as mutable
47-
--> $DIR/mut-borrow-of-mut-ref.rs:34:5
55+
--> $DIR/mut-borrow-of-mut-ref.rs:36:5
4856
|
4957
LL | f.bar();
5058
| ^ cannot borrow as mutable

tests/ui/did_you_mean/issue-31424.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,18 @@ struct Struct;
44

55
impl Struct {
66
fn foo(&mut self) {
7-
(&mut self).bar(); //~ ERROR cannot borrow
8-
//~^ HELP try removing `&mut` here
7+
(&mut self).bar(); //~ ERROR: cannot borrow
8+
//~^ HELP: try removing `&mut` here
99
}
1010

1111
// In this case we could keep the suggestion, but to distinguish the
1212
// two cases is pretty hard. It's an obscure case anyway.
1313
fn bar(self: &mut Self) {
14-
//~^ WARN function cannot return without recursing
15-
//~^^ HELP a `loop` may express intention better if this is on purpose
14+
//~^ WARN: function cannot return without recursing
15+
//~| HELP: a `loop` may express intention better if this is on purpose
16+
//~| HELP: consider making the binding mutable if you need to reborrow multiple times
1617
(&mut self).bar(); //~ ERROR cannot borrow
17-
//~^ HELP try removing `&mut` here
18+
//~^ HELP: try removing `&mut` here
1819
}
1920
}
2021

tests/ui/did_you_mean/issue-31424.stderr

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ LL | (&mut self).bar();
2828
= note: `#[warn(unconditional_recursion)]` on by default
2929

3030
error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
31-
--> $DIR/issue-31424.rs:16:9
31+
--> $DIR/issue-31424.rs:17:9
3232
|
3333
LL | (&mut self).bar();
3434
| ^^^^^^^^^^^ cannot borrow as mutable
@@ -39,10 +39,14 @@ note: the binding is already a mutable borrow
3939
LL | fn bar(self: &mut Self) {
4040
| ^^^^^^^^^
4141
help: try removing `&mut` here
42-
--> $DIR/issue-31424.rs:16:9
42+
--> $DIR/issue-31424.rs:17:9
4343
|
4444
LL | (&mut self).bar();
4545
| ^^^^^^^^^^^
46+
help: consider making the binding mutable if you need to reborrow multiple times
47+
|
48+
LL | fn bar(mut self: &mut Self) {
49+
| +++
4650

4751
error: aborting due to 2 previous errors; 1 warning emitted
4852

tests/ui/did_you_mean/issue-34126.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ struct Z { }
33
impl Z {
44
fn run(&self, z: &mut Z) { }
55
fn start(&mut self) {
6-
self.run(&mut self); //~ ERROR cannot borrow
7-
//~| ERROR cannot borrow
8-
//~| HELP try removing `&mut` here
6+
self.run(&mut self); //~ ERROR: cannot borrow
7+
//~| ERROR: cannot borrow
8+
//~| HELP: if there is only one mutable reborrow, remove the `&mut`
99
}
1010
}
1111

tests/ui/did_you_mean/issue-34126.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ note: the binding is already a mutable borrow
99
|
1010
LL | fn start(&mut self) {
1111
| ^^^^^^^^^
12-
help: try removing `&mut` here
12+
help: if there is only one mutable reborrow, remove the `&mut`
1313
|
1414
LL - self.run(&mut self);
1515
LL + self.run(self);

tests/ui/nll/issue-51191.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@ struct Struct;
22

33
impl Struct {
44
fn bar(self: &mut Self) {
5-
//~^ WARN function cannot return without recursing
6-
//~^^ HELP a `loop` may express intention better if this is on purpose
5+
//~^ WARN: function cannot return without recursing
6+
//~| HELP: a `loop` may express intention better if this is on purpose
7+
//~| HELP: consider making the binding mutable if you need to reborrow multiple times
78
(&mut self).bar();
8-
//~^ ERROR cannot borrow `self` as mutable, as it is not declared as mutable [E0596]
9-
//~^^ HELP try removing `&mut` here
9+
//~^ ERROR: cannot borrow `self` as mutable, as it is not declared as mutable [E0596]
10+
//~| HELP: try removing `&mut` here
1011
}
1112

1213
fn imm(self) { //~ HELP consider changing this to be mutable
1314
(&mut self).bar();
14-
//~^ ERROR cannot borrow `self` as mutable, as it is not declared as mutable [E0596]
15+
//~^ ERROR: cannot borrow `self` as mutable, as it is not declared as mutable [E0596]
1516
}
1617

1718
fn mtbl(mut self) {
@@ -20,14 +21,14 @@ impl Struct {
2021

2122
fn immref(&self) {
2223
(&mut self).bar();
23-
//~^ ERROR cannot borrow `self` as mutable, as it is not declared as mutable [E0596]
24-
//~^^ ERROR cannot borrow data in a `&` reference as mutable [E0596]
24+
//~^ ERROR: cannot borrow `self` as mutable, as it is not declared as mutable [E0596]
25+
//~| ERROR: cannot borrow data in a `&` reference as mutable [E0596]
2526
}
2627

2728
fn mtblref(&mut self) {
2829
(&mut self).bar();
29-
//~^ ERROR cannot borrow `self` as mutable, as it is not declared as mutable [E0596]
30-
//~^^ HELP try removing `&mut` here
30+
//~^ ERROR: cannot borrow `self` as mutable, as it is not declared as mutable [E0596]
31+
//~| HELP: try removing `&mut` here
3132
}
3233
}
3334

tests/ui/nll/issue-51191.stderr

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ LL | (&mut self).bar();
1111
= note: `#[warn(unconditional_recursion)]` on by default
1212

1313
error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
14-
--> $DIR/issue-51191.rs:7:9
14+
--> $DIR/issue-51191.rs:8:9
1515
|
1616
LL | (&mut self).bar();
1717
| ^^^^^^^^^^^ cannot borrow as mutable
@@ -22,13 +22,17 @@ note: the binding is already a mutable borrow
2222
LL | fn bar(self: &mut Self) {
2323
| ^^^^^^^^^
2424
help: try removing `&mut` here
25-
--> $DIR/issue-51191.rs:7:9
25+
--> $DIR/issue-51191.rs:8:9
2626
|
2727
LL | (&mut self).bar();
2828
| ^^^^^^^^^^^
29+
help: consider making the binding mutable if you need to reborrow multiple times
30+
|
31+
LL | fn bar(mut self: &mut Self) {
32+
| +++
2933

3034
error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
31-
--> $DIR/issue-51191.rs:13:9
35+
--> $DIR/issue-51191.rs:14:9
3236
|
3337
LL | (&mut self).bar();
3438
| ^^^^^^^^^^^ cannot borrow as mutable
@@ -39,30 +43,30 @@ LL | fn imm(mut self) {
3943
| +++
4044

4145
error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
42-
--> $DIR/issue-51191.rs:22:9
46+
--> $DIR/issue-51191.rs:23:9
4347
|
4448
LL | (&mut self).bar();
4549
| ^^^^^^^^^^^ cannot borrow as mutable
4650

4751
error[E0596]: cannot borrow data in a `&` reference as mutable
48-
--> $DIR/issue-51191.rs:22:9
52+
--> $DIR/issue-51191.rs:23:9
4953
|
5054
LL | (&mut self).bar();
5155
| ^^^^^^^^^^^ cannot borrow as mutable
5256

5357
error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
54-
--> $DIR/issue-51191.rs:28:9
58+
--> $DIR/issue-51191.rs:29:9
5559
|
5660
LL | (&mut self).bar();
5761
| ^^^^^^^^^^^ cannot borrow as mutable
5862
|
5963
note: the binding is already a mutable borrow
60-
--> $DIR/issue-51191.rs:27:16
64+
--> $DIR/issue-51191.rs:28:16
6165
|
6266
LL | fn mtblref(&mut self) {
6367
| ^^^^^^^^^
6468
help: try removing `&mut` here
65-
--> $DIR/issue-51191.rs:28:9
69+
--> $DIR/issue-51191.rs:29:9
6670
|
6771
LL | (&mut self).bar();
6872
| ^^^^^^^^^^^

0 commit comments

Comments
 (0)