@@ -248,7 +248,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
248
248
249
249
match error {
250
250
MethodError :: NoMatch ( NoMatchData {
251
- static_candidates : mut static_sources ,
251
+ mut static_candidates ,
252
252
unsatisfied_predicates,
253
253
out_of_scope_traits,
254
254
lev_candidate,
@@ -288,9 +288,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
288
288
if generics. len ( ) > 0 {
289
289
let mut autoderef = self . autoderef ( span, actual) ;
290
290
let candidate_found = autoderef. any ( |( ty, _) | {
291
- if let ty:: Adt ( adt_deref , _) = ty. kind ( ) {
291
+ if let ty:: Adt ( adt_def , _) = ty. kind ( ) {
292
292
self . tcx
293
- . inherent_impls ( adt_deref . did ( ) )
293
+ . inherent_impls ( adt_def . did ( ) )
294
294
. iter ( )
295
295
. filter_map ( |def_id| self . associated_value ( * def_id, item_name) )
296
296
. count ( )
@@ -348,15 +348,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
348
348
}
349
349
350
350
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
+ ) ,
356
354
ty:: Adt ( def, _) if def. did ( ) . is_local ( ) => Some ( tcx. def_span ( def. did ( ) ) ) ,
357
355
_ => None ,
358
356
} ;
359
-
360
357
if let Some ( span) = ty_span {
361
358
err. span_label (
362
359
span,
@@ -386,17 +383,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
386
383
387
384
let mut custom_span_label = false ;
388
385
389
- if !static_sources . is_empty ( ) {
386
+ if !static_candidates . is_empty ( ) {
390
387
err. note (
391
388
"found the following associated functions; to be used as methods, \
392
389
functions must have a `self` parameter",
393
390
) ;
394
391
err. span_label ( span, "this is an associated function, not a method" ) ;
395
392
custom_span_label = true ;
396
393
}
397
- if static_sources . len ( ) == 1 {
394
+ if static_candidates . len ( ) == 1 {
398
395
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 ) {
400
397
// When the "method" is resolved through dereferencing, we really want the
401
398
// original type that has the associated function for accurate suggestions.
402
399
// (#61411)
@@ -422,9 +419,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
422
419
err. help ( & format ! ( "try with `{}::{}`" , ty_str, item_name, ) ) ;
423
420
}
424
421
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) ;
428
425
}
429
426
430
427
let mut bound_spans = vec ! [ ] ;
@@ -496,24 +493,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
496
493
if let ( ty:: Param ( _) , ty:: PredicateKind :: Trait ( p) ) =
497
494
( self_ty. kind ( ) , parent_pred. kind ( ) . skip_binder ( ) )
498
495
{
496
+ let hir = self . tcx . hir ( ) ;
499
497
let node = match p. trait_ref . self_ty ( ) . kind ( ) {
500
498
ty:: Param ( _) => {
501
499
// Account for `fn` items like in `issue-35677.rs` to
502
500
// 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) )
511
507
}
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
- } ) ,
517
508
_ => None ,
518
509
} ;
519
510
if let Some ( hir:: Node :: Item ( hir:: Item { kind, .. } ) ) = node {
@@ -605,7 +596,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
605
596
. iter ( )
606
597
. filter_map ( |( p, parent, c) | c. as_ref ( ) . map ( |c| ( p, parent, c) ) )
607
598
. filter_map ( |( p, parent, c) | match c. code ( ) {
608
- ObligationCauseCode :: ImplDerivedObligation ( ref data) => {
599
+ ObligationCauseCode :: ImplDerivedObligation ( data) => {
609
600
Some ( ( & data. derived , p, parent, data. impl_def_id , data) )
610
601
}
611
602
_ => None ,
@@ -620,22 +611,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
620
611
match self . tcx . hir ( ) . get_if_local ( impl_def_id) {
621
612
// Unmet obligation comes from a `derive` macro, point at it once to
622
613
// 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
-
639
614
Some ( Node :: Item ( hir:: Item {
640
615
kind : hir:: ItemKind :: Impl ( hir:: Impl { of_trait, self_ty, .. } ) ,
641
616
..
@@ -659,34 +634,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
659
634
entry. or_insert_with ( || ( path, tr_self_ty, Vec :: new ( ) ) ) . 2 . push ( p) ;
660
635
}
661
636
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
-
690
637
// Unmet obligation coming from an `impl`.
691
638
Some ( Node :: Item ( hir:: Item {
692
639
kind :
@@ -695,19 +642,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
695
642
} ) ,
696
643
span : item_span,
697
644
..
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
+ } ) ) => {
711
646
let sized_pred =
712
647
unsatisfied_predicates. iter ( ) . any ( |( pred, _, _) | {
713
648
match pred. kind ( ) . skip_binder ( ) {
@@ -759,7 +694,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
759
694
let entry = spanned_predicates. entry ( spans) ;
760
695
entry. or_insert_with ( || ( path, tr_self_ty, Vec :: new ( ) ) ) . 2 . push ( p) ;
761
696
}
762
- _ => { }
697
+ Some ( _) => unreachable ! ( ) ,
698
+ None => ( ) ,
763
699
}
764
700
}
765
701
let mut spanned_predicates: Vec < _ > = spanned_predicates. into_iter ( ) . collect ( ) ;
@@ -863,7 +799,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
863
799
. on_unimplemented_note ( trait_ref, & obligation) ;
864
800
( message, label)
865
801
} )
866
- . unwrap_or ( ( None , None ) )
802
+ . unwrap ( )
867
803
} else {
868
804
( None , None )
869
805
} ;
@@ -972,7 +908,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
972
908
// If the method name is the name of a field with a function or closure type,
973
909
// give a helping note that it has to be called as `(x.f)(...)`.
974
910
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)
976
912
&& lev_candidate. is_none ( )
977
913
&& !custom_span_label
978
914
{
@@ -982,10 +918,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
982
918
label_span_not_found ( & mut err) ;
983
919
}
984
920
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 .
987
923
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) ;
989
925
}
990
926
991
927
self . check_for_inner_self ( & mut err, source, span, actual, item_name) ;
@@ -1007,7 +943,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1007
943
source,
1008
944
out_of_scope_traits,
1009
945
& unsatisfied_predicates,
1010
- & static_sources ,
946
+ & static_candidates ,
1011
947
unsatisfied_bounds,
1012
948
) ;
1013
949
}
@@ -1146,7 +1082,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1146
1082
None
1147
1083
}
1148
1084
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 (
1150
1088
& self ,
1151
1089
span : Span ,
1152
1090
rcvr_ty : Ty < ' tcx > ,
@@ -1408,7 +1346,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1408
1346
false
1409
1347
}
1410
1348
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 (
1412
1351
& self ,
1413
1352
err : & mut Diagnostic ,
1414
1353
source : SelfSource < ' tcx > ,
@@ -2021,7 +1960,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2021
1960
) {
2022
1961
let mut alt_rcvr_sugg = false ;
2023
1962
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
+ ) ;
2025
1967
let skippable = [
2026
1968
self . tcx . lang_items ( ) . clone_trait ( ) ,
2027
1969
self . tcx . lang_items ( ) . deref_trait ( ) ,
@@ -2060,7 +2002,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2060
2002
// suggestions are generally misleading (see #94218).
2061
2003
break ;
2062
2004
}
2063
- _ => { }
2005
+ Err ( _ ) => ( ) ,
2064
2006
}
2065
2007
2066
2008
for ( rcvr_ty, pre) in & [
0 commit comments