@@ -2831,69 +2831,119 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2831
2831
errors : Vec < FulfillmentError < ' tcx > > ,
2832
2832
suggest_derive : bool ,
2833
2833
) {
2834
- let all_local_types_needing_impls =
2835
- errors. iter ( ) . all ( |e| match e. obligation . predicate . kind ( ) . skip_binder ( ) {
2834
+ let preds: Vec < _ > = errors
2835
+ . iter ( )
2836
+ . filter_map ( |e| match e. obligation . predicate . kind ( ) . skip_binder ( ) {
2836
2837
ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( pred) ) => {
2837
2838
match pred. self_ty ( ) . kind ( ) {
2838
- ty:: Adt ( def , _) => def . did ( ) . is_local ( ) ,
2839
- _ => false ,
2839
+ ty:: Adt ( _ , _) => Some ( pred ) ,
2840
+ _ => None ,
2840
2841
}
2841
2842
}
2842
- _ => false ,
2843
- } ) ;
2844
- let mut preds: Vec < _ > = errors
2845
- . iter ( )
2846
- . filter_map ( |e| match e. obligation . predicate . kind ( ) . skip_binder ( ) {
2847
- ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( pred) ) => Some ( pred) ,
2848
2843
_ => None ,
2849
2844
} )
2850
2845
. collect ( ) ;
2851
- preds. sort_by_key ( |pred| pred. trait_ref . to_string ( ) ) ;
2852
- let def_ids = preds
2846
+
2847
+ // Note for local items and foreign items respectively.
2848
+ let ( mut local_preds, mut foreign_preds) : ( Vec < _ > , Vec < _ > ) =
2849
+ preds. iter ( ) . partition ( |& pred| {
2850
+ if let ty:: Adt ( def, _) = pred. self_ty ( ) . kind ( ) {
2851
+ def. did ( ) . is_local ( )
2852
+ } else {
2853
+ false
2854
+ }
2855
+ } ) ;
2856
+
2857
+ local_preds. sort_by_key ( |pred : & & ty:: TraitPredicate < ' _ > | pred. trait_ref . to_string ( ) ) ;
2858
+ let local_def_ids = local_preds
2853
2859
. iter ( )
2854
2860
. filter_map ( |pred| match pred. self_ty ( ) . kind ( ) {
2855
2861
ty:: Adt ( def, _) => Some ( def. did ( ) ) ,
2856
2862
_ => None ,
2857
2863
} )
2858
2864
. collect :: < FxIndexSet < _ > > ( ) ;
2859
- let mut spans : MultiSpan = def_ids
2865
+ let mut local_spans : MultiSpan = local_def_ids
2860
2866
. iter ( )
2861
2867
. filter_map ( |def_id| {
2862
2868
let span = self . tcx . def_span ( * def_id) ;
2863
2869
if span. is_dummy ( ) { None } else { Some ( span) }
2864
2870
} )
2865
2871
. collect :: < Vec < _ > > ( )
2866
2872
. into ( ) ;
2867
-
2868
- for pred in & preds {
2873
+ for pred in & local_preds {
2869
2874
match pred. self_ty ( ) . kind ( ) {
2870
- ty:: Adt ( def, _) if def . did ( ) . is_local ( ) => {
2871
- spans . push_span_label (
2875
+ ty:: Adt ( def, _) => {
2876
+ local_spans . push_span_label (
2872
2877
self . tcx . def_span ( def. did ( ) ) ,
2873
2878
format ! ( "must implement `{}`" , pred. trait_ref. print_trait_sugared( ) ) ,
2874
2879
) ;
2875
2880
}
2876
2881
_ => { }
2877
2882
}
2878
2883
}
2879
-
2880
- if all_local_types_needing_impls && spans. primary_span ( ) . is_some ( ) {
2881
- let msg = if preds. len ( ) == 1 {
2884
+ if local_spans. primary_span ( ) . is_some ( ) {
2885
+ let msg = if local_preds. len ( ) == 1 {
2882
2886
format ! (
2883
2887
"an implementation of `{}` might be missing for `{}`" ,
2884
- preds [ 0 ] . trait_ref. print_trait_sugared( ) ,
2885
- preds [ 0 ] . self_ty( )
2888
+ local_preds [ 0 ] . trait_ref. print_trait_sugared( ) ,
2889
+ local_preds [ 0 ] . self_ty( )
2886
2890
)
2887
2891
} else {
2888
2892
format ! (
2889
2893
"the following type{} would have to `impl` {} required trait{} for this \
2890
2894
operation to be valid",
2891
- pluralize!( def_ids. len( ) ) ,
2892
- if def_ids. len( ) == 1 { "its" } else { "their" } ,
2893
- pluralize!( preds. len( ) ) ,
2895
+ pluralize!( local_def_ids. len( ) ) ,
2896
+ if local_def_ids. len( ) == 1 { "its" } else { "their" } ,
2897
+ pluralize!( local_preds. len( ) ) ,
2898
+ )
2899
+ } ;
2900
+ err. span_note ( local_spans, msg) ;
2901
+ }
2902
+
2903
+ foreign_preds. sort_by_key ( |pred : & & ty:: TraitPredicate < ' _ > | pred. trait_ref . to_string ( ) ) ;
2904
+ let foreign_def_ids = foreign_preds
2905
+ . iter ( )
2906
+ . filter_map ( |pred| match pred. self_ty ( ) . kind ( ) {
2907
+ ty:: Adt ( def, _) => Some ( def. did ( ) ) ,
2908
+ _ => None ,
2909
+ } )
2910
+ . collect :: < FxIndexSet < _ > > ( ) ;
2911
+ let mut foreign_spans: MultiSpan = foreign_def_ids
2912
+ . iter ( )
2913
+ . filter_map ( |def_id| {
2914
+ let span = self . tcx . def_span ( * def_id) ;
2915
+ if span. is_dummy ( ) { None } else { Some ( span) }
2916
+ } )
2917
+ . collect :: < Vec < _ > > ( )
2918
+ . into ( ) ;
2919
+ for pred in & foreign_preds {
2920
+ match pred. self_ty ( ) . kind ( ) {
2921
+ ty:: Adt ( def, _) => {
2922
+ foreign_spans. push_span_label (
2923
+ self . tcx . def_span ( def. did ( ) ) ,
2924
+ format ! ( "not implement `{}`" , pred. trait_ref. print_trait_sugared( ) ) ,
2925
+ ) ;
2926
+ }
2927
+ _ => { }
2928
+ }
2929
+ }
2930
+ if foreign_spans. primary_span ( ) . is_some ( ) {
2931
+ let msg = if foreign_preds. len ( ) == 1 {
2932
+ format ! (
2933
+ "the foreign item type `{}` doesn't implement `{}`" ,
2934
+ foreign_preds[ 0 ] . self_ty( ) ,
2935
+ foreign_preds[ 0 ] . trait_ref. print_trait_sugared( )
2936
+ )
2937
+ } else {
2938
+ format ! (
2939
+ "the foreign item type{} {} implement required trait{} for this \
2940
+ operation to be valid",
2941
+ pluralize!( foreign_def_ids. len( ) ) ,
2942
+ if foreign_def_ids. len( ) > 1 { "don't" } else { "doesn't" } ,
2943
+ pluralize!( foreign_preds. len( ) ) ,
2894
2944
)
2895
2945
} ;
2896
- err. span_note ( spans , msg) ;
2946
+ err. span_note ( foreign_spans , msg) ;
2897
2947
}
2898
2948
2899
2949
let preds: Vec < _ > = errors
0 commit comments