@@ -2989,7 +2989,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
29892989 . filter_map ( |e| match e. obligation . predicate . kind ( ) . skip_binder ( ) {
29902990 ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( pred) ) => {
29912991 match pred. self_ty ( ) . kind ( ) {
2992- ty:: Adt ( _, _) => Some ( pred) ,
2992+ ty:: Adt ( _, _) => Some ( ( e . root_obligation . predicate , pred) ) ,
29932993 _ => None ,
29942994 }
29952995 }
@@ -2999,18 +2999,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
29992999
30003000 // Note for local items and foreign items respectively.
30013001 let ( mut local_preds, mut foreign_preds) : ( Vec < _ > , Vec < _ > ) =
3002- preds. iter ( ) . partition ( |& pred| {
3002+ preds. iter ( ) . partition ( |& ( _ , pred) | {
30033003 if let ty:: Adt ( def, _) = pred. self_ty ( ) . kind ( ) {
30043004 def. did ( ) . is_local ( )
30053005 } else {
30063006 false
30073007 }
30083008 } ) ;
30093009
3010- local_preds. sort_by_key ( |pred : & & ty :: TraitPredicate < ' _ > | pred. trait_ref . to_string ( ) ) ;
3010+ local_preds. sort_by_key ( |( _ , pred ) | pred. trait_ref . to_string ( ) ) ;
30113011 let local_def_ids = local_preds
30123012 . iter ( )
3013- . filter_map ( |pred| match pred. self_ty ( ) . kind ( ) {
3013+ . filter_map ( |( _ , pred) | match pred. self_ty ( ) . kind ( ) {
30143014 ty:: Adt ( def, _) => Some ( def. did ( ) ) ,
30153015 _ => None ,
30163016 } )
@@ -3023,7 +3023,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
30233023 } )
30243024 . collect :: < Vec < _ > > ( )
30253025 . into ( ) ;
3026- for pred in & local_preds {
3026+ for ( _ , pred) in & local_preds {
30273027 if let ty:: Adt ( def, _) = pred. self_ty ( ) . kind ( ) {
30283028 local_spans. push_span_label (
30293029 self . tcx . def_span ( def. did ( ) ) ,
@@ -3032,7 +3032,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
30323032 }
30333033 }
30343034 if local_spans. primary_span ( ) . is_some ( ) {
3035- let msg = if let [ local_pred] = local_preds. as_slice ( ) {
3035+ let msg = if let [ ( _ , local_pred) ] = local_preds. as_slice ( ) {
30363036 format ! (
30373037 "an implementation of `{}` might be missing for `{}`" ,
30383038 local_pred. trait_ref. print_trait_sugared( ) ,
@@ -3050,9 +3050,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
30503050 err. span_note ( local_spans, msg) ;
30513051 }
30523052
3053- foreign_preds. sort_by_key ( |pred : & & ty:: TraitPredicate < ' _ > | pred. trait_ref . to_string ( ) ) ;
3053+ foreign_preds
3054+ . sort_by_key ( |( _, pred) : & ( _ , ty:: TraitPredicate < ' _ > ) | pred. trait_ref . to_string ( ) ) ;
30543055
3055- for pred in foreign_preds {
3056+ for ( _ , pred) in & foreign_preds {
30563057 let ty = pred. self_ty ( ) ;
30573058 let ty:: Adt ( def, _) = ty. kind ( ) else { continue } ;
30583059 let span = self . tcx . def_span ( def. did ( ) ) ;
@@ -3065,6 +3066,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
30653066 mspan,
30663067 format ! ( "`{ty}` does not implement `{}`" , pred. trait_ref. print_trait_sugared( ) ) ,
30673068 ) ;
3069+
3070+ if foreign_preds. iter ( ) . any ( |& ( root_pred, pred) | {
3071+ if let ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( root_pred) ) =
3072+ root_pred. kind ( ) . skip_binder ( )
3073+ && let Some ( root_adt) = root_pred. self_ty ( ) . ty_adt_def ( )
3074+ {
3075+ self . tcx . is_diagnostic_item ( sym:: HashSet , root_adt. did ( ) )
3076+ && self . tcx . is_diagnostic_item ( sym:: BuildHasher , pred. def_id ( ) )
3077+ } else {
3078+ false
3079+ }
3080+ } ) {
3081+ err. help ( "you might have intended to use a HashMap instead" ) ;
3082+ }
30683083 }
30693084
30703085 let preds: Vec < _ > = errors
0 commit comments