diff options
| author | Young-Flash <871946895@qq.com> | 2023-12-27 15:47:57 +0800 |
|---|---|---|
| committer | Young-Flash <871946895@qq.com> | 2023-12-27 15:47:57 +0800 |
| commit | 9e9353c0da58315b6acc13891ca412ed6acfb513 (patch) | |
| tree | 366dead3cecd6addb4ca1850236516ec3717f5c6 | |
| parent | ffd619a69521b034ea9d37f5f128055dbea35671 (diff) | |
| download | rust-9e9353c0da58315b6acc13891ca412ed6acfb513.tar.gz rust-9e9353c0da58315b6acc13891ca412ed6acfb513.zip | |
fix broken CI and code review
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 |
