@@ -409,6 +409,78 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
409409 err. downgrade_to_delayed_bug ( ) ;
410410 }
411411
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+ } ;
412484 if tcx. ty_is_opaque_future ( rcvr_ty) && item_name. name == sym:: poll {
413485 err. help ( format ! (
414486 "method `poll` found on `Pin<&mut {ty_str}>`, \
0 commit comments