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.
This commit is contained in:
commit
21e7463bf8
@ -416,12 +416,28 @@ pub(crate) fn report_mutability_error(
|
||||
_,
|
||||
) = 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;
|
||||
|
28
tests/ui/borrowck/issue-111554.rs
Normal file
28
tests/ui/borrowck/issue-111554.rs
Normal file
@ -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
tests/ui/borrowck/issue-111554.stderr
Normal file
29
tests/ui/borrowck/issue-111554.stderr
Normal file
@ -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`.
|
Loading…
Reference in New Issue
Block a user