@@ -11,7 +11,6 @@ use rustc_hir::{
1111 Expr , ExprKind , GenericBound , Node , Path , QPath , Stmt , StmtKind , TyKind , WherePredicate ,
1212} ;
1313use rustc_hir_analysis:: astconv:: AstConv ;
14- use rustc_infer:: infer;
1514use rustc_infer:: traits:: { self , StatementAsExpression } ;
1615use rustc_middle:: lint:: in_external_macro;
1716use rustc_middle:: ty:: {
@@ -23,9 +22,9 @@ use rustc_span::source_map::Spanned;
2322use rustc_span:: symbol:: { sym, Ident } ;
2423use rustc_span:: { Span , Symbol } ;
2524use rustc_trait_selection:: infer:: InferCtxtExt ;
25+ use rustc_trait_selection:: traits:: error_reporting:: suggestions:: TypeErrCtxtExt ;
2626use rustc_trait_selection:: traits:: error_reporting:: DefIdOrName ;
2727use rustc_trait_selection:: traits:: query:: evaluate_obligation:: InferCtxtExt as _;
28- use rustc_trait_selection:: traits:: NormalizeExt ;
2928
3029impl < ' a , ' tcx > FnCtxt < ' a , ' tcx > {
3130 pub ( crate ) fn body_fn_sig ( & self ) -> Option < ty:: FnSig < ' tcx > > {
@@ -94,7 +93,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
9493 found : Ty < ' tcx > ,
9594 can_satisfy : impl FnOnce ( Ty < ' tcx > ) -> bool ,
9695 ) -> bool {
97- let Some ( ( def_id_or_name, output, inputs) ) = self . extract_callable_info ( expr , found)
96+ let Some ( ( def_id_or_name, output, inputs) ) = self . extract_callable_info ( found)
9897 else { return false ; } ;
9998 if can_satisfy ( output) {
10099 let ( sugg_call, mut applicability) = match inputs. len ( ) {
@@ -163,99 +162,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
163162 /// because the callable type must also be well-formed to be called.
164163 pub ( in super :: super ) fn extract_callable_info (
165164 & self ,
166- expr : & Expr < ' _ > ,
167- found : Ty < ' tcx > ,
165+ ty : Ty < ' tcx > ,
168166 ) -> Option < ( DefIdOrName , Ty < ' tcx > , Vec < Ty < ' tcx > > ) > {
169- // Autoderef is useful here because sometimes we box callables, etc.
170- let Some ( ( def_id_or_name, output, inputs) ) = self . autoderef ( expr. span , found) . silence_errors ( ) . find_map ( |( found, _) | {
171- match * found. kind ( ) {
172- ty:: FnPtr ( fn_sig) =>
173- Some ( ( DefIdOrName :: Name ( "function pointer" ) , fn_sig. output ( ) , fn_sig. inputs ( ) ) ) ,
174- ty:: FnDef ( def_id, _) => {
175- let fn_sig = found. fn_sig ( self . tcx ) ;
176- Some ( ( DefIdOrName :: DefId ( def_id) , fn_sig. output ( ) , fn_sig. inputs ( ) ) )
177- }
178- ty:: Closure ( def_id, substs) => {
179- let fn_sig = substs. as_closure ( ) . sig ( ) ;
180- Some ( ( DefIdOrName :: DefId ( def_id) , fn_sig. output ( ) , fn_sig. inputs ( ) . map_bound ( |inputs| & inputs[ 1 ..] ) ) )
181- }
182- ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id, substs, .. } ) => {
183- self . tcx . bound_item_bounds ( def_id) . subst ( self . tcx , substs) . iter ( ) . find_map ( |pred| {
184- if let ty:: PredicateKind :: Clause ( ty:: Clause :: Projection ( proj) ) = pred. kind ( ) . skip_binder ( )
185- && Some ( proj. projection_ty . def_id ) == self . tcx . lang_items ( ) . fn_once_output ( )
186- // args tuple will always be substs[1]
187- && let ty:: Tuple ( args) = proj. projection_ty . substs . type_at ( 1 ) . kind ( )
188- {
189- Some ( (
190- DefIdOrName :: DefId ( def_id) ,
191- pred. kind ( ) . rebind ( proj. term . ty ( ) . unwrap ( ) ) ,
192- pred. kind ( ) . rebind ( args. as_slice ( ) ) ,
193- ) )
194- } else {
195- None
196- }
197- } )
198- }
199- ty:: Dynamic ( data, _, ty:: Dyn ) => {
200- data. iter ( ) . find_map ( |pred| {
201- if let ty:: ExistentialPredicate :: Projection ( proj) = pred. skip_binder ( )
202- && Some ( proj. def_id ) == self . tcx . lang_items ( ) . fn_once_output ( )
203- // for existential projection, substs are shifted over by 1
204- && let ty:: Tuple ( args) = proj. substs . type_at ( 0 ) . kind ( )
205- {
206- Some ( (
207- DefIdOrName :: Name ( "trait object" ) ,
208- pred. rebind ( proj. term . ty ( ) . unwrap ( ) ) ,
209- pred. rebind ( args. as_slice ( ) ) ,
210- ) )
211- } else {
212- None
213- }
214- } )
215- }
216- ty:: Param ( param) => {
217- let def_id = self . tcx . generics_of ( self . body_id . owner ) . type_param ( & param, self . tcx ) . def_id ;
218- self . tcx . predicates_of ( self . body_id . owner ) . predicates . iter ( ) . find_map ( |( pred, _) | {
219- if let ty:: PredicateKind :: Clause ( ty:: Clause :: Projection ( proj) ) = pred. kind ( ) . skip_binder ( )
220- && Some ( proj. projection_ty . def_id ) == self . tcx . lang_items ( ) . fn_once_output ( )
221- && proj. projection_ty . self_ty ( ) == found
222- // args tuple will always be substs[1]
223- && let ty:: Tuple ( args) = proj. projection_ty . substs . type_at ( 1 ) . kind ( )
224- {
225- Some ( (
226- DefIdOrName :: DefId ( def_id) ,
227- pred. kind ( ) . rebind ( proj. term . ty ( ) . unwrap ( ) ) ,
228- pred. kind ( ) . rebind ( args. as_slice ( ) ) ,
229- ) )
230- } else {
231- None
232- }
233- } )
234- }
235- _ => None ,
236- }
237- } ) else { return None ; } ;
238-
239- let output = self . replace_bound_vars_with_fresh_vars ( expr. span , infer:: FnCall , output) ;
240- let inputs = inputs
241- . skip_binder ( )
242- . iter ( )
243- . map ( |ty| {
244- self . replace_bound_vars_with_fresh_vars (
245- expr. span ,
246- infer:: FnCall ,
247- inputs. rebind ( * ty) ,
248- )
249- } )
250- . collect ( ) ;
251-
252- // We don't want to register any extra obligations, which should be
253- // implied by wf, but also because that would possibly result in
254- // erroneous errors later on.
255- let infer:: InferOk { value : output, obligations : _ } =
256- self . at ( & self . misc ( expr. span ) , self . param_env ) . normalize ( output) ;
257-
258- if output. is_ty_var ( ) { None } else { Some ( ( def_id_or_name, output, inputs) ) }
167+ self . err_ctxt ( ) . extract_callable_info ( self . body_id , self . param_env , ty)
259168 }
260169
261170 pub fn suggest_two_fn_call (
@@ -267,9 +176,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
267176 rhs_ty : Ty < ' tcx > ,
268177 can_satisfy : impl FnOnce ( Ty < ' tcx > , Ty < ' tcx > ) -> bool ,
269178 ) -> bool {
270- let Some ( ( _, lhs_output_ty, lhs_inputs) ) = self . extract_callable_info ( lhs_expr , lhs_ty)
179+ let Some ( ( _, lhs_output_ty, lhs_inputs) ) = self . extract_callable_info ( lhs_ty)
271180 else { return false ; } ;
272- let Some ( ( _, rhs_output_ty, rhs_inputs) ) = self . extract_callable_info ( rhs_expr , rhs_ty)
181+ let Some ( ( _, rhs_output_ty, rhs_inputs) ) = self . extract_callable_info ( rhs_ty)
273182 else { return false ; } ;
274183
275184 if can_satisfy ( lhs_output_ty, rhs_output_ty) {
0 commit comments