@@ -446,6 +446,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
446
446
}
447
447
}
448
448
449
+ let mut label_span_not_found = || {
450
+ if unsatisfied_predicates. is_empty ( ) {
451
+ err. span_label ( span, format ! ( "{item_kind} not found in `{ty_str}`" ) ) ;
452
+ } else {
453
+ err. span_label ( span, format ! ( "{item_kind} cannot be called on `{ty_str}` due to unsatisfied trait bounds" ) ) ;
454
+ }
455
+ self . tcx . sess . trait_methods_not_found . borrow_mut ( ) . insert ( orig_span) ;
456
+ } ;
457
+
449
458
// If the method name is the name of a field with a function or closure type,
450
459
// give a helping note that it has to be called as `(x.f)(...)`.
451
460
if let SelfSource :: MethodCall ( expr) = source {
@@ -501,12 +510,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
501
510
let field_kind = if is_accessible { "field" } else { "private field" } ;
502
511
err. span_label ( item_name. span , format ! ( "{}, not a method" , field_kind) ) ;
503
512
} else if lev_candidate. is_none ( ) && static_sources. is_empty ( ) {
504
- err. span_label ( span, format ! ( "{} not found in `{}`" , item_kind, ty_str) ) ;
505
- self . tcx . sess . trait_methods_not_found . borrow_mut ( ) . insert ( orig_span) ;
513
+ label_span_not_found ( ) ;
506
514
}
507
515
} else {
508
- err. span_label ( span, format ! ( "{} not found in `{}`" , item_kind, ty_str) ) ;
509
- self . tcx . sess . trait_methods_not_found . borrow_mut ( ) . insert ( orig_span) ;
516
+ label_span_not_found ( ) ;
510
517
}
511
518
512
519
if self . is_fn_ty ( & rcvr_ty, span) {
@@ -721,10 +728,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
721
728
. map ( |( _, path) | path)
722
729
. collect :: < Vec < _ > > ( )
723
730
. join ( "\n " ) ;
731
+ let actual_prefix = actual. prefix_string ( ) ;
732
+ err. set_primary_message ( & format ! (
733
+ "the {item_kind} `{item_name}` exists for {actual_prefix} `{ty_str}`, but its trait bounds were not satisfied"
734
+ ) ) ;
724
735
err. note ( & format ! (
725
- "the method `{}` exists but the following trait bounds were not \
726
- satisfied:\n {}",
727
- item_name, bound_list
736
+ "the following trait bounds were not satisfied:\n {bound_list}"
728
737
) ) ;
729
738
}
730
739
}
@@ -742,7 +751,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
742
751
) ;
743
752
}
744
753
745
- if actual. is_enum ( ) {
754
+ // Don't emit a suggestion if we found an actual method
755
+ // that had unsatisfied trait bounds
756
+ if unsatisfied_predicates. is_empty ( ) && actual. is_enum ( ) {
746
757
let adt_def = actual. ty_adt_def ( ) . expect ( "enum is not an ADT" ) ;
747
758
if let Some ( suggestion) = lev_distance:: find_best_match_for_name (
748
759
& adt_def. variants . iter ( ) . map ( |s| s. ident . name ) . collect :: < Vec < _ > > ( ) ,
@@ -778,17 +789,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
778
789
err. span_label ( span, msg) ;
779
790
}
780
791
} else if let Some ( lev_candidate) = lev_candidate {
781
- let def_kind = lev_candidate. kind . as_def_kind ( ) ;
782
- err. span_suggestion (
783
- span,
784
- & format ! (
785
- "there is {} {} with a similar name" ,
786
- def_kind. article( ) ,
787
- def_kind. descr( lev_candidate. def_id) ,
788
- ) ,
789
- lev_candidate. ident . to_string ( ) ,
790
- Applicability :: MaybeIncorrect ,
791
- ) ;
792
+ // Don't emit a suggestion if we found an actual method
793
+ // that had unsatisfied trait bounds
794
+ if unsatisfied_predicates. is_empty ( ) {
795
+ let def_kind = lev_candidate. kind . as_def_kind ( ) ;
796
+ err. span_suggestion (
797
+ span,
798
+ & format ! (
799
+ "there is {} {} with a similar name" ,
800
+ def_kind. article( ) ,
801
+ def_kind. descr( lev_candidate. def_id) ,
802
+ ) ,
803
+ lev_candidate. ident . to_string ( ) ,
804
+ Applicability :: MaybeIncorrect ,
805
+ ) ;
806
+ }
792
807
}
793
808
794
809
return Some ( err) ;
0 commit comments