Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3369,6 +3369,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err.span_label(within_macro_span, "due to this macro variable");
}

// Check if there is an associated function with the same name.
if let Some(def_id) = base_ty.peel_refs().ty_adt_def().map(|d| d.did()) {
for impl_def_id in self.tcx.inherent_impls(def_id) {
for item in self.tcx.associated_items(impl_def_id).in_definition_order() {
if let ExprKind::Field(base_expr, _) = expr.kind
&& item.name() == field.name
&& matches!(item.kind, ty::AssocKind::Fn { has_self: false, .. })
{
err.span_label(field.span, "this is an associated function, not a method");
err.note("found the following associated function; to be used as method, it must have a `self` parameter");
let impl_ty = self.tcx.type_of(impl_def_id).instantiate_identity();
err.span_note(
self.tcx.def_span(item.def_id),
format!("the candidate is defined in an impl for the type `{impl_ty}`"),
);

let ty_str = match base_ty.peel_refs().kind() {
ty::Adt(def, args) => self.tcx.def_path_str_with_args(def.did(), args),
_ => base_ty.peel_refs().to_string(),
};
err.multipart_suggestion(
"use associated function syntax instead",
vec![
(base_expr.span, ty_str),
(base_expr.span.between(field.span), "::".to_string()),
],
Applicability::MaybeIncorrect,
);
return err;
}
}
}
}

