diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index d0e17bf5a0848..34d466db2b409 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 0000000000000..0dad55be3acff --- /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 0000000000000..6b7a42e495999 --- /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`.