@@ -1260,6 +1260,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12601260 // Dynamic limit to avoid hiding just one candidate, which is silly.
12611261 let limit = if sources. len ( ) == 5 { 5 } else { 4 } ;
12621262
1263+ let mut suggs = vec ! [ ] ;
12631264 for ( idx, source) in sources. iter ( ) . take ( limit) . enumerate ( ) {
12641265 match * source {
12651266 CandidateSource :: Impl ( impl_did) => {
@@ -1334,7 +1335,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13341335 . copied ( )
13351336 . unwrap_or ( rcvr_ty) ,
13361337 } ;
1337- print_disambiguation_help (
1338+ if let Some ( sugg ) = print_disambiguation_help (
13381339 item_name,
13391340 args,
13401341 err,
@@ -1347,7 +1348,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13471348 idx,
13481349 self . tcx . sess . source_map ( ) ,
13491350 item. fn_has_self_parameter ,
1350- ) ;
1351+ ) {
1352+ suggs. push ( sugg) ;
1353+ }
13511354 }
13521355 }
13531356 CandidateSource :: Trait ( trait_did) => {
@@ -1371,7 +1374,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13711374 } ;
13721375 if let Some ( sugg_span) = sugg_span {
13731376 let path = self . tcx . def_path_str ( trait_did) ;
1374- print_disambiguation_help (
1377+ if let Some ( sugg ) = print_disambiguation_help (
13751378 item_name,
13761379 args,
13771380 err,
@@ -1384,11 +1387,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13841387 idx,
13851388 self . tcx . sess . source_map ( ) ,
13861389 item. fn_has_self_parameter ,
1387- ) ;
1390+ ) {
1391+ suggs. push ( sugg) ;
1392+ }
13881393 }
13891394 }
13901395 }
13911396 }
1397+ if !suggs. is_empty ( ) && let Some ( span) = sugg_span {
1398+ err. span_suggestions (
1399+ span. with_hi ( item_name. span . lo ( ) ) ,
1400+ "use fully-qualified syntax to disambiguate" ,
1401+ suggs,
1402+ Applicability :: MachineApplicable ,
1403+ ) ;
1404+ }
13921405 if sources. len ( ) > limit {
13931406 err. note ( format ! ( "and {} others" , sources. len( ) - limit) ) ;
13941407 }
@@ -3155,47 +3168,44 @@ fn print_disambiguation_help<'tcx>(
31553168 candidate : Option < usize > ,
31563169 source_map : & source_map:: SourceMap ,
31573170 fn_has_self_parameter : bool ,
3158- ) {
3159- let mut applicability = Applicability :: MachineApplicable ;
3160- let ( span, sugg) = if let (
3161- ty:: AssocKind :: Fn ,
3162- Some ( MethodCallComponents { receiver, args, .. } ) ,
3163- ) = ( kind, args)
3164- {
3165- let args = format ! (
3166- "({}{})" ,
3167- rcvr_ty. ref_mutability( ) . map_or( "" , |mutbl| mutbl. ref_prefix_str( ) ) ,
3168- std:: iter:: once( receiver)
3169- . chain( args. iter( ) )
3170- . map( |arg| source_map. span_to_snippet( arg. span) . unwrap_or_else( |_| {
3171- applicability = Applicability :: HasPlaceholders ;
3172- "_" . to_owned( )
3173- } ) )
3174- . collect:: <Vec <_>>( )
3175- . join( ", " ) ,
3176- ) ;
3177- let trait_name = if !fn_has_self_parameter && let Some ( impl_self_ty) = impl_self_ty {
3171+ ) -> Option < String > {
3172+ Some (
3173+ if let ( ty:: AssocKind :: Fn , Some ( MethodCallComponents { receiver, args, .. } ) ) = ( kind, args)
3174+ {
3175+ let args = format ! (
3176+ "({}{})" ,
3177+ rcvr_ty. ref_mutability( ) . map_or( "" , |mutbl| mutbl. ref_prefix_str( ) ) ,
3178+ std:: iter:: once( receiver)
3179+ . chain( args. iter( ) )
3180+ . map( |arg| source_map
3181+ . span_to_snippet( arg. span)
3182+ . unwrap_or_else( |_| { "_" . to_owned( ) } ) )
3183+ . collect:: <Vec <_>>( )
3184+ . join( ", " ) ,
3185+ ) ;
3186+ let trait_name = if !fn_has_self_parameter && let Some ( impl_self_ty) = impl_self_ty {
31783187 format ! ( "<{impl_self_ty} as {trait_name}>" )
31793188 } else {
31803189 trait_name
31813190 } ;
3182- ( span, format ! ( "{trait_name}::{item_name}{args}" ) )
3183- } else if let Some ( impl_self_ty) = impl_self_ty {
3184- ( span. with_hi ( item_name. span . lo ( ) ) , format ! ( "<{impl_self_ty} as {trait_name}>::" ) )
3185- } else {
3186- ( span. with_hi ( item_name. span . lo ( ) ) , format ! ( "{trait_name}::" ) )
3187- } ;
3188- err. span_suggestion_verbose (
3189- span,
3190- format ! (
3191- "disambiguate the {def_kind_descr} for {}" ,
3192- if let Some ( candidate) = candidate {
3193- format!( "candidate #{candidate}" )
3194- } else {
3195- "the candidate" . to_string( )
3196- } ,
3197- ) ,
3198- sugg,
3199- applicability,
3200- ) ;
3191+ err. span_suggestion_verbose (
3192+ span,
3193+ format ! (
3194+ "disambiguate the {def_kind_descr} for {}" ,
3195+ if let Some ( candidate) = candidate {
3196+ format!( "candidate #{candidate}" )
3197+ } else {
3198+ "the candidate" . to_string( )
3199+ } ,
3200+ ) ,
3201+ format ! ( "{trait_name}::{item_name}{args}" ) ,
3202+ Applicability :: HasPlaceholders ,
3203+ ) ;
3204+ return None ;
3205+ } else if let Some ( impl_self_ty) = impl_self_ty {
3206+ format ! ( "<{impl_self_ty} as {trait_name}>::" )
3207+ } else {
3208+ format ! ( "{trait_name}::" )
3209+ } ,
3210+ )
32013211}
0 commit comments