@@ -1260,6 +1260,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1260
1260
// Dynamic limit to avoid hiding just one candidate, which is silly.
1261
1261
let limit = if sources. len ( ) == 5 { 5 } else { 4 } ;
1262
1262
1263
+ let mut suggs = vec ! [ ] ;
1263
1264
for ( idx, source) in sources. iter ( ) . take ( limit) . enumerate ( ) {
1264
1265
match * source {
1265
1266
CandidateSource :: Impl ( impl_did) => {
@@ -1334,7 +1335,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1334
1335
. copied ( )
1335
1336
. unwrap_or ( rcvr_ty) ,
1336
1337
} ;
1337
- print_disambiguation_help (
1338
+ if let Some ( sugg ) = print_disambiguation_help (
1338
1339
item_name,
1339
1340
args,
1340
1341
err,
@@ -1347,7 +1348,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1347
1348
idx,
1348
1349
self . tcx . sess . source_map ( ) ,
1349
1350
item. fn_has_self_parameter ,
1350
- ) ;
1351
+ ) {
1352
+ suggs. push ( sugg) ;
1353
+ }
1351
1354
}
1352
1355
}
1353
1356
CandidateSource :: Trait ( trait_did) => {
@@ -1371,7 +1374,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1371
1374
} ;
1372
1375
if let Some ( sugg_span) = sugg_span {
1373
1376
let path = self . tcx . def_path_str ( trait_did) ;
1374
- print_disambiguation_help (
1377
+ if let Some ( sugg ) = print_disambiguation_help (
1375
1378
item_name,
1376
1379
args,
1377
1380
err,
@@ -1384,11 +1387,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1384
1387
idx,
1385
1388
self . tcx . sess . source_map ( ) ,
1386
1389
item. fn_has_self_parameter ,
1387
- ) ;
1390
+ ) {
1391
+ suggs. push ( sugg) ;
1392
+ }
1388
1393
}
1389
1394
}
1390
1395
}
1391
1396
}
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
+ }
1392
1405
if sources. len ( ) > limit {
1393
1406
err. note ( format ! ( "and {} others" , sources. len( ) - limit) ) ;
1394
1407
}
@@ -3155,47 +3168,44 @@ fn print_disambiguation_help<'tcx>(
3155
3168
candidate : Option < usize > ,
3156
3169
source_map : & source_map:: SourceMap ,
3157
3170
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 {
3178
3187
format ! ( "<{impl_self_ty} as {trait_name}>" )
3179
3188
} else {
3180
3189
trait_name
3181
3190
} ;
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
+ )
3201
3211
}
0 commit comments