Skip to content

Commit 58bfe3b

Browse files
authored
Rollup merge of #65145 - estebank:turbofish-assoc-fn-call, r=varkor
When suggesting assoc function with type params, include turbofish Fix #61412, fix #61411.
2 parents 153d3c3 + 3166ce8 commit 58bfe3b

6 files changed

+102
-9
lines changed

src/librustc_typeck/check/method/suggest.rs

+36-8
Original file line numberDiff line numberDiff line change
@@ -461,16 +461,36 @@ 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 {
465-
err.span_suggestion(expr.span.to(span),
466-
"use associated function syntax instead",
467-
format!("{}::{}",
468-
self.ty_to_string(actual),
469-
item_name),
470-
Applicability::MachineApplicable);
482+
err.span_suggestion(
483+
expr.span.to(span),
484+
"use associated function syntax instead",
485+
format!("{}::{}", ty_str, item_name),
486+
Applicability::MachineApplicable,
487+
);
471488
} else {
472-
err.help(&format!("try with `{}::{}`",
473-
self.ty_to_string(actual), item_name));
489+
err.help(&format!(
490+
"try with `{}::{}`",
491+
ty_str,
492+
item_name,
493+
));
474494
}
475495

476496
report_candidates(span, &mut err, static_sources);
@@ -586,6 +606,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
586606
None
587607
}
588608

609+
/// Print out the type for use in value namespace.
610+
fn ty_to_value_string(&self, ty: Ty<'tcx>) -> String {
611+
match ty.kind {
612+
ty::Adt(def, substs) => format!("{}", ty::Instance::new(def.did, substs)),
613+
_ => self.ty_to_string(ty),
614+
}
615+
}
616+
589617
fn suggest_use_candidates(&self,
590618
err: &mut DiagnosticBuilder<'_>,
591619
mut msg: String,

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

+1-1
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`
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+
}
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`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
struct GenericAssocMethod<T>(T);
2+
3+
impl<T> GenericAssocMethod<T> {
4+
fn default_hello() {}
5+
}
6+
7+
fn main() {
8+
let x = GenericAssocMethod(33i32);
9+
x.default_hello();
10+
//~^ ERROR no method named `default_hello` found for type `GenericAssocMethod<i32>`
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
error[E0599]: no method named `default_hello` found for type `GenericAssocMethod<i32>` in the current scope
2+
--> $DIR/suggest-assoc-fn-call-with-turbofish.rs:9:7
3+
|
4+
LL | struct GenericAssocMethod<T>(T);
5+
| -------------------------------- method `default_hello` not found for this
6+
...
7+
LL | x.default_hello();
8+
| --^^^^^^^^^^^^^
9+
| | |
10+
| | this is an associated function, not a method
11+
| help: use associated function syntax instead: `GenericAssocMethod::<i32>::default_hello`
12+
|
13+
= note: found the following associated functions; to be used as methods, functions must have a `self` parameter
14+
note: the candidate is defined in an impl for the type `GenericAssocMethod<_>`
15+
--> $DIR/suggest-assoc-fn-call-with-turbofish.rs:4:5
16+
|
17+
LL | fn default_hello() {}
18+
| ^^^^^^^^^^^^^^^^^^
19+
20+
error: aborting due to previous error
21+
22+
For more information about this error, try `rustc --explain E0599`.

0 commit comments

Comments
 (0)