@@ -101,6 +101,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
101
101
self . autoderef ( span, ty) . any ( |( ty, _) | matches ! ( ty. kind( ) , ty:: Slice ( ..) | ty:: Array ( ..) ) )
102
102
}
103
103
104
+ #[ instrument( level = "debug" , skip( self ) ) ]
104
105
pub fn report_method_error (
105
106
& self ,
106
107
span : Span ,
@@ -586,22 +587,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
586
587
587
588
// Find all the requirements that come from a local `impl` block.
588
589
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
591
592
. iter ( )
592
593
. filter_map ( |( p, parent, c) | c. as_ref ( ) . map ( |c| ( p, parent, c) ) )
593
594
. 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) )
596
599
}
597
600
_ => None ,
598
601
} )
599
602
{
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" ;
605
603
match self . tcx . hir ( ) . get_if_local ( impl_def_id) {
606
604
// Unmet obligation comes from a `derive` macro, point at it once to
607
605
// avoid multiple span labels pointing at the same place.
@@ -617,10 +615,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
617
615
) =>
618
616
{
619
617
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) ;
624
629
}
625
630
626
631
// Unmet obligation coming from an `impl`.
@@ -647,8 +652,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
647
652
} ;
648
653
err. span_suggestion_verbose (
649
654
sp,
650
- "consider relaxing the type parameter's implicit \
651
- `Sized` bound",
655
+ "consider relaxing the type parameter's implicit `Sized` bound" ,
652
656
sugg,
653
657
Applicability :: MachineApplicable ,
654
658
) ;
@@ -659,25 +663,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
659
663
let _ = format_pred ( * pred) ;
660
664
}
661
665
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" ) ) ;
666
674
} else {
667
- let mut spans = Vec :: with_capacity ( 2 ) ;
668
675
if let Some ( trait_ref) = of_trait {
669
- spans . push ( trait_ref. path . span ) ;
676
+ entry . 0 . insert ( trait_ref. path . span ) ;
670
677
}
671
- spans. push ( self_ty. span ) ;
672
- spans. into ( )
678
+ entry. 0 . insert ( self_ty. span ) ;
673
679
} ;
674
680
if let Some ( trait_ref) = of_trait {
675
- spans . push_span_label ( trait_ref. path . span , "" ) ;
681
+ entry . 1 . insert ( ( trait_ref. path . span , "" ) ) ;
676
682
}
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 , "" ) ) ;
681
684
}
682
685
Some ( Node :: Item ( hir:: Item {
683
686
kind : hir:: ItemKind :: Trait ( rustc_ast:: ast:: IsAuto :: Yes , ..) ,
@@ -694,11 +697,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
694
697
}
695
698
}
696
699
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) )
702
705
. map ( |( p, _) | format ! ( "`{}`" , p) )
703
706
. collect ( ) ;
704
707
preds. sort ( ) ;
@@ -708,6 +711,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
708
711
} else {
709
712
format ! ( "the following trait bounds were not satisfied:\n {}" , preds. join( "\n " ) , )
710
713
} ;
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
+ }
711
718
err. span_note ( span, & msg) ;
712
719
unsatisfied_bounds = true ;
713
720
}
0 commit comments