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