@@ -1256,94 +1256,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1256
1256
// ...or if we already suggested that name because of `rustc_confusable` annotation.
1257
1257
&& Some ( similar_candidate. name ) != confusable_suggested
1258
1258
{
1259
- let def_kind = similar_candidate. kind . as_def_kind ( ) ;
1260
- let an = self . tcx . def_kind_descr_article ( def_kind, similar_candidate. def_id ) ;
1261
- // Methods are defined within the context of a struct and their first parameter
1262
- // is always `self`, which represents the instance of the struct the method is
1263
- // being called on Associated functions don’t take self as a parameter and they are
1264
- // not methods because they don’t have an instance of the struct to work with.
1265
- if def_kind == DefKind :: AssocFn {
1266
- let ty_args = self . infcx . fresh_args_for_item ( span, similar_candidate. def_id ) ;
1267
- let fn_sig = tcx. fn_sig ( similar_candidate. def_id ) . instantiate ( tcx, ty_args) ;
1268
- let fn_sig =
1269
- self . instantiate_binder_with_fresh_vars ( span, infer:: FnCall , fn_sig) ;
1270
- if similar_candidate. fn_has_self_parameter {
1271
- if let Some ( args) = args
1272
- && fn_sig. inputs ( ) [ 1 ..] . len ( ) == args. len ( )
1273
- {
1274
- // We found a method with the same number of arguments as the method
1275
- // call expression the user wrote.
1276
- err. span_suggestion_verbose (
1277
- span,
1278
- format ! ( "there is {an} method with a similar name" ) ,
1279
- similar_candidate. name ,
1280
- Applicability :: MaybeIncorrect ,
1281
- ) ;
1282
- } else {
1283
- // We found a method but either the expression is not a method call or
1284
- // the argument count didn't match.
1285
- err. span_help (
1286
- tcx. def_span ( similar_candidate. def_id ) ,
1287
- format ! (
1288
- "there is {an} method `{}` with a similar name{}" ,
1289
- similar_candidate. name,
1290
- if let None = args {
1291
- ""
1292
- } else {
1293
- ", but with different arguments"
1294
- } ,
1295
- ) ,
1296
- ) ;
1297
- }
1298
- } else if let Some ( args) = args
1299
- && fn_sig. inputs ( ) . len ( ) == args. len ( )
1300
- {
1301
- // We have fn call expression and the argument count match the associated
1302
- // function we found.
1303
- err. span_suggestion_verbose (
1304
- span,
1305
- format ! (
1306
- "there is {an} {} with a similar name" ,
1307
- self . tcx. def_kind_descr( def_kind, similar_candidate. def_id)
1308
- ) ,
1309
- similar_candidate. name ,
1310
- Applicability :: MaybeIncorrect ,
1311
- ) ;
1312
- } else {
1313
- err. span_help (
1314
- tcx. def_span ( similar_candidate. def_id ) ,
1315
- format ! (
1316
- "there is {an} {} `{}` with a similar name" ,
1317
- self . tcx. def_kind_descr( def_kind, similar_candidate. def_id) ,
1318
- similar_candidate. name,
1319
- ) ,
1320
- ) ;
1321
- }
1322
- } else if let Mode :: Path = mode
1323
- && args. unwrap_or ( & [ ] ) . is_empty ( )
1324
- {
1325
- // We have an associated item syntax and we found something that isn't an fn.
1326
- err. span_suggestion_verbose (
1327
- span,
1328
- format ! (
1329
- "there is {an} {} with a similar name" ,
1330
- self . tcx. def_kind_descr( def_kind, similar_candidate. def_id)
1331
- ) ,
1332
- similar_candidate. name ,
1333
- Applicability :: MaybeIncorrect ,
1334
- ) ;
1335
- } else {
1336
- // The expression is a function or method call, but the item we found is an
1337
- // associated const or type.
1338
- err. span_help (
1339
- tcx. def_span ( similar_candidate. def_id ) ,
1340
- format ! (
1341
- "there is {an} {} `{}` with a similar name" ,
1342
- self . tcx. def_kind_descr( def_kind, similar_candidate. def_id) ,
1343
- similar_candidate. name,
1344
- ) ,
1345
- ) ;
1346
- }
1259
+ self . find_likely_intended_associated_item (
1260
+ & mut err,
1261
+ similar_candidate,
1262
+ span,
1263
+ args,
1264
+ mode,
1265
+ ) ;
1347
1266
}
1348
1267
}
1349
1268
// If an appropriate error source is not found, check method chain for possible candiates
@@ -1395,6 +1314,100 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1395
1314
Some ( err)
1396
1315
}
1397
1316
1317
+ fn find_likely_intended_associated_item (
1318
+ & self ,
1319
+ err : & mut Diagnostic ,
1320
+ similar_candidate : ty:: AssocItem ,
1321
+ span : Span ,
1322
+ args : Option < & ' tcx [ hir:: Expr < ' tcx > ] > ,
1323
+ mode : Mode ,
1324
+ ) {
1325
+ let tcx = self . tcx ;
1326
+ let def_kind = similar_candidate. kind . as_def_kind ( ) ;
1327
+ let an = self . tcx . def_kind_descr_article ( def_kind, similar_candidate. def_id ) ;
1328
+ // Methods are defined within the context of a struct and their first parameter
1329
+ // is always `self`, which represents the instance of the struct the method is
1330
+ // being called on Associated functions don’t take self as a parameter and they are
1331
+ // not methods because they don’t have an instance of the struct to work with.
1332
+ if def_kind == DefKind :: AssocFn {
1333
+ let ty_args = self . infcx . fresh_args_for_item ( span, similar_candidate. def_id ) ;
1334
+ let fn_sig = tcx. fn_sig ( similar_candidate. def_id ) . instantiate ( tcx, ty_args) ;
1335
+ let fn_sig = self . instantiate_binder_with_fresh_vars ( span, infer:: FnCall , fn_sig) ;
1336
+ if similar_candidate. fn_has_self_parameter {
1337
+ if let Some ( args) = args
1338
+ && fn_sig. inputs ( ) [ 1 ..] . len ( ) == args. len ( )
1339
+ {
1340
+ // We found a method with the same number of arguments as the method
1341
+ // call expression the user wrote.
1342
+ err. span_suggestion_verbose (
1343
+ span,
1344
+ format ! ( "there is {an} method with a similar name" ) ,
1345
+ similar_candidate. name ,
1346
+ Applicability :: MaybeIncorrect ,
1347
+ ) ;
1348
+ } else {
1349
+ // We found a method but either the expression is not a method call or
1350
+ // the argument count didn't match.
1351
+ err. span_help (
1352
+ tcx. def_span ( similar_candidate. def_id ) ,
1353
+ format ! (
1354
+ "there is {an} method `{}` with a similar name{}" ,
1355
+ similar_candidate. name,
1356
+ if let None = args { "" } else { ", but with different arguments" } ,
1357
+ ) ,
1358
+ ) ;
1359
+ }
1360
+ } else if let Some ( args) = args
1361
+ && fn_sig. inputs ( ) . len ( ) == args. len ( )
1362
+ {
1363
+ // We have fn call expression and the argument count match the associated
1364
+ // function we found.
1365
+ err. span_suggestion_verbose (
1366
+ span,
1367
+ format ! (
1368
+ "there is {an} {} with a similar name" ,
1369
+ self . tcx. def_kind_descr( def_kind, similar_candidate. def_id)
1370
+ ) ,
1371
+ similar_candidate. name ,
1372
+ Applicability :: MaybeIncorrect ,
1373
+ ) ;
1374
+ } else {
1375
+ err. span_help (
1376
+ tcx. def_span ( similar_candidate. def_id ) ,
1377
+ format ! (
1378
+ "there is {an} {} `{}` with a similar name" ,
1379
+ self . tcx. def_kind_descr( def_kind, similar_candidate. def_id) ,
1380
+ similar_candidate. name,
1381
+ ) ,
1382
+ ) ;
1383
+ }
1384
+ } else if let Mode :: Path = mode
1385
+ && args. unwrap_or ( & [ ] ) . is_empty ( )
1386
+ {
1387
+ // We have an associated item syntax and we found something that isn't an fn.
1388
+ err. span_suggestion_verbose (
1389
+ span,
1390
+ format ! (
1391
+ "there is {an} {} with a similar name" ,
1392
+ self . tcx. def_kind_descr( def_kind, similar_candidate. def_id)
1393
+ ) ,
1394
+ similar_candidate. name ,
1395
+ Applicability :: MaybeIncorrect ,
1396
+ ) ;
1397
+ } else {
1398
+ // The expression is a function or method call, but the item we found is an
1399
+ // associated const or type.
1400
+ err. span_help (
1401
+ tcx. def_span ( similar_candidate. def_id ) ,
1402
+ format ! (
1403
+ "there is {an} {} `{}` with a similar name" ,
1404
+ self . tcx. def_kind_descr( def_kind, similar_candidate. def_id) ,
1405
+ similar_candidate. name,
1406
+ ) ,
1407
+ ) ;
1408
+ }
1409
+ }
1410
+
1398
1411
pub ( crate ) fn confusable_method_name (
1399
1412
& self ,
1400
1413
err : & mut Diagnostic ,
0 commit comments