about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_typeck/check/method/suggest.rs21
-rw-r--r--src/test/ui/issues/issue-3707.stderr2
-rw-r--r--src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.rs13
-rw-r--r--src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr19
4 files changed, 52 insertions, 3 deletions
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 7ce855c73c7..621124541d1 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -461,17 +461,34 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     err.span_label(span, "this is an associated function, not a method");
                 }
                 if static_sources.len() == 1 {
+                    let ty_str = if let Some(CandidateSource::ImplSource(
+                        impl_did,
+                    )) = static_sources.get(0) {
+                        // When the "method" is resolved through dereferencing, we really want the
+                        // original type that has the associated function for accurate suggestions.
+                        // (#61411)
+                        let ty = self.impl_self_ty(span, *impl_did).ty;
+                        match (&ty.peel_refs().kind, &actual.peel_refs().kind) {
+                            (ty::Adt(def, _), ty::Adt(def_actual, _)) if def == def_actual => {
+                                // Use `actual` as it will have more `substs` filled in.
+                                self.ty_to_value_string(actual.peel_refs())
+                            }
+                            _ => self.ty_to_value_string(ty.peel_refs()),
+                        }
+                    } else {
+                        self.ty_to_value_string(actual.peel_refs())
+                    };
                     if let SelfSource::MethodCall(expr) = source {
                         err.span_suggestion(
                             expr.span.to(span),
                             "use associated function syntax instead",
-                            format!("{}::{}", self.ty_to_value_string(actual), item_name),
+                            format!("{}::{}", ty_str, item_name),
                             Applicability::MachineApplicable,
                         );
                     } else {
                         err.help(&format!(
                             "try with `{}::{}`",
-                            self.ty_to_value_string(actual),
+                            ty_str,
                             item_name,
                         ));
                     }
diff --git a/src/test/ui/issues/issue-3707.stderr b/src/test/ui/issues/issue-3707.stderr
index 05c8ce4c3f1..b98bc572a39 100644
--- a/src/test/ui/issues/issue-3707.stderr
+++ b/src/test/ui/issues/issue-3707.stderr
@@ -5,7 +5,7 @@ LL |         self.boom();
    |         -----^^^^
    |         |    |
    |         |    this is an associated function, not a method
-   |         help: use associated function syntax instead: `&Obj::boom`
+   |         help: use associated function syntax instead: `Obj::boom`
    |
    = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
 note: the candidate is defined in an impl for the type `Obj`
diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.rs b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.rs
new file mode 100644
index 00000000000..5480adb3101
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.rs
@@ -0,0 +1,13 @@
+use std::cell::RefCell;
+
+struct HasAssocMethod;
+
+impl HasAssocMethod {
+    fn hello() {}
+}
+fn main() {
+    let shared_state = RefCell::new(HasAssocMethod);
+    let state = shared_state.borrow_mut();
+    state.hello();
+    //~^ ERROR no method named `hello` found for type `std::cell::RefMut<'_, HasAssocMethod>`
+}
diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr
new file mode 100644
index 00000000000..a1c0126146e
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr
@@ -0,0 +1,19 @@
+error[E0599]: no method named `hello` found for type `std::cell::RefMut<'_, HasAssocMethod>` in the current scope
+  --> $DIR/suggest-assoc-fn-call-with-turbofish-through-deref.rs:11:11
+   |
+LL |     state.hello();
+   |     ------^^^^^
+   |     |     |
+   |     |     this is an associated function, not a method
+   |     help: use associated function syntax instead: `HasAssocMethod::hello`
+   |
+   = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
+note: the candidate is defined in an impl for the type `HasAssocMethod`
+  --> $DIR/suggest-assoc-fn-call-with-turbofish-through-deref.rs:6:5
+   |
+LL |     fn hello() {}
+   |     ^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.