Skip to content

Commit

Permalink
Rollup merge of rust-lang#112019 - jieyouxu:issue-111554, r=compiler-…
Browse files Browse the repository at this point in the history
…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 rust-lang#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 rust-lang#111554.
  • Loading branch information
matthiaskrgr authored Jun 6, 2023
2 parents cfb96d8 + 57e67e4 commit 86076cd
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 6 deletions.
28 changes: 22 additions & 6 deletions compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,12 +416,28 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
_,
) = pat.kind
{
err.span_suggestion(
upvar_ident.span,
"consider changing this to be mutable",
format!("mut {}", upvar_ident.name),
Applicability::MachineApplicable,
);
if upvar_ident.name == kw::SelfLower {
for (_, node) in self.infcx.tcx.hir().parent_iter(upvar_hir_id) {
if let Some(fn_decl) = node.fn_decl() {
if !matches!(fn_decl.implicit_self, hir::ImplicitSelfKind::ImmRef | hir::ImplicitSelfKind::MutRef) {
err.span_suggestion(
upvar_ident.span,
"consider changing this to be mutable",
format!("mut {}", upvar_ident.name),
Applicability::MachineApplicable,
);
break;
}
}
}
} else {
err.span_suggestion(
upvar_ident.span,
"consider changing this to be mutable",
format!("mut {}", upvar_ident.name),
Applicability::MachineApplicable,
);
}
}

let tcx = self.infcx.tcx;
Expand Down
28 changes: 28 additions & 0 deletions tests/ui/borrowck/issue-111554.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
struct Foo {}

impl Foo {
pub fn foo(&mut self) {
|| bar(&mut self);
//~^ ERROR cannot borrow `self` as mutable, as it is not declared as mutable
}

pub fn baz(&self) {
|| bar(&mut self);
//~^ ERROR cannot borrow `self` as mutable, as it is not declared as mutable
//~| ERROR cannot borrow data in a `&` reference as mutable
}

pub fn qux(mut self) {
|| bar(&mut self);
// OK
}

pub fn quux(self) {
|| bar(&mut self);
//~^ ERROR cannot borrow `self` as mutable, as it is not declared as mutable
}
}

fn bar(_: &mut Foo) {}

fn main() {}
29 changes: 29 additions & 0 deletions tests/ui/borrowck/issue-111554.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
--> $DIR/issue-111554.rs:5:16
|
LL | || bar(&mut self);
| ^^^^^^^^^ cannot borrow as mutable

error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
--> $DIR/issue-111554.rs:10:16
|
LL | || bar(&mut self);
| ^^^^^^^^^ cannot borrow as mutable

error[E0596]: cannot borrow data in a `&` reference as mutable
--> $DIR/issue-111554.rs:10:16
|
LL | || bar(&mut self);
| ^^^^^^^^^ cannot borrow as mutable

error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
--> $DIR/issue-111554.rs:21:16
|
LL | pub fn quux(self) {
| ---- help: consider changing this to be mutable: `mut self`
LL | || bar(&mut self);
| ^^^^^^^^^ cannot borrow as mutable

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0596`.

0 comments on commit 86076cd

Please sign in to comment.