From 6c6a2c1ef75aaa2fd3b813e3a12dd7908bdd94b1 Mon Sep 17 00:00:00 2001 From: Young-Flash <871946895@qq.com> Date: Wed, 13 Dec 2023 19:57:42 +0800 Subject: [PATCH] fix: correct the args for `disambiguate the associated function` diagnostic --- .../rustc_hir_typeck/src/method/suggest.rs | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 8fb703fa7f5..503fb13664a 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -3312,6 +3312,7 @@ fn print_disambiguation_help<'tcx>( span: Span, item: ty::AssocItem, ) -> Option { + let trait_impl_type = trait_ref.self_ty(); let trait_ref = if item.fn_has_self_parameter { trait_ref.print_only_trait_name().to_string() } else { @@ -3324,6 +3325,13 @@ 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() @@ -3332,19 +3340,22 @@ fn print_disambiguation_help<'tcx>( .get(0) .and_then(|ty| ty.ref_mutability()) .map_or("", |mutbl| mutbl.ref_prefix_str()); - let args = format!( - "({}{})", - rcvr_ref, - std::iter::once(receiver) - .chain(args.iter()) - .map(|arg| tcx - .sess - .source_map() - .span_to_snippet(arg.span) - .unwrap_or_else(|_| { "_".to_owned() })) - .collect::>() - .join(", "), - ); + // 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) + { + std::iter::once(receiver).chain(args.iter()).collect::>() + } else { + args.iter().collect::>() + } + .iter() + .map(|arg| { + tcx.sess.source_map().span_to_snippet(arg.span).unwrap_or_else(|_| "_".to_owned()) + }) + .collect::>() + .join(", "); + + let args = format!("({}{})", rcvr_ref, args); err.span_suggestion_verbose( span, format!(