@@ -1338,42 +1338,68 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13381338 item_name : Ident ,
13391339 ) {
13401340 if let SelfSource :: MethodCall ( expr) = source
1341- && let mod_id = self . tcx . parent_module ( expr. hir_id ) . to_def_id ( )
1342- && let Some ( ( fields, substs) ) = self . get_field_candidates_considering_privacy ( span, actual, mod_id)
1341+ && let mod_id = self . tcx . parent_module ( expr. hir_id ) . to_def_id ( )
1342+ && let Some ( ( fields, substs) ) =
1343+ self . get_field_candidates_considering_privacy ( span, actual, mod_id)
13431344 {
13441345 let call_expr = self . tcx . hir ( ) . expect_expr ( self . tcx . hir ( ) . get_parent_node ( expr. hir_id ) ) ;
1345- for candidate_field in fields {
1346- if let Some ( field_path) = self . check_for_nested_field_satisfying (
1347- span,
1348- & |_, field_ty| {
1349- self . lookup_probe (
1350- span,
1351- item_name,
1352- field_ty,
1353- call_expr,
1354- ProbeScope :: AllTraits ,
1355- )
1356- . is_ok ( )
1357- } ,
1358- candidate_field,
1359- substs,
1360- vec ! [ ] ,
1361- mod_id,
1362- ) {
1363- let field_path_str = field_path
1346+
1347+ let lang_items = self . tcx . lang_items ( ) ;
1348+ let never_mention_traits = [
1349+ lang_items. clone_trait ( ) ,
1350+ lang_items. deref_trait ( ) ,
1351+ lang_items. deref_mut_trait ( ) ,
1352+ self . tcx . get_diagnostic_item ( sym:: AsRef ) ,
1353+ self . tcx . get_diagnostic_item ( sym:: AsMut ) ,
1354+ self . tcx . get_diagnostic_item ( sym:: Borrow ) ,
1355+ self . tcx . get_diagnostic_item ( sym:: BorrowMut ) ,
1356+ ] ;
1357+ let candidate_fields: Vec < _ > = fields
1358+ . filter_map ( |candidate_field| {
1359+ 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 :: TraitsInScope ,
1368+ )
1369+ . map_or ( false , |pick| {
1370+ !never_mention_traits
1371+ . iter ( )
1372+ . flatten ( )
1373+ . any ( |def_id| self . tcx . parent ( pick. item . def_id ) == * def_id)
1374+ } )
1375+ } ,
1376+ candidate_field,
1377+ substs,
1378+ vec ! [ ] ,
1379+ mod_id,
1380+ )
1381+ } )
1382+ . map ( |field_path| {
1383+ field_path
13641384 . iter ( )
13651385 . map ( |id| id. name . to_ident_string ( ) )
13661386 . collect :: < Vec < String > > ( )
1367- . join ( "." ) ;
1368- debug ! ( "field_path_str: {:?}" , field_path_str) ;
1369-
1370- err. span_suggestion_verbose (
1371- item_name. span . shrink_to_lo ( ) ,
1372- "one of the expressions' fields has a method of the same name" ,
1373- format ! ( "{field_path_str}." ) ,
1374- Applicability :: MaybeIncorrect ,
1375- ) ;
1376- }
1387+ . join ( "." )
1388+ } )
1389+ . collect ( ) ;
1390+
1391+ let len = candidate_fields. len ( ) ;
1392+ if len > 0 {
1393+ err. span_suggestions (
1394+ item_name. span . shrink_to_lo ( ) ,
1395+ format ! (
1396+ "{} of the expressions' fields {} a method of the same name" ,
1397+ if len > 1 { "some" } else { "one" } ,
1398+ if len > 1 { "have" } else { "has" } ,
1399+ ) ,
1400+ candidate_fields. iter ( ) . map ( |path| format ! ( "{path}." ) ) ,
1401+ Applicability :: MaybeIncorrect ,
1402+ ) ;
13771403 }
13781404 }
13791405 }
0 commit comments