@@ -248,7 +248,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
248248
249249 match error {
250250 MethodError :: NoMatch ( NoMatchData {
251- static_candidates : mut static_sources ,
251+ mut static_candidates ,
252252 unsatisfied_predicates,
253253 out_of_scope_traits,
254254 lev_candidate,
@@ -288,9 +288,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
288288 if generics. len ( ) > 0 {
289289 let mut autoderef = self . autoderef ( span, actual) ;
290290 let candidate_found = autoderef. any ( |( ty, _) | {
291- if let ty:: Adt ( adt_deref , _) = ty. kind ( ) {
291+ if let ty:: Adt ( adt_def , _) = ty. kind ( ) {
292292 self . tcx
293- . inherent_impls ( adt_deref . did ( ) )
293+ . inherent_impls ( adt_def . did ( ) )
294294 . iter ( )
295295 . filter_map ( |def_id| self . associated_value ( * def_id, item_name) )
296296 . count ( )
@@ -348,15 +348,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
348348 }
349349
350350 let ty_span = match actual. kind ( ) {
351- ty:: Param ( param_type) => {
352- let generics = self . tcx . generics_of ( self . body_id . owner . to_def_id ( ) ) ;
353- let type_param = generics. type_param ( param_type, self . tcx ) ;
354- Some ( self . tcx . def_span ( type_param. def_id ) )
355- }
351+ ty:: Param ( param_type) => Some (
352+ param_type. span_from_generics ( self . tcx , self . body_id . owner . to_def_id ( ) ) ,
353+ ) ,
356354 ty:: Adt ( def, _) if def. did ( ) . is_local ( ) => Some ( tcx. def_span ( def. did ( ) ) ) ,
357355 _ => None ,
358356 } ;
359-
360357 if let Some ( span) = ty_span {
361358 err. span_label (
362359 span,
@@ -386,17 +383,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
386383
387384 let mut custom_span_label = false ;
388385
389- if !static_sources . is_empty ( ) {
386+ if !static_candidates . is_empty ( ) {
390387 err. note (
391388 "found the following associated functions; to be used as methods, \
392389 functions must have a `self` parameter",
393390 ) ;
394391 err. span_label ( span, "this is an associated function, not a method" ) ;
395392 custom_span_label = true ;
396393 }
397- if static_sources . len ( ) == 1 {
394+ if static_candidates . len ( ) == 1 {
398395 let ty_str =
399- if let Some ( CandidateSource :: Impl ( impl_did) ) = static_sources . get ( 0 ) {
396+ if let Some ( CandidateSource :: Impl ( impl_did) ) = static_candidates . get ( 0 ) {
400397 // When the "method" is resolved through dereferencing, we really want the
401398 // original type that has the associated function for accurate suggestions.
402399 // (#61411)
@@ -422,9 +419,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
422419 err. help ( & format ! ( "try with `{}::{}`" , ty_str, item_name, ) ) ;
423420 }
424421
425- report_candidates ( span, & mut err, & mut static_sources , sugg_span) ;
426- } else if static_sources . len ( ) > 1 {
427- report_candidates ( span, & mut err, & mut static_sources , sugg_span) ;
422+ report_candidates ( span, & mut err, & mut static_candidates , sugg_span) ;
423+ } else if static_candidates . len ( ) > 1 {
424+ report_candidates ( span, & mut err, & mut static_candidates , sugg_span) ;
428425 }
429426
430427 let mut bound_spans = vec ! [ ] ;
@@ -496,24 +493,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
496493 if let ( ty:: Param ( _) , ty:: PredicateKind :: Trait ( p) ) =
497494 ( self_ty. kind ( ) , parent_pred. kind ( ) . skip_binder ( ) )
498495 {
496+ let hir = self . tcx . hir ( ) ;
499497 let node = match p. trait_ref . self_ty ( ) . kind ( ) {
500498 ty:: Param ( _) => {
501499 // Account for `fn` items like in `issue-35677.rs` to
502500 // suggest restricting its type params.
503- let did = self . tcx . hir ( ) . body_owner_def_id ( hir:: BodyId {
504- hir_id : self . body_id ,
505- } ) ;
506- Some (
507- self . tcx
508- . hir ( )
509- . get ( self . tcx . hir ( ) . local_def_id_to_hir_id ( did) ) ,
510- )
501+ let parent_body =
502+ hir. body_owner ( hir:: BodyId { hir_id : self . body_id } ) ;
503+ Some ( hir. get ( parent_body) )
504+ }
505+ ty:: Adt ( def, _) => {
506+ def. did ( ) . as_local ( ) . map ( |def_id| hir. get_by_def_id ( def_id) )
511507 }
512- ty:: Adt ( def, _) => def. did ( ) . as_local ( ) . map ( |def_id| {
513- self . tcx
514- . hir ( )
515- . get ( self . tcx . hir ( ) . local_def_id_to_hir_id ( def_id) )
516- } ) ,
517508 _ => None ,
518509 } ;
519510 if let Some ( hir:: Node :: Item ( hir:: Item { kind, .. } ) ) = node {
@@ -605,7 +596,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
605596 . iter ( )
606597 . filter_map ( |( p, parent, c) | c. as_ref ( ) . map ( |c| ( p, parent, c) ) )
607598 . filter_map ( |( p, parent, c) | match c. code ( ) {
608- ObligationCauseCode :: ImplDerivedObligation ( ref data) => {
599+ ObligationCauseCode :: ImplDerivedObligation ( data) => {
609600 Some ( ( & data. derived , p, parent, data. impl_def_id , data) )
610601 }
611602 _ => None ,
@@ -620,22 +611,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
620611 match self . tcx . hir ( ) . get_if_local ( impl_def_id) {
621612 // Unmet obligation comes from a `derive` macro, point at it once to
622613 // avoid multiple span labels pointing at the same place.
623- Some ( Node :: Item ( hir:: Item {
624- kind : hir:: ItemKind :: Trait ( ..) ,
625- ident,
626- ..
627- } ) ) if matches ! (
628- ident. span. ctxt( ) . outer_expn_data( ) . kind,
629- ExpnKind :: Macro ( MacroKind :: Derive , _)
630- ) =>
631- {
632- let span = ident. span . ctxt ( ) . outer_expn_data ( ) . call_site ;
633- let mut spans: MultiSpan = span. into ( ) ;
634- spans. push_span_label ( span, derive_msg) ;
635- let entry = spanned_predicates. entry ( spans) ;
636- entry. or_insert_with ( || ( path, tr_self_ty, Vec :: new ( ) ) ) . 2 . push ( p) ;
637- }
638-
639614 Some ( Node :: Item ( hir:: Item {
640615 kind : hir:: ItemKind :: Impl ( hir:: Impl { of_trait, self_ty, .. } ) ,
641616 ..
@@ -659,34 +634,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
659634 entry. or_insert_with ( || ( path, tr_self_ty, Vec :: new ( ) ) ) . 2 . push ( p) ;
660635 }
661636
662- // Unmet obligation coming from a `trait`.
663- Some ( Node :: Item ( hir:: Item {
664- kind : hir:: ItemKind :: Trait ( ..) ,
665- ident,
666- span : item_span,
667- ..
668- } ) ) if !matches ! (
669- ident. span. ctxt( ) . outer_expn_data( ) . kind,
670- ExpnKind :: Macro ( MacroKind :: Derive , _)
671- ) =>
672- {
673- if let Some ( pred) = parent_p {
674- // Done to add the "doesn't satisfy" `span_label`.
675- let _ = format_pred ( * pred) ;
676- }
677- skip_list. insert ( p) ;
678- let mut spans = if cause. span != * item_span {
679- let mut spans: MultiSpan = cause. span . into ( ) ;
680- spans. push_span_label ( cause. span , unsatisfied_msg) ;
681- spans
682- } else {
683- ident. span . into ( )
684- } ;
685- spans. push_span_label ( ident. span , "in this trait" ) ;
686- let entry = spanned_predicates. entry ( spans) ;
687- entry. or_insert_with ( || ( path, tr_self_ty, Vec :: new ( ) ) ) . 2 . push ( p) ;
688- }
689-
690637 // Unmet obligation coming from an `impl`.
691638 Some ( Node :: Item ( hir:: Item {
692639 kind :
@@ -695,19 +642,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
695642 } ) ,
696643 span : item_span,
697644 ..
698- } ) ) if !matches ! (
699- self_ty. span. ctxt( ) . outer_expn_data( ) . kind,
700- ExpnKind :: Macro ( MacroKind :: Derive , _)
701- ) && !matches ! (
702- of_trait. as_ref( ) . map( |t| t
703- . path
704- . span
705- . ctxt( )
706- . outer_expn_data( )
707- . kind) ,
708- Some ( ExpnKind :: Macro ( MacroKind :: Derive , _) )
709- ) =>
710- {
645+ } ) ) => {
711646 let sized_pred =
712647 unsatisfied_predicates. iter ( ) . any ( |( pred, _, _) | {
713648 match pred. kind ( ) . skip_binder ( ) {
@@ -759,7 +694,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
759694 let entry = spanned_predicates. entry ( spans) ;
760695 entry. or_insert_with ( || ( path, tr_self_ty, Vec :: new ( ) ) ) . 2 . push ( p) ;
761696 }
762- _ => { }
697+ Some ( _) => unreachable ! ( ) ,
698+ None => ( ) ,
763699 }
764700 }
765701 let mut spanned_predicates: Vec < _ > = spanned_predicates. into_iter ( ) . collect ( ) ;
@@ -863,7 +799,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
863799 . on_unimplemented_note ( trait_ref, & obligation) ;
864800 ( message, label)
865801 } )
866- . unwrap_or ( ( None , None ) )
802+ . unwrap ( )
867803 } else {
868804 ( None , None )
869805 } ;
@@ -972,7 +908,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
972908 // If the method name is the name of a field with a function or closure type,
973909 // give a helping note that it has to be called as `(x.f)(...)`.
974910 if let SelfSource :: MethodCall ( expr) = source {
975- if !self . suggest_field_call ( span, rcvr_ty, expr, item_name, & mut err)
911+ if !self . suggest_calling_field_as_fn ( span, rcvr_ty, expr, item_name, & mut err)
976912 && lev_candidate. is_none ( )
977913 && !custom_span_label
978914 {
@@ -982,10 +918,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
982918 label_span_not_found ( & mut err) ;
983919 }
984920
985- // Don't suggest (for example) `expr.field.method ()` if `expr.method ()`
986- // doesn 't exist due to unsatisfied predicates .
921+ // Don't suggest (for example) `expr.field.clone ()` if `expr.clone ()`
922+ // can 't be called due to `typeof(expr): Clone` not holding .
987923 if unsatisfied_predicates. is_empty ( ) {
988- self . check_for_field_method ( & mut err, source, span, actual, item_name) ;
924+ self . suggest_calling_method_on_field ( & mut err, source, span, actual, item_name) ;
989925 }
990926
991927 self . check_for_inner_self ( & mut err, source, span, actual, item_name) ;
@@ -1007,7 +943,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1007943 source,
1008944 out_of_scope_traits,
1009945 & unsatisfied_predicates,
1010- & static_sources ,
946+ & static_candidates ,
1011947 unsatisfied_bounds,
1012948 ) ;
1013949 }
@@ -1146,7 +1082,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11461082 None
11471083 }
11481084
1149- fn suggest_field_call (
1085+ /// Suggest calling a field with a type that implements the `Fn*` traits instead of a method with
1086+ /// the same name as the field i.e. `(a.my_fn_ptr)(10)` instead of `a.my_fn_ptr(10)`.
1087+ fn suggest_calling_field_as_fn (
11501088 & self ,
11511089 span : Span ,
11521090 rcvr_ty : Ty < ' tcx > ,
@@ -1408,7 +1346,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14081346 false
14091347 }
14101348
1411- fn check_for_field_method (
1349+ /// Suggest calling a method on a field i.e. `a.field.bar()` instead of `a.bar()`
1350+ fn suggest_calling_method_on_field (
14121351 & self ,
14131352 err : & mut Diagnostic ,
14141353 source : SelfSource < ' tcx > ,
@@ -2021,7 +1960,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20211960 ) {
20221961 let mut alt_rcvr_sugg = false ;
20231962 if let ( SelfSource :: MethodCall ( rcvr) , false ) = ( source, unsatisfied_bounds) {
2024- debug ! ( ?span, ?item_name, ?rcvr_ty, ?rcvr) ;
1963+ debug ! (
1964+ "suggest_traits_to_import: span={:?}, item_name={:?}, rcvr_ty={:?}, rcvr={:?}" ,
1965+ span, item_name, rcvr_ty, rcvr
1966+ ) ;
20251967 let skippable = [
20261968 self . tcx . lang_items ( ) . clone_trait ( ) ,
20271969 self . tcx . lang_items ( ) . deref_trait ( ) ,
@@ -2060,7 +2002,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20602002 // suggestions are generally misleading (see #94218).
20612003 break ;
20622004 }
2063- _ => { }
2005+ Err ( _ ) => ( ) ,
20642006 }
20652007
20662008 for ( rcvr_ty, pre) in & [
0 commit comments