@@ -587,7 +587,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
587587
588588 // Find all the requirements that come from a local `impl` block.
589589 let mut skip_list: FxHashSet < _ > = Default :: default ( ) ;
590- let mut spanned_predicates: FxHashMap < MultiSpan , _ > = Default :: default ( ) ;
590+ let mut spanned_predicates = FxHashMap :: default ( ) ;
591591 for ( p, parent_p, impl_def_id, cause) in unsatisfied_predicates
592592 . iter ( )
593593 . filter_map ( |( p, parent, c) | c. as_ref ( ) . map ( |c| ( p, parent, c) ) )
@@ -615,13 +615,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
615615 ) =>
616616 {
617617 let span = self_ty. span . ctxt ( ) . outer_expn_data ( ) . call_site ;
618- let mut spans: MultiSpan = span. into ( ) ;
619- spans. push_span_label (
618+ let entry = spanned_predicates. entry ( span) ;
619+ let entry = entry. or_insert_with ( || {
620+ ( FxHashSet :: default ( ) , FxHashSet :: default ( ) , Vec :: new ( ) )
621+ } ) ;
622+ entry. 0 . insert ( span) ;
623+ entry. 1 . insert ( (
620624 span,
621625 "unsatisfied trait bound introduced in this `derive` macro" ,
622- ) ;
623- let entry = spanned_predicates . entry ( spans ) ;
624- entry . or_insert_with ( || Vec :: new ( ) ) . push ( p) ;
626+ ) ) ;
627+ entry. 2 . push ( p ) ;
628+ skip_list . insert ( p) ;
625629 }
626630
627631 // Unmet obligation coming from an `impl`.
@@ -659,28 +663,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
659663 let _ = format_pred ( * pred) ;
660664 }
661665 skip_list. insert ( p) ;
662- let mut spans = if cause. span != * item_span {
663- let mut spans: MultiSpan = cause. span . into ( ) ;
664- spans. push_span_label (
665- cause. span ,
666- "unsatisfied trait bound introduced here" ,
667- ) ;
668- spans
666+ let entry = spanned_predicates. entry ( self_ty. span ) ;
667+ let entry = entry. or_insert_with ( || {
668+ ( FxHashSet :: default ( ) , FxHashSet :: default ( ) , Vec :: new ( ) )
669+ } ) ;
670+ entry. 2 . push ( p) ;
671+ if cause. span != * item_span {
672+ entry. 0 . insert ( cause. span ) ;
673+ entry. 1 . insert ( ( cause. span , "unsatisfied trait bound introduced here" ) ) ;
669674 } else {
670- let mut spans = Vec :: with_capacity ( 2 ) ;
671675 if let Some ( trait_ref) = of_trait {
672- spans . push ( trait_ref. path . span ) ;
676+ entry . 0 . insert ( trait_ref. path . span ) ;
673677 }
674- spans. push ( self_ty. span ) ;
675- spans. into ( )
678+ entry. 0 . insert ( self_ty. span ) ;
676679 } ;
677680 if let Some ( trait_ref) = of_trait {
678- spans . push_span_label ( trait_ref. path . span , "" ) ;
681+ entry . 1 . insert ( ( trait_ref. path . span , "" ) ) ;
679682 }
680- spans. push_span_label ( self_ty. span , "" ) ;
681-
682- let entry = spanned_predicates. entry ( spans) ;
683- entry. or_insert_with ( || Vec :: new ( ) ) . push ( p) ;
683+ entry. 1 . insert ( ( self_ty. span , "" ) ) ;
684684 }
685685 Some ( Node :: Item ( hir:: Item {
686686 kind : hir:: ItemKind :: Trait ( rustc_ast:: ast:: IsAuto :: Yes , ..) ,
@@ -697,8 +697,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
697697 }
698698 }
699699 let mut spanned_predicates: Vec < _ > = spanned_predicates. into_iter ( ) . collect ( ) ;
700- spanned_predicates. sort_by_key ( |( span, _) | span. primary_span ( ) ) ;
701- for ( span , predicates) in spanned_predicates {
700+ spanned_predicates. sort_by_key ( |( span, _) | * span) ;
701+ for ( _ , ( primary_spans , span_labels , predicates) ) in spanned_predicates {
702702 let mut preds: Vec < _ > = predicates
703703 . iter ( )
704704 . filter_map ( |pred| format_pred ( * * pred) )
@@ -711,6 +711,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
711711 } else {
712712 format ! ( "the following trait bounds were not satisfied:\n {}" , preds. join( "\n " ) , )
713713 } ;
714+ let mut span: MultiSpan = primary_spans. into_iter ( ) . collect :: < Vec < _ > > ( ) . into ( ) ;
715+ for ( sp, label) in span_labels {
716+ span. push_span_label ( sp, label) ;
717+ }
714718 err. span_note ( span, & msg) ;
715719 unsatisfied_bounds = true ;
716720 }
0 commit comments