about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYoung-Flash <871946895@qq.com>2023-12-27 15:47:57 +0800
committerYoung-Flash <871946895@qq.com>2023-12-27 15:47:57 +0800
commit9e9353c0da58315b6acc13891ca412ed6acfb513 (patch)
tree366dead3cecd6addb4ca1850236516ec3717f5c6
parentffd619a69521b034ea9d37f5f128055dbea35671 (diff)
downloadrust-9e9353c0da58315b6acc13891ca412ed6acfb513.tar.gz
rust-9e9353c0da58315b6acc13891ca412ed6acfb513.zip
fix broken CI and code review
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs41
-rw-r--r--tests/ui/methods/disambiguate-associated-function-first-arg.rs21
-rw-r--r--tests/ui/methods/disambiguate-associated-function-first-arg.stderr30
-rw-r--r--tests/ui/methods/method-ambiguity-no-rcvr.stderr8
4 files changed, 72 insertions, 28 deletions
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 503fb13664a..c355e78ecba 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -3312,7 +3312,7 @@ fn print_disambiguation_help<'tcx>(
     span: Span,
     item: ty::AssocItem,
 ) -> Option<String> {
-    let trait_impl_type = trait_ref.self_ty();
+    let trait_impl_type = trait_ref.self_ty().peel_refs();
     let trait_ref = if item.fn_has_self_parameter {
         trait_ref.print_only_trait_name().to_string()
     } else {
@@ -3325,30 +3325,27 @@ fn print_disambiguation_help<'tcx>(
         {
             let def_kind_descr = tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id);
             let item_name = item.ident(tcx);
-            let first_arg_type = tcx
-                .fn_sig(item.def_id)
-                .instantiate_identity()
-                .skip_binder()
-                .inputs()
-                .get(0)
-                .and_then(|first| Some(first.peel_refs()));
-            let rcvr_ref = tcx
-                .fn_sig(item.def_id)
-                .skip_binder()
-                .skip_binder()
-                .inputs()
-                .get(0)
-                .and_then(|ty| ty.ref_mutability())
-                .map_or("", |mutbl| mutbl.ref_prefix_str());
-            // If the type of first arg of this assoc function is `Self` or current trait impl type, we need to take the receiver as args. Otherwise, we don't.
-            let args = if let Some(t) = first_arg_type
-                && (t.to_string() == "Self" || t == trait_impl_type)
+            let first_input =
+                tcx.fn_sig(item.def_id).instantiate_identity().skip_binder().inputs().get(0);
+            let (first_arg_type, rcvr_ref) = (
+                first_input.map(|first| first.peel_refs()),
+                first_input
+                    .and_then(|ty| ty.ref_mutability())
+                    .map_or("", |mutbl| mutbl.ref_prefix_str()),
+            );
+
+            // If the type of first arg of this assoc function is `Self` or current trait impl type or `arbitrary_self_types`, we need to take the receiver as args. Otherwise, we don't.
+            let args = if let Some(first_arg_type) = first_arg_type
+                && (first_arg_type == tcx.types.self_param
+                    || first_arg_type == trait_impl_type
+                    || item.fn_has_self_parameter)
             {
-                std::iter::once(receiver).chain(args.iter()).collect::<Vec<_>>()
+                Some(receiver)
             } else {
-                args.iter().collect::<Vec<_>>()
+                None
             }
-            .iter()
+            .into_iter()
+            .chain(args)
             .map(|arg| {
                 tcx.sess.source_map().span_to_snippet(arg.span).unwrap_or_else(|_| "_".to_owned())
             })
diff --git a/tests/ui/methods/disambiguate-associated-function-first-arg.rs b/tests/ui/methods/disambiguate-associated-function-first-arg.rs
index 1f8aa07b685..4c8192fc14b 100644
--- a/tests/ui/methods/disambiguate-associated-function-first-arg.rs
+++ b/tests/ui/methods/disambiguate-associated-function-first-arg.rs
@@ -26,3 +26,24 @@ trait O {
 impl O for A {
     fn new(_a: A, _b: i32) {}
 }
+
+struct S;
+
+trait TraitA {
+    fn f(self);
+}
+trait TraitB {
+    fn f(self);
+}
+
+impl<T> TraitA for T {
+    fn f(self) {}
+}
+impl<T> TraitB for T {
+    fn f(self) {}
+}
+
+fn test() {
+    S.f();
+   //~^ multiple applicable items in scope
+}
diff --git a/tests/ui/methods/disambiguate-associated-function-first-arg.stderr b/tests/ui/methods/disambiguate-associated-function-first-arg.stderr
index b66ee7b8f4d..341b7a91003 100644
--- a/tests/ui/methods/disambiguate-associated-function-first-arg.stderr
+++ b/tests/ui/methods/disambiguate-associated-function-first-arg.stderr
@@ -36,6 +36,32 @@ help: disambiguate the associated function for candidate #3
 LL |     <A as O>::new(_a, 1);
    |     ~~~~~~~~~~~~~~~~~~~~
 
-error: aborting due to 1 previous error
+error[E0034]: multiple applicable items in scope
+  --> $DIR/disambiguate-associated-function-first-arg.rs:47:7
+   |
+LL |     S.f();
+   |       ^ multiple `f` found
+   |
+note: candidate #1 is defined in an impl of the trait `TraitA` for the type `T`
+  --> $DIR/disambiguate-associated-function-first-arg.rs:40:5
+   |
+LL |     fn f(self) {}
+   |     ^^^^^^^^^^
+note: candidate #2 is defined in an impl of the trait `TraitB` for the type `T`
+  --> $DIR/disambiguate-associated-function-first-arg.rs:43:5
+   |
+LL |     fn f(self) {}
+   |     ^^^^^^^^^^
+help: disambiguate the method for candidate #1
+   |
+LL |     TraitA::f(S);
+   |     ~~~~~~~~~~~~
+help: disambiguate the method for candidate #2
+   |
+LL |     TraitB::f(S);
+   |     ~~~~~~~~~~~~
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0599`.
+Some errors have detailed explanations: E0034, E0599.
+For more information about an error, try `rustc --explain E0034`.
diff --git a/tests/ui/methods/method-ambiguity-no-rcvr.stderr b/tests/ui/methods/method-ambiguity-no-rcvr.stderr
index 73f6043f256..3b6eb07393a 100644
--- a/tests/ui/methods/method-ambiguity-no-rcvr.stderr
+++ b/tests/ui/methods/method-ambiguity-no-rcvr.stderr
@@ -20,12 +20,12 @@ LL |     fn foo() {}
    |     ^^^^^^^^
 help: disambiguate the associated function for candidate #1
    |
-LL |     <Qux as Foo>::foo(Qux);
-   |     ~~~~~~~~~~~~~~~~~~~~~~
+LL |     <Qux as Foo>::foo();
+   |     ~~~~~~~~~~~~~~~~~~~
 help: disambiguate the associated function for candidate #2
    |
-LL |     <Qux as FooBar>::foo(Qux);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |     <Qux as FooBar>::foo();
+   |     ~~~~~~~~~~~~~~~~~~~~~~
 
 error: aborting due to 1 previous error