@@ -101,6 +101,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
101101 self . autoderef ( span, ty) . any ( |( ty, _) | matches ! ( ty. kind( ) , ty:: Slice ( ..) | ty:: Array ( ..) ) )
102102 }
103103
104+ #[ instrument( level = "debug" , skip( self ) ) ]
104105 pub fn report_method_error (
105106 & self ,
106107 span : Span ,
@@ -586,22 +587,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
586587
587588 // Find all the requirements that come from a local `impl` block.
588589 let mut skip_list: FxHashSet < _ > = Default :: default ( ) ;
589- let mut spanned_predicates: FxHashMap < MultiSpan , _ > = Default :: default ( ) ;
590- for ( data , p, parent_p, impl_def_id, cause) in unsatisfied_predicates
590+ let mut spanned_predicates = FxHashMap :: default ( ) ;
591+ for ( p, parent_p, impl_def_id, cause) in unsatisfied_predicates
591592 . iter ( )
592593 . filter_map ( |( p, parent, c) | c. as_ref ( ) . map ( |c| ( p, parent, c) ) )
593594 . filter_map ( |( p, parent, c) | match c. code ( ) {
594- ObligationCauseCode :: ImplDerivedObligation ( data) => {
595- Some ( ( & data. derived , p, parent, data. impl_def_id , data) )
595+ ObligationCauseCode :: ImplDerivedObligation ( data)
596+ if matches ! ( p. kind( ) . skip_binder( ) , ty:: PredicateKind :: Clause ( _) ) =>
597+ {
598+ Some ( ( p, parent, data. impl_def_id , data) )
596599 }
597600 _ => None ,
598601 } )
599602 {
600- let parent_trait_ref = data. parent_trait_pred ;
601- let path = parent_trait_ref. print_modifiers_and_trait_path ( ) ;
602- let tr_self_ty = parent_trait_ref. skip_binder ( ) . self_ty ( ) ;
603- let unsatisfied_msg = "unsatisfied trait bound introduced here" ;
604- let derive_msg = "unsatisfied trait bound introduced in this `derive` macro" ;
605603 match self . tcx . hir ( ) . get_if_local ( impl_def_id) {
606604 // Unmet obligation comes from a `derive` macro, point at it once to
607605 // avoid multiple span labels pointing at the same place.
@@ -617,10 +615,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
617615 ) =>
618616 {
619617 let span = self_ty. span . ctxt ( ) . outer_expn_data ( ) . call_site ;
620- let mut spans: MultiSpan = span. into ( ) ;
621- spans. push_span_label ( span, derive_msg) ;
622- let entry = spanned_predicates. entry ( spans) ;
623- entry. or_insert_with ( || ( path, tr_self_ty, Vec :: new ( ) ) ) . 2 . push ( p) ;
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 ( (
624+ span,
625+ "unsatisfied trait bound introduced in this `derive` macro" ,
626+ ) ) ;
627+ entry. 2 . push ( p) ;
628+ skip_list. insert ( p) ;
624629 }
625630
626631 // Unmet obligation coming from an `impl`.
@@ -647,8 +652,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
647652 } ;
648653 err. span_suggestion_verbose (
649654 sp,
650- "consider relaxing the type parameter's implicit \
651- `Sized` bound",
655+ "consider relaxing the type parameter's implicit `Sized` bound" ,
652656 sugg,
653657 Applicability :: MachineApplicable ,
654658 ) ;
@@ -659,25 +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 ( cause. span , unsatisfied_msg) ;
665- 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" ) ) ;
666674 } else {
667- let mut spans = Vec :: with_capacity ( 2 ) ;
668675 if let Some ( trait_ref) = of_trait {
669- spans . push ( trait_ref. path . span ) ;
676+ entry . 0 . insert ( trait_ref. path . span ) ;
670677 }
671- spans. push ( self_ty. span ) ;
672- spans. into ( )
678+ entry. 0 . insert ( self_ty. span ) ;
673679 } ;
674680 if let Some ( trait_ref) = of_trait {
675- spans . push_span_label ( trait_ref. path . span , "" ) ;
681+ entry . 1 . insert ( ( trait_ref. path . span , "" ) ) ;
676682 }
677- spans. push_span_label ( self_ty. span , "" ) ;
678-
679- let entry = spanned_predicates. entry ( spans) ;
680- entry. or_insert_with ( || ( path, tr_self_ty, Vec :: new ( ) ) ) . 2 . push ( p) ;
683+ entry. 1 . insert ( ( self_ty. span , "" ) ) ;
681684 }
682685 Some ( Node :: Item ( hir:: Item {
683686 kind : hir:: ItemKind :: Trait ( rustc_ast:: ast:: IsAuto :: Yes , ..) ,
@@ -694,11 +697,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
694697 }
695698 }
696699 let mut spanned_predicates: Vec < _ > = spanned_predicates. into_iter ( ) . collect ( ) ;
697- spanned_predicates. sort_by_key ( |( span, ( _ , _ , _ ) ) | span. primary_span ( ) ) ;
698- for ( span , ( _path , _self_ty , preds ) ) in spanned_predicates {
699- let mut preds: Vec < _ > = preds
700- . into_iter ( )
701- . filter_map ( |pred| format_pred ( * pred) )
700+ spanned_predicates. sort_by_key ( |( span, _ ) | * span) ;
701+ for ( _ , ( primary_spans , span_labels , predicates ) ) in spanned_predicates {
702+ let mut preds: Vec < _ > = predicates
703+ . iter ( )
704+ . filter_map ( |pred| format_pred ( * * pred) )
702705 . map ( |( p, _) | format ! ( "`{}`" , p) )
703706 . collect ( ) ;
704707 preds. sort ( ) ;
@@ -708,6 +711,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
708711 } else {
709712 format ! ( "the following trait bounds were not satisfied:\n {}" , preds. join( "\n " ) , )
710713 } ;
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+ }
711718 err. span_note ( span, & msg) ;
712719 unsatisfied_bounds = true ;
713720 }
0 commit comments