@@ -9,6 +9,7 @@ use crate::FnCtxt;
99use  rustc_ast:: ast:: Mutability ; 
1010use  rustc_attr:: parse_confusables; 
1111use  rustc_data_structures:: fx:: { FxIndexMap ,  FxIndexSet } ; 
12+ use  rustc_data_structures:: sorted_map:: SortedMap ; 
1213use  rustc_data_structures:: unord:: UnordSet ; 
1314use  rustc_errors:: { 
1415    codes:: * ,  pluralize,  struct_span_code_err,  Applicability ,  Diagnostic ,  DiagnosticBuilder , 
@@ -458,22 +459,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
458459            ) ; 
459460        } 
460461
461-         let  ty_span = match  rcvr_ty. kind ( )  { 
462+         let  mut   ty_span = match  rcvr_ty. kind ( )  { 
462463            ty:: Param ( param_type)  => { 
463464                Some ( param_type. span_from_generics ( self . tcx ,  self . body_id . to_def_id ( ) ) ) 
464465            } 
465466            ty:: Adt ( def,  _)  if  def. did ( ) . is_local ( )  => Some ( tcx. def_span ( def. did ( ) ) ) , 
466467            _ => None , 
467468        } ; 
468-         if  let  Some ( span)  = ty_span { 
469-             err. span_label ( 
470-                 span, 
471-                 format ! ( 
472-                     "{item_kind} `{item_name}` not found for this {}" , 
473-                     rcvr_ty. prefix_string( self . tcx) 
474-                 ) , 
475-             ) ; 
476-         } 
477469
478470        if  let  SelfSource :: MethodCall ( rcvr_expr)  = source { 
479471            self . suggest_fn_call ( & mut  err,  rcvr_expr,  rcvr_ty,  |output_ty| { 
@@ -546,7 +538,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
546538            ) ; 
547539        } 
548540
549-         let  mut  bound_spans =  vec ! [ ] ; 
541+         let  mut  bound_spans:   SortedMap < Span ,   Vec < String > >  =  Default :: default ( ) ; 
550542        let  mut  restrict_type_params = false ; 
551543        let  mut  unsatisfied_bounds = false ; 
552544        if  item_name. name  == sym:: count && self . is_slice_ty ( rcvr_ty,  span)  { 
@@ -641,28 +633,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
641633                    false 
642634                } ; 
643635            let  mut  bound_span_label = |self_ty :  Ty < ' _ > ,  obligation :  & str ,  quiet :  & str | { 
644-                 let  msg = format ! ( 
645-                     "doesn't satisfy `{}`" , 
646-                     if  obligation. len( )  > 50  {  quiet }  else {  obligation } 
647-                 ) ; 
636+                 let  msg = format ! ( "`{}`" ,  if  obligation. len( )  > 50  {  quiet }  else {  obligation } ) ; 
648637                match  & self_ty. kind ( )  { 
649638                    // Point at the type that couldn't satisfy the bound. 
650-                     ty:: Adt ( def,  _)  => bound_spans. push ( ( self . tcx . def_span ( def. did ( ) ) ,  msg) ) , 
639+                     ty:: Adt ( def,  _)  => { 
640+                         bound_spans. get_mut_or_insert_default ( tcx. def_span ( def. did ( ) ) ) . push ( msg) 
641+                     } 
651642                    // Point at the trait object that couldn't satisfy the bound. 
652643                    ty:: Dynamic ( preds,  _,  _)  => { 
653644                        for  pred in  preds. iter ( )  { 
654645                            match  pred. skip_binder ( )  { 
655646                                ty:: ExistentialPredicate :: Trait ( tr)  => { 
656-                                     bound_spans. push ( ( self . tcx . def_span ( tr. def_id ) ,  msg. clone ( ) ) ) 
647+                                     bound_spans
648+                                         . get_mut_or_insert_default ( tcx. def_span ( tr. def_id ) ) 
649+                                         . push ( msg. clone ( ) ) ; 
657650                                } 
658651                                ty:: ExistentialPredicate :: Projection ( _) 
659652                                | ty:: ExistentialPredicate :: AutoTrait ( _)  => { } 
660653                            } 
661654                        } 
662655                    } 
663656                    // Point at the closure that couldn't satisfy the bound. 
664-                     ty:: Closure ( def_id,  _)  => bound_spans
665-                         . push ( ( tcx. def_span ( * def_id) ,  format ! ( "doesn't satisfy `{quiet}`" ) ) ) , 
657+                     ty:: Closure ( def_id,  _)  => { 
658+                         bound_spans
659+                             . get_mut_or_insert_default ( tcx. def_span ( * def_id) ) 
660+                             . push ( format ! ( "`{quiet}`" ) ) ; 
661+                     } 
666662                    _ => { } 
667663                } 
668664            } ; 
@@ -1169,11 +1165,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11691165
11701166        self . suggest_unwrapping_inner_self ( & mut  err,  source,  rcvr_ty,  item_name) ; 
11711167
1172-         bound_spans. sort ( ) ; 
1173-         bound_spans. dedup ( ) ; 
1174-         for  ( span,  msg)  in  bound_spans. into_iter ( )  { 
1168+         for  ( span,  mut  bounds)  in  bound_spans { 
1169+             if  !tcx. sess . source_map ( ) . is_span_accessible ( span)  { 
1170+                 continue ; 
1171+             } 
1172+             bounds. sort ( ) ; 
1173+             bounds. dedup ( ) ; 
1174+             let  pre = if  Some ( span)  == ty_span { 
1175+                 ty_span. take ( ) ; 
1176+                 format ! ( 
1177+                     "{item_kind} `{item_name}` not found for this {} because it " , 
1178+                     rcvr_ty. prefix_string( self . tcx) 
1179+                 ) 
1180+             }  else  { 
1181+                 String :: new ( ) 
1182+             } ; 
1183+             let  msg = match  & bounds[ ..]  { 
1184+                 [ bound]  => format ! ( "{pre}doesn't satisfy {bound}" ) , 
1185+                 bounds if  bounds. len ( )  > 4  => format ! ( "doesn't satisfy {} bounds" ,  bounds. len( ) ) , 
1186+                 [ bounds @ ..,  last]  => { 
1187+                     format ! ( "{pre}doesn't satisfy {} or {last}" ,  bounds. join( ", " ) ) 
1188+                 } 
1189+                 [ ]  => unreachable ! ( ) , 
1190+             } ; 
11751191            err. span_label ( span,  msg) ; 
11761192        } 
1193+         if  let  Some ( span)  = ty_span { 
1194+             err. span_label ( 
1195+                 span, 
1196+                 format ! ( 
1197+                     "{item_kind} `{item_name}` not found for this {}" , 
1198+                     rcvr_ty. prefix_string( self . tcx) 
1199+                 ) , 
1200+             ) ; 
1201+         } 
11771202
11781203        if  rcvr_ty. is_numeric ( )  && rcvr_ty. is_fresh ( )  || restrict_type_params { 
11791204        }  else  { 
0 commit comments