diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-06-06 12:00:33 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-06-06 12:00:33 +0200 |
| commit | 21e7463bf8eb45cc8d9d9e4e111e64061da0d16a (patch) | |
| tree | 31a0a7ed3b15f9496ab08c1a0afe66a88578c099 | |
| parent | 29871d5480c887abdaf4b8b2b925a9e4aee7b521 (diff) | |
| parent | 57e67e4ab21b466158a3e7eeaf598baefc18ad72 (diff) | |
| download | rust-21e7463bf8eb45cc8d9d9e4e111e64061da0d16a.tar.gz rust-21e7463bf8eb45cc8d9d9e4e111e64061da0d16a.zip | |
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.
| -rw-r--r-- | compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs | 28 | ||||
| -rw-r--r-- | tests/ui/borrowck/issue-111554.rs | 28 | ||||
| -rw-r--r-- | tests/ui/borrowck/issue-111554.stderr | 29 |
3 files changed, 79 insertions, 6 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index d0e17bf5a08..34d466db2b4 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -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; diff --git a/tests/ui/borrowck/issue-111554.rs b/tests/ui/borrowck/issue-111554.rs new file mode 100644 index 00000000000..0dad55be3ac --- /dev/null +++ b/tests/ui/borrowck/issue-111554.rs @@ -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() {} diff --git a/tests/ui/borrowck/issue-111554.stderr b/tests/ui/borrowck/issue-111554.stderr new file mode 100644 index 00000000000..6b7a42e4959 --- /dev/null +++ b/tests/ui/borrowck/issue-111554.stderr @@ -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`. |
