@@ -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- , 
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