@@ -990,6 +990,57 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
990990 }
991991 }
992992
993+ fn suggest_method_not_found_because_of_unsatisfied_bounds (
994+ & self ,
995+ err : & mut Diag < ' _ > ,
996+ rcvr_ty : Ty < ' tcx > ,
997+ item_ident : Ident ,
998+ item_kind : & str ,
999+ bound_spans : SortedMap < Span , Vec < String > > ,
1000+ ) {
1001+ let mut ty_span = match rcvr_ty. kind ( ) {
1002+ ty:: Param ( param_type) => {
1003+ Some ( param_type. span_from_generics ( self . tcx , self . body_id . to_def_id ( ) ) )
1004+ }
1005+ ty:: Adt ( def, _) if def. did ( ) . is_local ( ) => Some ( self . tcx . def_span ( def. did ( ) ) ) ,
1006+ _ => None ,
1007+ } ;
1008+ for ( span, mut bounds) in bound_spans {
1009+ if !self . tcx . sess . source_map ( ) . is_span_accessible ( span) {
1010+ continue ;
1011+ }
1012+ bounds. sort ( ) ;
1013+ bounds. dedup ( ) ;
1014+ let pre = if Some ( span) == ty_span {
1015+ ty_span. take ( ) ;
1016+ format ! (
1017+ "{item_kind} `{item_ident}` not found for this {} because it " ,
1018+ rcvr_ty. prefix_string( self . tcx)
1019+ )
1020+ } else {
1021+ String :: new ( )
1022+ } ;
1023+ let msg = match & bounds[ ..] {
1024+ [ bound] => format ! ( "{pre}doesn't satisfy {bound}" ) ,
1025+ bounds if bounds. len ( ) > 4 => format ! ( "doesn't satisfy {} bounds" , bounds. len( ) ) ,
1026+ [ bounds @ .., last] => {
1027+ format ! ( "{pre}doesn't satisfy {} or {last}" , bounds. join( ", " ) )
1028+ }
1029+ [ ] => unreachable ! ( ) ,
1030+ } ;
1031+ err. span_label ( span, msg) ;
1032+ }
1033+ if let Some ( span) = ty_span {
1034+ err. span_label (
1035+ span,
1036+ format ! (
1037+ "{item_kind} `{item_ident}` not found for this {}" ,
1038+ rcvr_ty. prefix_string( self . tcx)
1039+ ) ,
1040+ ) ;
1041+ }
1042+ }
1043+
9931044 fn report_no_match_method_error (
9941045 & self ,
9951046 mut span : Span ,
@@ -1098,13 +1149,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10981149 let mut restrict_type_params = false ;
10991150 let mut suggested_derive = false ;
11001151 let mut unsatisfied_bounds = false ;
1101- let mut ty_span = match rcvr_ty. kind ( ) {
1102- ty:: Param ( param_type) => {
1103- Some ( param_type. span_from_generics ( self . tcx , self . body_id . to_def_id ( ) ) )
1104- }
1105- ty:: Adt ( def, _) if def. did ( ) . is_local ( ) => Some ( tcx. def_span ( def. did ( ) ) ) ,
1106- _ => None ,
1107- } ;
11081152
11091153 if self . suggest_unsatisfied_ty_or_trait (
11101154 & mut err,
@@ -1186,40 +1230,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11861230 similar_candidate,
11871231 ) ;
11881232
1189- for ( span, mut bounds) in bound_spans {
1190- if !tcx. sess . source_map ( ) . is_span_accessible ( span) {
1191- continue ;
1192- }
1193- bounds. sort ( ) ;
1194- bounds. dedup ( ) ;
1195- let pre = if Some ( span) == ty_span {
1196- ty_span. take ( ) ;
1197- format ! (
1198- "{item_kind} `{item_ident}` not found for this {} because it " ,
1199- rcvr_ty. prefix_string( self . tcx)
1200- )
1201- } else {
1202- String :: new ( )
1203- } ;
1204- let msg = match & bounds[ ..] {
1205- [ bound] => format ! ( "{pre}doesn't satisfy {bound}" ) ,
1206- bounds if bounds. len ( ) > 4 => format ! ( "doesn't satisfy {} bounds" , bounds. len( ) ) ,
1207- [ bounds @ .., last] => {
1208- format ! ( "{pre}doesn't satisfy {} or {last}" , bounds. join( ", " ) )
1209- }
1210- [ ] => unreachable ! ( ) ,
1211- } ;
1212- err. span_label ( span, msg) ;
1213- }
1214- if let Some ( span) = ty_span {
1215- err. span_label (
1216- span,
1217- format ! (
1218- "{item_kind} `{item_ident}` not found for this {}" ,
1219- rcvr_ty. prefix_string( self . tcx)
1220- ) ,
1221- ) ;
1222- }
1233+ self . suggest_method_not_found_because_of_unsatisfied_bounds (
1234+ & mut err,
1235+ rcvr_ty,
1236+ item_ident,
1237+ item_kind,
1238+ bound_spans,
1239+ ) ;
12231240
12241241 self . note_derefed_ty_has_method ( & mut err, source, rcvr_ty, item_ident, expected) ;
12251242 err. emit ( )
0 commit comments