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