Skip to content

Commit 3166ce8

Browse files
committed
Account for derefs when suggesting assoc function
1 parent 5497ba1 commit 3166ce8

File tree

4 files changed

+52
-3
lines changed

4 files changed

+52
-3
lines changed

src/librustc_typeck/check/method/suggest.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,17 +461,34 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
461461
err.span_label(span, "this is an associated function, not a method");
462462
}
463463
if static_sources.len() == 1 {
464+
let ty_str = if let Some(CandidateSource::ImplSource(
465+
impl_did,
466+
)) = static_sources.get(0) {
467+
// When the "method" is resolved through dereferencing, we really want the
468+
// original type that has the associated function for accurate suggestions.
469+
// (#61411)
470+
let ty = self.impl_self_ty(span, *impl_did).ty;
471+
match (&ty.peel_refs().kind, &actual.peel_refs().kind) {
472+
(ty::Adt(def, _), ty::Adt(def_actual, _)) if def == def_actual => {
473+
// Use `actual` as it will have more `substs` filled in.
474+
self.ty_to_value_string(actual.peel_refs())
475+
}
476+
_ => self.ty_to_value_string(ty.peel_refs()),
477+
}
478+
} else {
479+
self.ty_to_value_string(actual.peel_refs())
480+
};
464481
if let SelfSource::MethodCall(expr) = source {
465482
err.span_suggestion(
466483
expr.span.to(span),
467484
"use associated function syntax instead",
468-
format!("{}::{}", self.ty_to_value_string(actual), item_name),
485+
format!("{}::{}", ty_str, item_name),
469486
Applicability::MachineApplicable,
470487
);
471488
} else {
472489
err.help(&format!(
473490
"try with `{}::{}`",
474-
self.ty_to_value_string(actual),
491+
ty_str,
475492
item_name,
476493
));
477494
}

src/test/ui/issues/issue-3707.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | self.boom();
55
| -----^^^^
66
| | |
77
| | this is an associated function, not a method
8-
| help: use associated function syntax instead: `&Obj::boom`
8+
| help: use associated function syntax instead: `Obj::boom`
99
|
1010
= note: found the following associated functions; to be used as methods, functions must have a `self` parameter
1111
note: the candidate is defined in an impl for the type `Obj`
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use std::cell::RefCell;
2+
3+
struct HasAssocMethod;
4+
5+
impl HasAssocMethod {
6+
fn hello() {}
7+
}
8+
fn main() {
9+
let shared_state = RefCell::new(HasAssocMethod);
10+
let state = shared_state.borrow_mut();
11+
state.hello();
12+
//~^ ERROR no method named `hello` found for type `std::cell::RefMut<'_, HasAssocMethod>`
13+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error[E0599]: no method named `hello` found for type `std::cell::RefMut<'_, HasAssocMethod>` in the current scope
2+
--> $DIR/suggest-assoc-fn-call-with-turbofish-through-deref.rs:11:11
3+
|
4+
LL | state.hello();
5+
| ------^^^^^
6+
| | |
7+
| | this is an associated function, not a method
8+
| help: use associated function syntax instead: `HasAssocMethod::hello`
9+
|
10+
= note: found the following associated functions; to be used as methods, functions must have a `self` parameter
11+
note: the candidate is defined in an impl for the type `HasAssocMethod`
12+
--> $DIR/suggest-assoc-fn-call-with-turbofish-through-deref.rs:6:5
13+
|
14+
LL | fn hello() {}
15+
| ^^^^^^^^^^
16+
17+
error: aborting due to previous error
18+
19+
For more information about this error, try `rustc --explain E0599`.

0 commit comments

Comments
 (0)