@@ -997,6 +997,57 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
997997 }
998998 }
999999
1000+ fn suggest_method_not_found_because_of_unsatisfied_bounds (
1001+ & self ,
1002+ err : & mut Diag < ' _ > ,
1003+ rcvr_ty : Ty < ' tcx > ,
1004+ item_ident : Ident ,
1005+ item_kind : & str ,
1006+ bound_spans : SortedMap < Span , Vec < String > > ,
1007+ ) {
1008+ let mut ty_span = match rcvr_ty. kind ( ) {
1009+ ty:: Param ( param_type) => {
1010+ Some ( param_type. span_from_generics ( self . tcx , self . body_id . to_def_id ( ) ) )
1011+ }
1012+ ty:: Adt ( def, _) if def. did ( ) . is_local ( ) => Some ( self . tcx . def_span ( def. did ( ) ) ) ,
1013+ _ => None ,
1014+ } ;
1015+ for ( span, mut bounds) in bound_spans {
1016+ if !self . tcx . sess . source_map ( ) . is_span_accessible ( span) {
1017+ continue ;
1018+ }
1019+ bounds. sort ( ) ;
1020+ bounds. dedup ( ) ;
1021+ let pre = if Some ( span) == ty_span {
1022+ ty_span. take ( ) ;
1023+ format ! (
1024+ "{item_kind} `{item_ident}` not found for this {} because it " ,
1025+ rcvr_ty. prefix_string( self . tcx)
1026+ )
1027+ } else {
1028+ String :: new ( )
1029+ } ;
1030+ let msg = match & bounds[ ..] {
1031+ [ bound] => format ! ( "{pre}doesn't satisfy {bound}" ) ,
1032+ bounds if bounds. len ( ) > 4 => format ! ( "doesn't satisfy {} bounds" , bounds. len( ) ) ,
1033+ [ bounds @ .., last] => {
1034+ format ! ( "{pre}doesn't satisfy {} or {last}" , bounds. join( ", " ) )
1035+ }
1036+ [ ] => unreachable ! ( ) ,
1037+ } ;
1038+ err. span_label ( span, msg) ;
1039+ }
1040+ if let Some ( span) = ty_span {
1041+ err. span_label (
1042+ span,
1043+ format ! (
1044+ "{item_kind} `{item_ident}` not found for this {}" ,
1045+ rcvr_ty. prefix_string( self . tcx)
1046+ ) ,
1047+ ) ;
1048+ }
1049+ }
1050+
10001051 fn report_no_match_method_error (
10011052 & self ,
10021053 mut span : Span ,
@@ -1100,14 +1151,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11001151 & no_match_data,
11011152 ) ;
11021153
1103- let mut ty_span = match rcvr_ty. kind ( ) {
1104- ty:: Param ( param_type) => {
1105- Some ( param_type. span_from_generics ( self . tcx , self . body_id . to_def_id ( ) ) )
1106- }
1107- ty:: Adt ( def, _) if def. did ( ) . is_local ( ) => Some ( tcx. def_span ( def. did ( ) ) ) ,
1108- _ => None ,
1109- } ;
1110-
11111154 let Ok ( (
11121155 restrict_type_params,
11131156 suggested_derive,
@@ -1191,40 +1234,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11911234 similar_candidate,
11921235 ) ;
11931236
1194- for ( span, mut bounds) in bound_spans {
1195- if !tcx. sess . source_map ( ) . is_span_accessible ( span) {
1196- continue ;
1197- }
1198- bounds. sort ( ) ;
1199- bounds. dedup ( ) ;
1200- let pre = if Some ( span) == ty_span {
1201- ty_span. take ( ) ;
1202- format ! (
1203- "{item_kind} `{item_ident}` not found for this {} because it " ,
1204- rcvr_ty. prefix_string( self . tcx)
1205- )
1206- } else {
1207- String :: new ( )
1208- } ;
1209- let msg = match & bounds[ ..] {
1210- [ bound] => format ! ( "{pre}doesn't satisfy {bound}" ) ,
1211- bounds if bounds. len ( ) > 4 => format ! ( "doesn't satisfy {} bounds" , bounds. len( ) ) ,
1212- [ bounds @ .., last] => {
1213- format ! ( "{pre}doesn't satisfy {} or {last}" , bounds. join( ", " ) )
1214- }
1215- [ ] => unreachable ! ( ) ,
1216- } ;
1217- err. span_label ( span, msg) ;
1218- }
1219- if let Some ( span) = ty_span {
1220- err. span_label (
1221- span,
1222- format ! (
1223- "{item_kind} `{item_ident}` not found for this {}" ,
1224- rcvr_ty. prefix_string( self . tcx)
1225- ) ,
1226- ) ;
1227- }
1237+ self . suggest_method_not_found_because_of_unsatisfied_bounds (
1238+ & mut err,
1239+ rcvr_ty,
1240+ item_ident,
1241+ item_kind,
1242+ bound_spans,
1243+ ) ;
12281244
12291245 self . note_derefed_ty_has_method ( & mut err, source, rcvr_ty, item_ident, expected) ;
12301246 self . suggest_bounds_for_range_to_method ( & mut err, source, item_ident) ;
0 commit comments