@@ -1351,42 +1351,68 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13511351 item_name : Ident ,
13521352 ) {
13531353 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)
13561357 {
13571358 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
13771397 . iter ( )
13781398 . map ( |id| id. name . to_ident_string ( ) )
13791399 . 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+ ) ;
13901416 }
13911417 }
13921418 }
0 commit comments