Skip to content

Commit

Permalink
Rollup merge of rust-lang#65145 - estebank:turbofish-assoc-fn-call, r…
Browse files Browse the repository at this point in the history
…=varkor

When suggesting assoc function with type params, include turbofish

Fix rust-lang#61412, fix rust-lang#61411.
  • Loading branch information
Centril authored Oct 8, 2019
2 parents 153d3c3 + 3166ce8 commit 58bfe3b
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 9 deletions.
44 changes: 36 additions & 8 deletions src/librustc_typeck/check/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,16 +461,36 @@ 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_string(actual),
item_name),
Applicability::MachineApplicable);
err.span_suggestion(
expr.span.to(span),
"use associated function syntax instead",
format!("{}::{}", ty_str, item_name),
Applicability::MachineApplicable,
);
} else {
err.help(&format!("try with `{}::{}`",
self.ty_to_string(actual), item_name));
err.help(&format!(
"try with `{}::{}`",
ty_str,
item_name,
));
}

report_candidates(span, &mut err, static_sources);
Expand Down Expand Up @@ -586,6 +606,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
None
}

/// Print out the type for use in value namespace.
fn ty_to_value_string(&self, ty: Ty<'tcx>) -> String {
match ty.kind {
ty::Adt(def, substs) => format!("{}", ty::Instance::new(def.did, substs)),
_ => self.ty_to_string(ty),
}
}

fn suggest_use_candidates(&self,
err: &mut DiagnosticBuilder<'_>,
mut msg: String,
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`.
11 changes: 11 additions & 0 deletions src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
struct GenericAssocMethod<T>(T);

impl<T> GenericAssocMethod<T> {
fn default_hello() {}
}

fn main() {
let x = GenericAssocMethod(33i32);
x.default_hello();
//~^ ERROR no method named `default_hello` found for type `GenericAssocMethod<i32>`
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
error[E0599]: no method named `default_hello` found for type `GenericAssocMethod<i32>` in the current scope
--> $DIR/suggest-assoc-fn-call-with-turbofish.rs:9:7
|
LL | struct GenericAssocMethod<T>(T);
| -------------------------------- method `default_hello` not found for this
...
LL | x.default_hello();
| --^^^^^^^^^^^^^
| | |
| | this is an associated function, not a method
| help: use associated function syntax instead: `GenericAssocMethod::<i32>::default_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 `GenericAssocMethod<_>`
--> $DIR/suggest-assoc-fn-call-with-turbofish.rs:4:5
|
LL | fn default_hello() {}
| ^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0599`.

0 comments on commit 58bfe3b

Please sign in to comment.