@@ -2925,7 +2925,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
29252925 . filter_map ( |e| match e. obligation . predicate . kind ( ) . skip_binder ( ) {
29262926 ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( pred) ) => {
29272927 match pred. self_ty ( ) . kind ( ) {
2928- ty:: Adt ( _, _) => Some ( pred) ,
2928+ ty:: Adt ( _, _) => Some ( (
2929+ ( e. root_obligation . predicate , e. root_obligation . cause . span ) ,
2930+ pred,
2931+ ) ) ,
29292932 _ => None ,
29302933 }
29312934 }
@@ -2935,18 +2938,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
29352938
29362939 // Note for local items and foreign items respectively.
29372940 let ( mut local_preds, mut foreign_preds) : ( Vec < _ > , Vec < _ > ) =
2938- preds. iter ( ) . partition ( |& pred| {
2941+ preds. iter ( ) . partition ( |& ( _ , pred) | {
29392942 if let ty:: Adt ( def, _) = pred. self_ty ( ) . kind ( ) {
29402943 def. did ( ) . is_local ( )
29412944 } else {
29422945 false
29432946 }
29442947 } ) ;
29452948
2946- local_preds. sort_by_key ( |pred : & & ty :: TraitPredicate < ' _ > | pred. trait_ref . to_string ( ) ) ;
2949+ local_preds. sort_by_key ( |( _ , pred ) | pred. trait_ref . to_string ( ) ) ;
29472950 let local_def_ids = local_preds
29482951 . iter ( )
2949- . filter_map ( |pred| match pred. self_ty ( ) . kind ( ) {
2952+ . filter_map ( |( _ , pred) | match pred. self_ty ( ) . kind ( ) {
29502953 ty:: Adt ( def, _) => Some ( def. did ( ) ) ,
29512954 _ => None ,
29522955 } )
@@ -2959,7 +2962,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
29592962 } )
29602963 . collect :: < Vec < _ > > ( )
29612964 . into ( ) ;
2962- for pred in & local_preds {
2965+ for ( _ , pred) in & local_preds {
29632966 if let ty:: Adt ( def, _) = pred. self_ty ( ) . kind ( ) {
29642967 local_spans. push_span_label (
29652968 self . tcx . def_span ( def. did ( ) ) ,
@@ -2968,7 +2971,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
29682971 }
29692972 }
29702973 if local_spans. primary_span ( ) . is_some ( ) {
2971- let msg = if let [ local_pred] = local_preds. as_slice ( ) {
2974+ let msg = if let [ ( _ , local_pred) ] = local_preds. as_slice ( ) {
29722975 format ! (
29732976 "an implementation of `{}` might be missing for `{}`" ,
29742977 local_pred. trait_ref. print_trait_sugared( ) ,
@@ -2986,10 +2989,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
29862989 err. span_note ( local_spans, msg) ;
29872990 }
29882991
2989- foreign_preds. sort_by_key ( |pred : & & ty :: TraitPredicate < ' _ > | pred. trait_ref . to_string ( ) ) ;
2992+ foreign_preds. sort_by_key ( |( _ , pred ) | pred. trait_ref . to_string ( ) ) ;
29902993 let foreign_def_ids = foreign_preds
29912994 . iter ( )
2992- . filter_map ( |pred| match pred. self_ty ( ) . kind ( ) {
2995+ . filter_map ( |( _ , pred) | match pred. self_ty ( ) . kind ( ) {
29932996 ty:: Adt ( def, _) => Some ( def. did ( ) ) ,
29942997 _ => None ,
29952998 } )
@@ -3002,7 +3005,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
30023005 } )
30033006 . collect :: < Vec < _ > > ( )
30043007 . into ( ) ;
3005- for pred in & foreign_preds {
3008+ for ( _ , pred) in & foreign_preds {
30063009 if let ty:: Adt ( def, _) = pred. self_ty ( ) . kind ( ) {
30073010 foreign_spans. push_span_label (
30083011 self . tcx . def_span ( def. did ( ) ) ,
@@ -3011,7 +3014,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
30113014 }
30123015 }
30133016 if foreign_spans. primary_span ( ) . is_some ( ) {
3014- let msg = if let [ foreign_pred] = foreign_preds. as_slice ( ) {
3017+ let msg = if let [ ( _ , foreign_pred) ] = foreign_preds. as_slice ( ) {
30153018 format ! (
30163019 "the foreign item type `{}` doesn't implement `{}`" ,
30173020 foreign_pred. self_ty( ) ,
@@ -3027,6 +3030,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
30273030 )
30283031 } ;
30293032 err. span_note ( foreign_spans, msg) ;
3033+
3034+ if let Some ( span) = foreign_preds. iter ( ) . find_map ( |& ( ( root_pred, span) , pred) | {
3035+ match root_pred. kind ( ) . skip_binder ( ) {
3036+ ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( root_pred) )
3037+ if let Some ( root_adt) = root_pred. self_ty ( ) . ty_adt_def ( )
3038+ && self . tcx . is_diagnostic_item ( sym:: HashSet , root_adt. did ( ) )
3039+ && self . tcx . is_diagnostic_item ( sym:: BuildHasher , pred. def_id ( ) ) =>
3040+ {
3041+ Some ( span)
3042+ }
3043+ _ => None ,
3044+ }
3045+ } ) {
3046+ err. span_help ( span, "you might have intended to use a HashMap instead" ) ;
3047+ }
30303048 }
30313049
30323050 let preds: Vec < _ > = errors
0 commit comments