@@ -1358,94 +1358,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1358
1358
// ...or if we already suggested that name because of `rustc_confusable` annotation.
1359
1359
&& Some ( similar_candidate. name ) != confusable_suggested
1360
1360
{
1361
- let def_kind = similar_candidate. kind . as_def_kind ( ) ;
1362
- let an = self . tcx . def_kind_descr_article ( def_kind, similar_candidate. def_id ) ;
1363
- // Methods are defined within the context of a struct and their first parameter
1364
- // is always `self`, which represents the instance of the struct the method is
1365
- // being called on Associated functions don’t take self as a parameter and they are
1366
- // not methods because they don’t have an instance of the struct to work with.
1367
- if def_kind == DefKind :: AssocFn {
1368
- let ty_args = self . infcx . fresh_args_for_item ( span, similar_candidate. def_id ) ;
1369
- let fn_sig = tcx. fn_sig ( similar_candidate. def_id ) . instantiate ( tcx, ty_args) ;
1370
- let fn_sig =
1371
- self . instantiate_binder_with_fresh_vars ( span, infer:: FnCall , fn_sig) ;
1372
- if similar_candidate. fn_has_self_parameter {
1373
- if let Some ( args) = args
1374
- && fn_sig. inputs ( ) [ 1 ..] . len ( ) == args. len ( )
1375
- {
1376
- // We found a method with the same number of arguments as the method
1377
- // call expression the user wrote.
1378
- err. span_suggestion_verbose (
1379
- span,
1380
- format ! ( "there is {an} method with a similar name" ) ,
1381
- similar_candidate. name ,
1382
- Applicability :: MaybeIncorrect ,
1383
- ) ;
1384
- } else {
1385
- // We found a method but either the expression is not a method call or
1386
- // the argument count didn't match.
1387
- err. span_help (
1388
- tcx. def_span ( similar_candidate. def_id ) ,
1389
- format ! (
1390
- "there is {an} method `{}` with a similar name{}" ,
1391
- similar_candidate. name,
1392
- if let None = args {
1393
- ""
1394
- } else {
1395
- ", but with different arguments"
1396
- } ,
1397
- ) ,
1398
- ) ;
1399
- }
1400
- } else if let Some ( args) = args
1401
- && fn_sig. inputs ( ) . len ( ) == args. len ( )
1402
- {
1403
- // We have fn call expression and the argument count match the associated
1404
- // function we found.
1405
- err. span_suggestion_verbose (
1406
- span,
1407
- format ! (
1408
- "there is {an} {} with a similar name" ,
1409
- self . tcx. def_kind_descr( def_kind, similar_candidate. def_id)
1410
- ) ,
1411
- similar_candidate. name ,
1412
- Applicability :: MaybeIncorrect ,
1413
- ) ;
1414
- } else {
1415
- err. span_help (
1416
- tcx. def_span ( similar_candidate. def_id ) ,
1417
- format ! (
1418
- "there is {an} {} `{}` with a similar name" ,
1419
- self . tcx. def_kind_descr( def_kind, similar_candidate. def_id) ,
1420
- similar_candidate. name,
1421
- ) ,
1422
- ) ;
1423
- }
1424
- } else if let Mode :: Path = mode
1425
- && args. unwrap_or ( & [ ] ) . is_empty ( )
1426
- {
1427
- // We have an associated item syntax and we found something that isn't an fn.
1428
- err. span_suggestion_verbose (
1429
- span,
1430
- format ! (
1431
- "there is {an} {} with a similar name" ,
1432
- self . tcx. def_kind_descr( def_kind, similar_candidate. def_id)
1433
- ) ,
1434
- similar_candidate. name ,
1435
- Applicability :: MaybeIncorrect ,
1436
- ) ;
1437
- } else {
1438
- // The expression is a function or method call, but the item we found is an
1439
- // associated const or type.
1440
- err. span_help (
1441
- tcx. def_span ( similar_candidate. def_id ) ,
1442
- format ! (
1443
- "there is {an} {} `{}` with a similar name" ,
1444
- self . tcx. def_kind_descr( def_kind, similar_candidate. def_id) ,
1445
- similar_candidate. name,
1446
- ) ,
1447
- ) ;
1448
- }
1361
+ self . find_likely_intended_associated_item (
1362
+ & mut err,
1363
+ similar_candidate,
1364
+ span,
1365
+ args,
1366
+ mode,
1367
+ ) ;
1449
1368
}
1450
1369
}
1451
1370
// If an appropriate error source is not found, check method chain for possible candiates
@@ -1497,6 +1416,100 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1497
1416
Some ( err)
1498
1417
}
1499
1418
1419
+ fn find_likely_intended_associated_item (
1420
+ & self ,
1421
+ err : & mut Diagnostic ,
1422
+ similar_candidate : ty:: AssocItem ,
1423
+ span : Span ,
1424
+ args : Option < & ' tcx [ hir:: Expr < ' tcx > ] > ,
1425
+ mode : Mode ,
1426
+ ) {
1427
+ let tcx = self . tcx ;
1428
+ let def_kind = similar_candidate. kind . as_def_kind ( ) ;
1429
+ let an = self . tcx . def_kind_descr_article ( def_kind, similar_candidate. def_id ) ;
1430
+ // Methods are defined within the context of a struct and their first parameter
1431
+ // is always `self`, which represents the instance of the struct the method is
1432
+ // being called on Associated functions don’t take self as a parameter and they are
1433
+ // not methods because they don’t have an instance of the struct to work with.
1434
+ if def_kind == DefKind :: AssocFn {
1435
+ let ty_args = self . infcx . fresh_args_for_item ( span, similar_candidate. def_id ) ;
1436
+ let fn_sig = tcx. fn_sig ( similar_candidate. def_id ) . instantiate ( tcx, ty_args) ;
1437
+ let fn_sig = self . instantiate_binder_with_fresh_vars ( span, infer:: FnCall , fn_sig) ;
1438
+ if similar_candidate. fn_has_self_parameter {
1439
+ if let Some ( args) = args
1440
+ && fn_sig. inputs ( ) [ 1 ..] . len ( ) == args. len ( )
1441
+ {
1442
+ // We found a method with the same number of arguments as the method
1443
+ // call expression the user wrote.
1444
+ err. span_suggestion_verbose (
1445
+ span,
1446
+ format ! ( "there is {an} method with a similar name" ) ,
1447
+ similar_candidate. name ,
1448
+ Applicability :: MaybeIncorrect ,
1449
+ ) ;
1450
+ } else {
1451
+ // We found a method but either the expression is not a method call or
1452
+ // the argument count didn't match.
1453
+ err. span_help (
1454
+ tcx. def_span ( similar_candidate. def_id ) ,
1455
+ format ! (
1456
+ "there is {an} method `{}` with a similar name{}" ,
1457
+ similar_candidate. name,
1458
+ if let None = args { "" } else { ", but with different arguments" } ,
1459
+ ) ,
1460
+ ) ;
1461
+ }
1462
+ } else if let Some ( args) = args
1463
+ && fn_sig. inputs ( ) . len ( ) == args. len ( )
1464
+ {
1465
+ // We have fn call expression and the argument count match the associated
1466
+ // function we found.
1467
+ err. span_suggestion_verbose (
1468
+ span,
1469
+ format ! (
1470
+ "there is {an} {} with a similar name" ,
1471
+ self . tcx. def_kind_descr( def_kind, similar_candidate. def_id)
1472
+ ) ,
1473
+ similar_candidate. name ,
1474
+ Applicability :: MaybeIncorrect ,
1475
+ ) ;
1476
+ } else {
1477
+ err. span_help (
1478
+ tcx. def_span ( similar_candidate. def_id ) ,
1479
+ format ! (
1480
+ "there is {an} {} `{}` with a similar name" ,
1481
+ self . tcx. def_kind_descr( def_kind, similar_candidate. def_id) ,
1482
+ similar_candidate. name,
1483
+ ) ,
1484
+ ) ;
1485
+ }
1486
+ } else if let Mode :: Path = mode
1487
+ && args. unwrap_or ( & [ ] ) . is_empty ( )
1488
+ {
1489
+ // We have an associated item syntax and we found something that isn't an fn.
1490
+ err. span_suggestion_verbose (
1491
+ span,
1492
+ format ! (
1493
+ "there is {an} {} with a similar name" ,
1494
+ self . tcx. def_kind_descr( def_kind, similar_candidate. def_id)
1495
+ ) ,
1496
+ similar_candidate. name ,
1497
+ Applicability :: MaybeIncorrect ,
1498
+ ) ;
1499
+ } else {
1500
+ // The expression is a function or method call, but the item we found is an
1501
+ // associated const or type.
1502
+ err. span_help (
1503
+ tcx. def_span ( similar_candidate. def_id ) ,
1504
+ format ! (
1505
+ "there is {an} {} `{}` with a similar name" ,
1506
+ self . tcx. def_kind_descr( def_kind, similar_candidate. def_id) ,
1507
+ similar_candidate. name,
1508
+ ) ,
1509
+ ) ;
1510
+ }
1511
+ }
1512
+
1500
1513
pub ( crate ) fn confusable_method_name (
1501
1514
& self ,
1502
1515
err : & mut Diagnostic ,
0 commit comments