From e4cfe038adffb0cf5785d7c95f809364c6a39f5f Mon Sep 17 00:00:00 2001 From: Young-Flash <871946895@qq.com> Date: Fri, 1 Dec 2023 22:17:31 +0800 Subject: [PATCH] fix: correct the arg for 'suggest to use associated function syntax' diagnostic --- .../rustc_hir_typeck/src/method/suggest.rs | 8 ++-- ...ggest-assoc-fn-call-without-receiver.fixed | 16 ++++++++ .../suggest-assoc-fn-call-without-receiver.rs | 16 ++++++++ ...gest-assoc-fn-call-without-receiver.stderr | 41 +++++++++++++++++++ 4 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.fixed create mode 100644 tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.rs create mode 100644 tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.stderr diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index a7764f4ff96..117b60cf42e 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1591,10 +1591,12 @@ fn suggest_associated_call_syntax( { let sig = self.tcx.fn_sig(assoc.def_id).instantiate_identity(); sig.inputs().skip_binder().get(0).and_then(|first| { - if first.peel_refs() == rcvr_ty.peel_refs() { - None - } else { + let impl_ty = self.tcx.type_of(*impl_did).instantiate_identity(); + // if the type of first arg is the same as the current impl type, we should take the first arg into assoc function + if first.peel_refs() == impl_ty { Some(first.ref_mutability().map_or("", |mutbl| mutbl.ref_prefix_str())) + } else { + None } }) } else { diff --git a/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.fixed b/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.fixed new file mode 100644 index 00000000000..6e679134d63 --- /dev/null +++ b/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.fixed @@ -0,0 +1,16 @@ +// run-rustfix + +struct A {} + +impl A { + fn hello(_a: i32) {} + fn test(_a: Self, _b: i32) {} +} + +fn main() { + let _a = A {}; + A::hello(1); + //~^ ERROR no method named `hello` found + A::test(_a, 1); + //~^ ERROR no method named `test` found +} diff --git a/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.rs b/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.rs new file mode 100644 index 00000000000..67c2cc1bed5 --- /dev/null +++ b/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.rs @@ -0,0 +1,16 @@ +// run-rustfix + +struct A {} + +impl A { + fn hello(_a: i32) {} + fn test(_a: Self, _b: i32) {} +} + +fn main() { + let _a = A {}; + _a.hello(1); + //~^ ERROR no method named `hello` found + _a.test(1); + //~^ ERROR no method named `test` found +} diff --git a/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.stderr b/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.stderr new file mode 100644 index 00000000000..ed227cbab39 --- /dev/null +++ b/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.stderr @@ -0,0 +1,41 @@ +error[E0599]: no method named `hello` found for struct `A` in the current scope + --> $DIR/suggest-assoc-fn-call-without-receiver.rs:12:8 + | +LL | struct A {} + | -------- method `hello` not found for this struct +... +LL | _a.hello(1); + | ---^^^^^--- + | | | + | | this is an associated function, not a method + | help: use associated function syntax instead: `A::hello(1)` + | + = 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 `A` + --> $DIR/suggest-assoc-fn-call-without-receiver.rs:6:5 + | +LL | fn hello(_a: i32) {} + | ^^^^^^^^^^^^^^^^^ + +error[E0599]: no method named `test` found for struct `A` in the current scope + --> $DIR/suggest-assoc-fn-call-without-receiver.rs:14:8 + | +LL | struct A {} + | -------- method `test` not found for this struct +... +LL | _a.test(1); + | ---^^^^--- + | | | + | | this is an associated function, not a method + | help: use associated function syntax instead: `A::test(_a, 1)` + | + = 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 `A` + --> $DIR/suggest-assoc-fn-call-without-receiver.rs:7:5 + | +LL | fn test(_a: Self, _b: i32) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0599`.