@@ -1337,6 +1337,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13371337 but its trait bounds were not satisfied"
13381338 )
13391339 } ) ;
1340+
13401341 err. primary_message ( primary_message) ;
13411342 if let Some ( label) = label {
13421343 custom_span_label = true ;
@@ -1353,6 +1354,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13531354
13541355 suggested_derive = self . suggest_derive ( & mut err, unsatisfied_predicates) ;
13551356
1357+ if let ty:: Adt ( adt_def, _) = rcvr_ty. kind ( )
1358+ && self . tcx . is_diagnostic_item ( sym:: HashSet , adt_def. did ( ) )
1359+ && unsatisfied_predicates. iter ( ) . any ( |( pred, _parent, _cause) | {
1360+ if let ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( pred) ) =
1361+ pred. kind ( ) . skip_binder ( )
1362+ {
1363+ self . tcx . is_diagnostic_item ( sym:: BuildHasher , pred. def_id ( ) )
1364+ } else {
1365+ false
1366+ }
1367+ } )
1368+ {
1369+ err. help ( "you might have intended to use a HashMap instead" ) ;
1370+ }
1371+
13561372 unsatisfied_bounds = true ;
13571373 }
13581374 } else if let ty:: Adt ( def, targs) = rcvr_ty. kind ( )
@@ -2925,7 +2941,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
29252941 . filter_map ( |e| match e. obligation . predicate . kind ( ) . skip_binder ( ) {
29262942 ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( pred) ) => {
29272943 match pred. self_ty ( ) . kind ( ) {
2928- ty:: Adt ( _, _) => Some ( pred) ,
2944+ ty:: Adt ( _, _) => Some ( ( e . root_obligation . predicate , pred) ) ,
29292945 _ => None ,
29302946 }
29312947 }
@@ -2935,18 +2951,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
29352951
29362952 // Note for local items and foreign items respectively.
29372953 let ( mut local_preds, mut foreign_preds) : ( Vec < _ > , Vec < _ > ) =
2938- preds. iter ( ) . partition ( |& pred| {
2954+ preds. iter ( ) . partition ( |& ( _ , pred) | {
29392955 if let ty:: Adt ( def, _) = pred. self_ty ( ) . kind ( ) {
29402956 def. did ( ) . is_local ( )
29412957 } else {
29422958 false
29432959 }
29442960 } ) ;
29452961
2946- local_preds. sort_by_key ( |pred : & & ty :: TraitPredicate < ' _ > | pred. trait_ref . to_string ( ) ) ;
2962+ local_preds. sort_by_key ( |( _ , pred ) | pred. trait_ref . to_string ( ) ) ;
29472963 let local_def_ids = local_preds
29482964 . iter ( )
2949- . filter_map ( |pred| match pred. self_ty ( ) . kind ( ) {
2965+ . filter_map ( |( _ , pred) | match pred. self_ty ( ) . kind ( ) {
29502966 ty:: Adt ( def, _) => Some ( def. did ( ) ) ,
29512967 _ => None ,
29522968 } )
@@ -2959,7 +2975,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
29592975 } )
29602976 . collect :: < Vec < _ > > ( )
29612977 . into ( ) ;
2962- for pred in & local_preds {
2978+ for ( _ , pred) in & local_preds {
29632979 if let ty:: Adt ( def, _) = pred. self_ty ( ) . kind ( ) {
29642980 local_spans. push_span_label (
29652981 self . tcx . def_span ( def. did ( ) ) ,
@@ -2968,7 +2984,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
29682984 }
29692985 }
29702986 if local_spans. primary_span ( ) . is_some ( ) {
2971- let msg = if let [ local_pred] = local_preds. as_slice ( ) {
2987+ let msg = if let [ ( _ , local_pred) ] = local_preds. as_slice ( ) {
29722988 format ! (
29732989 "an implementation of `{}` might be missing for `{}`" ,
29742990 local_pred. trait_ref. print_trait_sugared( ) ,
@@ -2986,10 +3002,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
29863002 err. span_note ( local_spans, msg) ;
29873003 }
29883004
2989- foreign_preds. sort_by_key ( |pred : & & ty :: TraitPredicate < ' _ > | pred. trait_ref . to_string ( ) ) ;
3005+ foreign_preds. sort_by_key ( |( _ , pred ) | pred. trait_ref . to_string ( ) ) ;
29903006 let foreign_def_ids = foreign_preds
29913007 . iter ( )
2992- . filter_map ( |pred| match pred. self_ty ( ) . kind ( ) {
3008+ . filter_map ( |( _ , pred) | match pred. self_ty ( ) . kind ( ) {
29933009 ty:: Adt ( def, _) => Some ( def. did ( ) ) ,
29943010 _ => None ,
29953011 } )
@@ -3002,7 +3018,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
30023018 } )
30033019 . collect :: < Vec < _ > > ( )
30043020 . into ( ) ;
3005- for pred in & foreign_preds {
3021+ for ( _ , pred) in & foreign_preds {
30063022 if let ty:: Adt ( def, _) = pred. self_ty ( ) . kind ( ) {
30073023 foreign_spans. push_span_label (
30083024 self . tcx . def_span ( def. did ( ) ) ,
@@ -3011,7 +3027,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
30113027 }
30123028 }
30133029 if foreign_spans. primary_span ( ) . is_some ( ) {
3014- let msg = if let [ foreign_pred] = foreign_preds. as_slice ( ) {
3030+ let msg = if let [ ( _ , foreign_pred) ] = foreign_preds. as_slice ( ) {
30153031 format ! (
30163032 "the foreign item type `{}` doesn't implement `{}`" ,
30173033 foreign_pred. self_ty( ) ,
@@ -3027,6 +3043,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
30273043 )
30283044 } ;
30293045 err. span_note ( foreign_spans, msg) ;
3046+
3047+ if foreign_preds. iter ( ) . any ( |& ( root_pred, pred) | {
3048+ if let ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( root_pred) ) =
3049+ root_pred. kind ( ) . skip_binder ( )
3050+ && let Some ( root_adt) = root_pred. self_ty ( ) . ty_adt_def ( )
3051+ {
3052+ self . tcx . is_diagnostic_item ( sym:: HashSet , root_adt. did ( ) )
3053+ && self . tcx . is_diagnostic_item ( sym:: BuildHasher , pred. def_id ( ) )
3054+ } else {
3055+ false
3056+ }
3057+ } ) {
3058+ err. help ( "you might have intended to use a HashMap instead" ) ;
3059+ }
30303060 }
30313061
30323062 let preds: Vec < _ > = errors
0 commit comments