@@ -1351,42 +1351,68 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1351
1351
item_name : Ident ,
1352
1352
) {
1353
1353
if let SelfSource :: MethodCall ( expr) = source
1354
- && let mod_id = self . tcx . parent_module ( expr. hir_id ) . to_def_id ( )
1355
- && let Some ( ( fields, substs) ) = self . get_field_candidates_considering_privacy ( span, actual, mod_id)
1354
+ && let mod_id = self . tcx . parent_module ( expr. hir_id ) . to_def_id ( )
1355
+ && let Some ( ( fields, substs) ) =
1356
+ self . get_field_candidates_considering_privacy ( span, actual, mod_id)
1356
1357
{
1357
1358
let call_expr = self . tcx . hir ( ) . expect_expr ( self . tcx . hir ( ) . get_parent_node ( expr. hir_id ) ) ;
1358
- for candidate_field in fields {
1359
- if let Some ( field_path) = self . check_for_nested_field_satisfying (
1360
- span,
1361
- & |_, field_ty| {
1362
- self . lookup_probe (
1363
- span,
1364
- item_name,
1365
- field_ty,
1366
- call_expr,
1367
- ProbeScope :: AllTraits ,
1368
- )
1369
- . is_ok ( )
1370
- } ,
1371
- candidate_field,
1372
- substs,
1373
- vec ! [ ] ,
1374
- mod_id,
1375
- ) {
1376
- let field_path_str = field_path
1359
+
1360
+ let lang_items = self . tcx . lang_items ( ) ;
1361
+ let never_mention_traits = [
1362
+ lang_items. clone_trait ( ) ,
1363
+ lang_items. deref_trait ( ) ,
1364
+ lang_items. deref_mut_trait ( ) ,
1365
+ self . tcx . get_diagnostic_item ( sym:: AsRef ) ,
1366
+ self . tcx . get_diagnostic_item ( sym:: AsMut ) ,
1367
+ self . tcx . get_diagnostic_item ( sym:: Borrow ) ,
1368
+ self . tcx . get_diagnostic_item ( sym:: BorrowMut ) ,
1369
+ ] ;
1370
+ let candidate_fields: Vec < _ > = fields
1371
+ . filter_map ( |candidate_field| {
1372
+ self . check_for_nested_field_satisfying (
1373
+ span,
1374
+ & |_, field_ty| {
1375
+ self . lookup_probe (
1376
+ span,
1377
+ item_name,
1378
+ field_ty,
1379
+ call_expr,
1380
+ ProbeScope :: TraitsInScope ,
1381
+ )
1382
+ . map_or ( false , |pick| {
1383
+ !never_mention_traits
1384
+ . iter ( )
1385
+ . flatten ( )
1386
+ . any ( |def_id| self . tcx . parent ( pick. item . def_id ) == * def_id)
1387
+ } )
1388
+ } ,
1389
+ candidate_field,
1390
+ substs,
1391
+ vec ! [ ] ,
1392
+ mod_id,
1393
+ )
1394
+ } )
1395
+ . map ( |field_path| {
1396
+ field_path
1377
1397
. iter ( )
1378
1398
. map ( |id| id. name . to_ident_string ( ) )
1379
1399
. collect :: < Vec < String > > ( )
1380
- . join ( "." ) ;
1381
- debug ! ( "field_path_str: {:?}" , field_path_str) ;
1382
-
1383
- err. span_suggestion_verbose (
1384
- item_name. span . shrink_to_lo ( ) ,
1385
- "one of the expressions' fields has a method of the same name" ,
1386
- format ! ( "{field_path_str}." ) ,
1387
- Applicability :: MaybeIncorrect ,
1388
- ) ;
1389
- }
1400
+ . join ( "." )
1401
+ } )
1402
+ . collect ( ) ;
1403
+
1404
+ let len = candidate_fields. len ( ) ;
1405
+ if len > 0 {
1406
+ err. span_suggestions (
1407
+ item_name. span . shrink_to_lo ( ) ,
1408
+ format ! (
1409
+ "{} of the expressions' fields {} a method of the same name" ,
1410
+ if len > 1 { "some" } else { "one" } ,
1411
+ if len > 1 { "have" } else { "has" } ,
1412
+ ) ,
1413
+ candidate_fields. iter ( ) . map ( |path| format ! ( "{path}." ) ) ,
1414
+ Applicability :: MaybeIncorrect ,
1415
+ ) ;
1390
1416
}
1391
1417
}
1392
1418
}
0 commit comments