@@ -25,6 +25,7 @@ use tracing::{debug, instrument};
2525use super :: method:: MethodCallee ;
2626use super :: method:: probe:: ProbeScope ;
2727use super :: { Expectation , FnCtxt , TupleArgumentsFlag } ;
28+ use crate :: expr_use_visitor:: TypeInformationCtxt ;
2829use crate :: { errors, fluent_generated} ;
2930
3031/// Checks that it is legal to call methods of the trait corresponding
@@ -122,7 +123,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
122123 ) ;
123124 }
124125
125- let guar = self . report_invalid_callee ( call_expr, callee_expr, expr_ty, arg_exprs) ;
126+ let guar = self . report_invalid_callee (
127+ call_expr,
128+ callee_expr,
129+ expr_ty,
130+ arg_exprs,
131+ expected,
132+ ) ;
126133 Ty :: new_error ( self . tcx , guar)
127134 }
128135
@@ -677,6 +684,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
677684 callee_expr : & ' tcx hir:: Expr < ' tcx > ,
678685 callee_ty : Ty < ' tcx > ,
679686 arg_exprs : & ' tcx [ hir:: Expr < ' tcx > ] ,
687+ expected : Expectation < ' tcx > ,
680688 ) -> ErrorGuaranteed {
681689 // Callee probe fails when APIT references errors, so suppress those
682690 // errors here.
@@ -806,6 +814,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
806814 err. span_label ( def_span, "the callable type is defined here" ) ;
807815 }
808816 } else {
817+ // Suggest adding <Param>: Fn(...) [-> RetType]
818+ if callee_ty. has_non_region_param ( ) {
819+ let arg_types: Vec < Ty < ' tcx > > = arg_exprs
820+ . iter ( )
821+ . map ( |arg| self . typeck_results . borrow ( ) . expr_ty ( arg) )
822+ . collect ( ) ;
823+ let args_tuple = Ty :: new_tup ( self . tcx ( ) , & arg_types) ;
824+
825+ let fn_def_id = self . tcx ( ) . require_lang_item ( LangItem :: Fn , callee_expr. span ) ;
826+ let trait_ref =
827+ ty:: TraitRef :: new ( self . tcx ( ) , fn_def_id, [ callee_ty, args_tuple] ) ;
828+
829+ let trait_pred =
830+ ty:: TraitPredicate { trait_ref, polarity : ty:: PredicatePolarity :: Positive } ;
831+
832+ let associated_ty = expected. to_option ( self ) . map ( |ty| ( "Output" , ty) ) ;
833+ self . err_ctxt ( ) . suggest_restricting_param_bound (
834+ & mut err,
835+ ty:: Binder :: dummy ( trait_pred) ,
836+ associated_ty,
837+ self . body_id ,
838+ ) ;
839+ }
809840 err. span_label ( call_expr. span , "call expression requires function" ) ;
810841 }
811842 }
0 commit comments