about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs32
-rw-r--r--src/test/ui/borrowck/issue-93093.rs14
-rw-r--r--src/test/ui/borrowck/issue-93093.stderr12
3 files changed, 52 insertions, 6 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index 8ed50075ecb..049c3aab979 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -488,12 +488,32 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                                     // don't create labels for compiler-generated spans
                                     Some(_) => None,
                                     None => {
-                                        let (span, suggestion) = suggest_ampmut(
-                                            self.infcx.tcx,
-                                            local_decl,
-                                            opt_assignment_rhs_span,
-                                            *opt_ty_info,
-                                        );
+                                        let (span, suggestion) = if name != kw::SelfLower {
+                                            suggest_ampmut(
+                                                self.infcx.tcx,
+                                                local_decl,
+                                                opt_assignment_rhs_span,
+                                                *opt_ty_info,
+                                            )
+                                        } else {
+                                            match local_decl.local_info.as_deref() {
+                                                Some(LocalInfo::User(ClearCrossCrate::Set(
+                                                    mir::BindingForm::Var(mir::VarBindingForm {
+                                                        opt_ty_info: None,
+                                                        ..
+                                                    }),
+                                                ))) => {
+                                                    suggest_ampmut_self(self.infcx.tcx, local_decl)
+                                                }
+                                                // explicit self (eg `self: &'a Self`)
+                                                _ => suggest_ampmut(
+                                                    self.infcx.tcx,
+                                                    local_decl,
+                                                    opt_assignment_rhs_span,
+                                                    *opt_ty_info,
+                                                ),
+                                            }
+                                        };
                                         Some((true, span, suggestion))
                                     }
                                 }
diff --git a/src/test/ui/borrowck/issue-93093.rs b/src/test/ui/borrowck/issue-93093.rs
new file mode 100644
index 00000000000..f4db5ecafac
--- /dev/null
+++ b/src/test/ui/borrowck/issue-93093.rs
@@ -0,0 +1,14 @@
+// edition:2018
+struct S {
+    foo: usize,
+}
+impl S {
+    async fn bar(&self) { //~ HELP consider changing this to be a mutable reference
+        //~| SUGGESTION &mut self
+        self.foo += 1; //~ ERROR cannot assign to `self.foo`, which is behind a `&` reference [E0594]
+    }
+}
+
+fn main() {
+    S { foo: 1 }.bar();
+}
diff --git a/src/test/ui/borrowck/issue-93093.stderr b/src/test/ui/borrowck/issue-93093.stderr
new file mode 100644
index 00000000000..031128af476
--- /dev/null
+++ b/src/test/ui/borrowck/issue-93093.stderr
@@ -0,0 +1,12 @@
+error[E0594]: cannot assign to `self.foo`, which is behind a `&` reference
+  --> $DIR/issue-93093.rs:8:9
+   |
+LL |     async fn bar(&self) {
+   |                  ----- help: consider changing this to be a mutable reference: `&mut self`
+LL |
+LL |         self.foo += 1;
+   |         ^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0594`.