Skip to content

Commit 21e7463

Browse files
authored
Rollup merge of #112019 - jieyouxu:issue-111554, r=compiler-errors
Don't suggest changing `&self` and `&mut self` in function signature to be mutable when taking `&mut self` in closure Current suggestion for when taking a mutable reference to `self` in a closure (as an upvar) will produce a machine-applicable suggestion to change the `self` in the function signature to `mut self`, but does not account for the specialness of implicit self in that it can already have `&` and `&mut` (see #111554). This causes the function signature to become `test(&mut mut self)` which does not seem desirable. ``` error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable --> src/sound_player.rs:870:11 | 869 | pub fn test(&mut self) { | ---- help: consider changing this to be mutable: `mut self` 870 | || test2(&mut self); | ^^^^^^^^^ cannot borrow as mutable ``` This PR suppresses the "changing this to be mutable" suggestion if the implicit self is either `ImplicitSelfKind::ImmRef` or `ImplicitSelfKind::MutRef`. Fixes #111554.
2 parents 29871d5 + 57e67e4 commit 21e7463

File tree

3 files changed

+79
-6
lines changed

3 files changed

+79
-6
lines changed

compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

+22-6
Original file line numberDiff line numberDiff line change
@@ -416,12 +416,28 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
416416
_,
417417
) = pat.kind
418418
{
419-
err.span_suggestion(
420-
upvar_ident.span,
421-
"consider changing this to be mutable",
422-
format!("mut {}", upvar_ident.name),
423-
Applicability::MachineApplicable,
424-
);
419+
if upvar_ident.name == kw::SelfLower {
420+
for (_, node) in self.infcx.tcx.hir().parent_iter(upvar_hir_id) {
421+
if let Some(fn_decl) = node.fn_decl() {
422+
if !matches!(fn_decl.implicit_self, hir::ImplicitSelfKind::ImmRef | hir::ImplicitSelfKind::MutRef) {
423+
err.span_suggestion(
424+
upvar_ident.span,
425+
"consider changing this to be mutable",
426+
format!("mut {}", upvar_ident.name),
427+
Applicability::MachineApplicable,
428+
);
429+
break;
430+
}
431+
}
432+
}
433+
} else {
434+
err.span_suggestion(
435+
upvar_ident.span,
436+
"consider changing this to be mutable",
437+
format!("mut {}", upvar_ident.name),
438+
Applicability::MachineApplicable,
439+
);
440+
}
425441
}
426442

427443
let tcx = self.infcx.tcx;

tests/ui/borrowck/issue-111554.rs

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
struct Foo {}
2+
3+
impl Foo {
4+
pub fn foo(&mut self) {
5+
|| bar(&mut self);
6+
//~^ ERROR cannot borrow `self` as mutable, as it is not declared as mutable
7+
}
8+
9+
pub fn baz(&self) {
10+
|| bar(&mut self);
11+
//~^ ERROR cannot borrow `self` as mutable, as it is not declared as mutable
12+
//~| ERROR cannot borrow data in a `&` reference as mutable
13+
}
14+
15+
pub fn qux(mut self) {
16+
|| bar(&mut self);
17+
// OK
18+
}
19+
20+
pub fn quux(self) {
21+
|| bar(&mut self);
22+
//~^ ERROR cannot borrow `self` as mutable, as it is not declared as mutable
23+
}
24+
}
25+
26+
fn bar(_: &mut Foo) {}
27+
28+
fn main() {}

tests/ui/borrowck/issue-111554.stderr

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
2+
--> $DIR/issue-111554.rs:5:16
3+
|
4+
LL | || bar(&mut self);
5+
| ^^^^^^^^^ cannot borrow as mutable
6+
7+
error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
8+
--> $DIR/issue-111554.rs:10:16
9+
|
10+
LL | || bar(&mut self);
11+
| ^^^^^^^^^ cannot borrow as mutable
12+
13+
error[E0596]: cannot borrow data in a `&` reference as mutable
14+
--> $DIR/issue-111554.rs:10:16
15+
|
16+
LL | || bar(&mut self);
17+
| ^^^^^^^^^ cannot borrow as mutable
18+
19+
error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
20+
--> $DIR/issue-111554.rs:21:16
21+
|
22+
LL | pub fn quux(self) {
23+
| ---- help: consider changing this to be mutable: `mut self`
24+
LL | || bar(&mut self);
25+
| ^^^^^^^^^ cannot borrow as mutable
26+
27+
error: aborting due to 4 previous errors
28+
29+
For more information about this error, try `rustc --explain E0596`.

0 commit comments

Comments
 (0)