Skip to content

Commit

Permalink
Account for derefs when suggesting assoc function
Browse files Browse the repository at this point in the history
  • Loading branch information
estebank committed Oct 5, 2019
1 parent 5497ba1 commit 3166ce8
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 3 deletions.
21 changes: 19 additions & 2 deletions src/librustc_typeck/check/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
));
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/issues/issue-3707.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
Original file line number Diff line number Diff line change
@@ -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>`
}
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 3166ce8

Please sign in to comment.