// try to add a suggestion in case the field is a nested field of a field of the Adt
let mod_id = self.tcx.parent_module(expr.hir_id).to_def_id();
let (ty, unwrap) = if let ty::Adt(def, args) = base_ty.kind()
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2339,7 +2339,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
applicability = Applicability::HasPlaceholders;
"(...)".to_owned()
};
err.span_suggestion(
err.span_suggestion_verbose(
sugg_span,
"use associated function syntax instead",
format!("{ty_str}::{item_name}{args}"),
Expand Down
10 changes: 6 additions & 4 deletions tests/ui/issues/issue-4265.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,19 @@ LL | struct Foo {
| ---------- method `bar` not found for this struct
...
LL | Foo { baz: 0 }.bar();
| ---------------^^^--
| | |
| | this is an associated function, not a method
| help: use associated function syntax instead: `Foo::bar()`
| ^^^ this is an associated function, not a method
|
= 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 `Foo`
--> $DIR/issue-4265.rs:6:5
|
LL | fn bar() {
| ^^^^^^^^
help: use associated function syntax instead
|
LL - Foo { baz: 0 }.bar();
LL + Foo::bar();
|

error: aborting due to 2 previous errors

Expand Down
10 changes: 10 additions & 0 deletions tests/ui/methods/assc-func-issue-149038.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
struct S;
impl S {
fn foo() {}
fn bar(&self) {
self.foo(); //~ ERROR no method named `foo` found for reference `&S` in the current scope
let f: fn() = self.foo; //~ ERROR no field `foo` on type `&S`
}
}

fn main() {}
43 changes: 43 additions & 0 deletions tests/ui/methods/assc-func-issue-149038.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
error[E0599]: no method named `foo` found for reference `&S` in the current scope
--> $DIR/assc-func-issue-149038.rs:5:14
|
LL | self.foo();
| ^^^ this is an associated function, not a method
|
= 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 `S`
--> $DIR/assc-func-issue-149038.rs:3:5
|
LL | fn foo() {}
| ^^^^^^^^
help: use associated function syntax instead
|
LL - self.foo();
LL + S::foo();
|

error[E0609]: no field `foo` on type `&S`
--> $DIR/assc-func-issue-149038.rs:6:28
|
LL | let f: fn() = self.foo;
| ^^^
| |
| this is an associated function, not a method
| unknown field
|
= note: found the following associated function; to be used as method, it must have a `self` parameter
note: the candidate is defined in an impl for the type `S`
--> $DIR/assc-func-issue-149038.rs:3:5
|
LL | fn foo() {}
| ^^^^^^^^
help: use associated function syntax instead
|
LL - let f: fn() = self.foo;
LL + let f: fn() = S::foo;
|

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0599, E0609.
For more information about an error, try `rustc --explain E0599`.
10 changes: 6 additions & 4 deletions tests/ui/methods/issue-3707.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@ error[E0599]: no method named `boom` found for reference `&Obj` in the current s
--> $DIR/issue-3707.rs:10:14
|
LL | self.boom();
| -----^^^^--
| | |
| | this is an associated function, not a method
| help: use associated function syntax instead: `Obj::boom()`
| ^^^^ this is an associated function, not a method
|
= 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`
--> $DIR/issue-3707.rs:6:5
|
LL | pub fn boom() -> bool {
| ^^^^^^^^^^^^^^^^^^^^^
help: use associated function syntax instead
|
LL - self.boom();
LL + Obj::boom();
|

error: aborting due to 1 previous error

Expand Down
10 changes: 6 additions & 4 deletions tests/ui/suggestions/issue-102354.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@ error[E0599]: no method named `func` found for type `i32` in the current scope
--> $DIR/issue-102354.rs:9:7
|
LL | x.func();
| --^^^^--
| | |
| | this is an associated function, not a method
| help: use associated function syntax instead: `i32::func()`
| ^^^^ this is an associated function, not a method
|
= note: found the following associated functions; to be used as methods, functions must have a `self` parameter
note: the candidate is defined in the trait `Trait`
--> $DIR/issue-102354.rs:2:5
|
LL | fn func() {}
| ^^^^^^^^^
help: use associated function syntax instead
|
LL - x.func();
LL + i32::func();
|

error: aborting due to 1 previous error

Expand Down
10 changes: 6 additions & 4 deletions tests/ui/suggestions/issue-103646.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@ error[E0599]: no method named `nya` found for type parameter `T` in the current
LL | fn uwu<T: Cat>(c: T) {
| - method `nya` not found for this type parameter
LL | c.nya();
| --^^^--
| | |
| | this is an associated function, not a method
| help: use associated function syntax instead: `T::nya()`
| ^^^ this is an associated function, not a method
|
= note: found the following associated functions; to be used as methods, functions must have a `self` parameter
note: the candidate is defined in the trait `Cat`
--> $DIR/issue-103646.rs:2:5
|
LL | fn nya() {}
| ^^^^^^^^
help: use associated function syntax instead
|
LL - c.nya();
LL + T::nya();
|

error: aborting due to 1 previous error

Expand Down
10 changes: 6 additions & 4 deletions tests/ui/suggestions/suggest-assoc-fn-call-deref.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@ error[E0599]: no method named `test` found for struct `Box<Foo<i32>>` in the cur
--> $DIR/suggest-assoc-fn-call-deref.rs:13:7
|
LL | x.test();
| --^^^^--
| | |
| | this is an associated function, not a method
| help: use associated function syntax instead: `Foo::<i32>::test()`
| ^^^^ this is an associated function, not a method
|
= 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 `Foo<T>`
--> $DIR/suggest-assoc-fn-call-deref.rs:8:5
|
LL | fn test() -> i32 { 1 }
| ^^^^^^^^^^^^^^^^
help: use associated function syntax instead
|
LL - x.test();
LL + Foo::<i32>::test();
|

error: aborting due to 1 previous error

Expand Down
30 changes: 18 additions & 12 deletions tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@ LL | struct A {
| -------- method `foo` not found for this struct
...
LL | _a.foo();
| ---^^^--
| | |
| | this is an associated function, not a method
| help: use associated function syntax instead: `A::foo(_a)`
| ^^^ this is an associated function, not a method
|
= note: found the following associated functions; to be used as methods, functions must have a `self` parameter
note: the candidate is defined in the trait `M`
--> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:8:5
|
LL | fn foo(_a: Self);
| ^^^^^^^^^^^^^^^^^
help: use associated function syntax instead
|
LL - _a.foo();
LL + A::foo(_a);
|

error[E0599]: no method named `baz` found for struct `A` in the current scope
--> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:23:8
Expand All @@ -24,17 +26,19 @@ LL | struct A {
| -------- method `baz` not found for this struct
...
LL | _a.baz(0);
| ---^^^---
| | |
| | this is an associated function, not a method
| help: use associated function syntax instead: `A::baz(0)`
| ^^^ this is an associated function, not a method
|
= note: found the following associated functions; to be used as methods, functions must have a `self` parameter
note: the candidate is defined in the trait `M`
--> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:10:5
|
LL | fn baz(_a: i32);
| ^^^^^^^^^^^^^^^^
help: use associated function syntax instead
|
LL - _a.baz(0);
LL + A::baz(0);
|

error[E0599]: no method named `bar` found for struct `A` in the current scope
--> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:27:8
Expand All @@ -43,17 +47,19 @@ LL | struct A {
| -------- method `bar` not found for this struct
...
LL | _b.bar();
| ---^^^--
| | |
| | this is an associated function, not a method
| help: use associated function syntax instead: `A::bar(_b)`
| ^^^ this is an associated function, not a method
|
= note: found the following associated functions; to be used as methods, functions must have a `self` parameter
note: the candidate is defined in the trait `M`
--> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:9:5
|
LL | fn bar(_a: Self);
| ^^^^^^^^^^^^^^^^^
help: use associated function syntax instead
|
LL - _b.bar();
LL + A::bar(_b);
|

error: aborting due to 3 previous errors

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@ LL | struct GenericAssocMethod<T>(T);
| ---------------------------- method `default_hello` not found for this struct
...
LL | x.default_hello();
| --^^^^^^^^^^^^^--
| | |
| | this is an associated function, not a method
| help: use associated function syntax instead: `GenericAssocMethod::<_>::default_hello()`
| ^^^^^^^^^^^^^ this is an associated function, not a method
|
= 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<T>`
--> $DIR/suggest-assoc-fn-call-with-turbofish-placeholder.rs:4:5
|
LL | fn default_hello() {}
| ^^^^^^^^^^^^^^^^^^
help: use associated function syntax instead
|
LL - x.default_hello();
LL + GenericAssocMethod::<_>::default_hello();
|

error: aborting due to 1 previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@ error[E0599]: no method named `hello` found for struct `RefMut<'_, HasAssocMetho
--> $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()`
| ^^^^^ this is an associated function, not a method
|
= 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() {}
| ^^^^^^^^^^
help: use associated function syntax instead
|
LL - state.hello();
LL + HasAssocMethod::hello();
|

error: aborting due to 1 previous error

Expand Down
Loading
Loading