@@ -409,6 +409,78 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
409
409
err. downgrade_to_delayed_bug ( ) ;
410
410
}
411
411
412
+ if let ( ty:: Adt ( adt_def, _) , SelfSource :: QPath ( _) ) = ( rcvr_ty. kind ( ) , source) {
413
+ let mut items = self
414
+ . tcx
415
+ . inherent_impls ( adt_def. did ( ) )
416
+ . iter ( )
417
+ . flat_map ( |i| self . tcx . associated_items ( i) . in_definition_order ( ) )
418
+ . filter ( |item| {
419
+ matches ! ( item. kind, ty:: AssocKind :: Fn ) && !item. fn_has_self_parameter
420
+ } )
421
+ . filter_map ( |item| {
422
+ let ret_ty = self . tcx . fn_sig ( item. def_id ) . skip_binder ( ) . output ( ) . skip_binder ( ) ;
423
+ let ty:: Adt ( def, args) = ret_ty. kind ( ) else {
424
+ return None ;
425
+ } ;
426
+ if ![
427
+ self . tcx . lang_items ( ) . option_type ( ) ,
428
+ self . tcx . get_diagnostic_item ( sym:: Result ) ,
429
+ ]
430
+ . contains ( & Some ( def. did ( ) ) )
431
+ {
432
+ return None ;
433
+ }
434
+ let arg = args. get ( 0 ) ?;
435
+ if self . can_eq ( self . param_env , rcvr_ty, arg. expect_ty ( ) )
436
+ || self . can_eq ( self . param_env , ret_ty, rcvr_ty)
437
+ {
438
+ Some ( ( item. def_id , ret_ty) )
439
+ } else {
440
+ None
441
+ }
442
+ } )
443
+ . collect :: < Vec < _ > > ( ) ;
444
+ let post = if items. len ( ) > 9 {
445
+ let items_len = items. len ( ) ;
446
+ items. truncate ( 8 ) ;
447
+ format ! ( "and {} others" , items_len - 8 )
448
+ } else {
449
+ String :: new ( )
450
+ } ;
451
+ match & items[ ..] {
452
+ [ ] => { }
453
+ [ ( def_id, ret_ty) ] => {
454
+ err. span_note (
455
+ self . tcx . def_span ( def_id) ,
456
+ format ! (
457
+ "if you're trying to build a new `{rcvr_ty}`, consider using `{}` \
458
+ which returns `{ret_ty}`",
459
+ self . tcx. def_path_str( def_id) ,
460
+ ) ,
461
+ ) ;
462
+ }
463
+ _ => {
464
+ let span: MultiSpan = items
465
+ . iter ( )
466
+ . map ( |( def_id, _) | self . tcx . def_span ( def_id) )
467
+ . collect :: < Vec < Span > > ( )
468
+ . into ( ) ;
469
+ err. span_note (
470
+ span,
471
+ format ! (
472
+ "if you're trying to build a new `{rcvr_ty}` consider using one of the \
473
+ following associated functions:\n {}{post}",
474
+ items
475
+ . iter( )
476
+ . map( |( def_id, _ret_ty) | self . tcx. def_path_str( def_id) )
477
+ . collect:: <Vec <String >>( )
478
+ . join( "\n " )
479
+ ) ,
480
+ ) ;
481
+ }
482
+ }
483
+ } ;
412
484
if tcx. ty_is_opaque_future ( rcvr_ty) && item_name. name == sym:: poll {
413
485
err. help ( format ! (
414
486
"method `poll` found on `Pin<&mut {ty_str}>`, \
0 commit comments