about summary refs log tree commit diff
diff options
context:
space:
mode:
author许杰友 Jieyou Xu (Joe) <jieyouxu@outlook.com>2023-05-27 21:25:25 +0800
committer许杰友 Jieyou Xu (Joe) <jieyouxu@outlook.com>2023-05-29 13:11:03 +0800
commit57e67e4ab21b466158a3e7eeaf598baefc18ad72 (patch)
treec0f4d3c41cb5baf93c92fd96e16a6bc7c08d91ef
parentb9c5fdc888e05be88269a47d40fd0d911ec2be0b (diff)
downloadrust-57e67e4ab21b466158a3e7eeaf598baefc18ad72.tar.gz
rust-57e67e4ab21b466158a3e7eeaf598baefc18ad72.zip
Don't suggest changing {ImmRef,MutRef} implicit self to be mutable
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs28
-rw-r--r--tests/ui/borrowck/issue-111554.rs28
-rw-r--r--tests/ui/borrowck/issue-111554.stderr29
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`.