@@ -15,7 +15,7 @@ use rustc_middle::ty::adjustment::{
1515use  rustc_middle:: ty:: { self ,  GenericArgsRef ,  Ty ,  TyCtxt ,  TypeVisitableExt } ; 
1616use  rustc_middle:: { bug,  span_bug} ; 
1717use  rustc_span:: def_id:: LocalDefId ; 
18- use  rustc_span:: { Span ,  sym} ; 
18+ use  rustc_span:: { Span ,  Symbol ,   sym} ; 
1919use  rustc_target:: spec:: { AbiMap ,  AbiMapping } ; 
2020use  rustc_trait_selection:: error_reporting:: traits:: DefIdOrName ; 
2121use  rustc_trait_selection:: infer:: InferCtxtExt  as  _; 
@@ -78,7 +78,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
7878            _ => self . check_expr ( callee_expr) , 
7979        } ; 
8080
81-         let  expr_ty = self . structurally_resolve_type ( call_expr. span ,  original_callee_ty) ; 
81+         let  expr_ty = self . try_structurally_resolve_type ( call_expr. span ,  original_callee_ty) ; 
8282
8383        let  mut  autoderef = self . autoderef ( callee_expr. span ,  expr_ty) ; 
8484        let  mut  result = None ; 
@@ -200,7 +200,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
200200        arg_exprs :  & ' tcx  [ hir:: Expr < ' tcx > ] , 
201201        autoderef :  & Autoderef < ' a ,  ' tcx > , 
202202    )  -> Option < CallStep < ' tcx > >  { 
203-         let  adjusted_ty = self . structurally_resolve_type ( autoderef. span ( ) ,  autoderef. final_ty ( ) ) ; 
203+         let  adjusted_ty =
204+             self . try_structurally_resolve_type ( autoderef. span ( ) ,  autoderef. final_ty ( ) ) ; 
204205
205206        // If the callee is a function pointer or a closure, then we're all set. 
206207        match  * adjusted_ty. kind ( )  { 
@@ -297,6 +298,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
297298                return  None ; 
298299            } 
299300
301+             ty:: Infer ( ty:: TyVar ( vid) )  => { 
302+                 // If we end up with an inference variable which is not the hidden type of 
303+                 // an opaque, emit an error. 
304+                 if  let  Some ( alias_ty)  = self . find_opaque_type_related_to_vid ( vid)  { 
305+                     return  self 
306+                         . try_overloaded_call_traits_for_alias ( call_expr,  alias_ty,  arg_exprs) 
307+                         . map ( |( autoref,  method) | { 
308+                             let  mut  adjustments = self . adjust_steps ( autoderef) ; 
309+                             adjustments. extend ( autoref) ; 
310+                             self . apply_adjustments ( callee_expr,  adjustments) ; 
311+                             CallStep :: Overloaded ( method) 
312+                         } ) ; 
313+                 }  else  { 
314+                     self . type_must_be_known_at_this_point ( autoderef. span ( ) ,  adjusted_ty) ; 
315+                     return  None ; 
316+                 } 
317+             } 
318+ 
300319            ty:: Error ( _)  => { 
301320                return  None ; 
302321            } 
@@ -401,6 +420,102 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
401420        None 
402421    } 
403422
423+     fn  try_overloaded_call_trait ( 
424+         & self , 
425+         call_expr :  & hir:: Expr < ' _ > , 
426+         call_ty :  Ty < ' tcx > , 
427+         opt_arg_exprs :  Option < & ' tcx  [ hir:: Expr < ' tcx > ] > , 
428+         opt_trait_def_id :  Option < DefId > , 
429+         method_name :  Symbol , 
430+         borrow :  bool , 
431+     )  -> Option < ( Option < Adjustment < ' tcx > > ,  MethodCallee < ' tcx > ) >  { 
432+         let  Some ( trait_def_id)  = opt_trait_def_id else  { 
433+             return  None ; 
434+         } ; 
435+ 
436+         let  opt_input_type = opt_arg_exprs. map ( |arg_exprs| { 
437+             Ty :: new_tup_from_iter ( self . tcx ,  arg_exprs. iter ( ) . map ( |e| self . next_ty_var ( e. span ) ) ) 
438+         } ) ; 
439+ 
440+         let  Some ( ok)  = self . lookup_method_for_operator ( 
441+             self . misc ( call_expr. span ) , 
442+             method_name, 
443+             trait_def_id, 
444+             call_ty, 
445+             opt_input_type, 
446+         )  else  { 
447+             return  None ; 
448+         } ; 
449+         let  method = self . register_infer_ok_obligations ( ok) ; 
450+         let  mut  autoref = None ; 
451+         if  borrow { 
452+             // Check for &self vs &mut self in the method signature. Since this is either 
453+             // the Fn or FnMut trait, it should be one of those. 
454+             let  ty:: Ref ( _,  _,  mutbl)  = * method. sig . inputs ( ) [ 0 ] . kind ( )  else  { 
455+                 bug ! ( "Expected `FnMut`/`Fn` to take receiver by-ref/by-mut" ) 
456+             } ; 
457+ 
458+             // For initial two-phase borrow 
459+             // deployment, conservatively omit 
460+             // overloaded function call ops. 
461+             let  mutbl = AutoBorrowMutability :: new ( mutbl,  AllowTwoPhase :: No ) ; 
462+ 
463+             autoref = Some ( Adjustment  { 
464+                 kind :  Adjust :: Borrow ( AutoBorrow :: Ref ( mutbl) ) , 
465+                 target :  method. sig . inputs ( ) [ 0 ] , 
466+             } ) ; 
467+         } 
468+ 
469+         Some ( ( autoref,  method) ) 
470+     } 
471+ 
472+     fn  try_overloaded_call_traits_for_alias ( 
473+         & self , 
474+         call_expr :  & ' tcx  hir:: Expr < ' tcx > , 
475+         alias_ty :  ty:: AliasTy < ' tcx > , 
476+         arg_exprs :  & ' tcx  [ rustc_hir:: Expr < ' tcx > ] , 
477+     )  -> Option < ( Option < Adjustment < ' tcx > > ,  MethodCallee < ' tcx > ) >  { 
478+         let  call_ty = alias_ty. to_ty ( self . tcx ) ; 
479+ 
480+         let  call_traits = [ 
481+             ( self . tcx . lang_items ( ) . fn_trait ( ) ,  sym:: call,  true ) , 
482+             ( self . tcx . lang_items ( ) . fn_mut_trait ( ) ,  sym:: call_mut,  true ) , 
483+             ( self . tcx . lang_items ( ) . fn_once_trait ( ) ,  sym:: call_once,  false ) , 
484+             ( self . tcx . lang_items ( ) . async_fn_trait ( ) ,  sym:: async_call,  true ) , 
485+             ( self . tcx . lang_items ( ) . async_fn_mut_trait ( ) ,  sym:: async_call_mut,  true ) , 
486+             ( self . tcx . lang_items ( ) . async_fn_once_trait ( ) ,  sym:: async_call_once,  false ) , 
487+         ] ; 
488+         // We only want to try a call trait if it shows up in the bounds 
489+         // of the opaque. We confirm the first one that shows up in the 
490+         // bounds list, which can lead to inference weirdness but doesn't 
491+         // matter today. 
492+         for  clause in 
493+             self . tcx . item_self_bounds ( alias_ty. def_id ) . iter_instantiated ( self . tcx ,  alias_ty. args ) 
494+         { 
495+             let  Some ( poly_trait_ref)  = clause. as_trait_clause ( )  else  { 
496+                 continue ; 
497+             } ; 
498+ 
499+             if  let  Some ( & ( opt_trait_def_id,  method_name,  borrow) )  =
500+                 call_traits. iter ( ) . find ( |( trait_def_id,  _,  _) | { 
501+                     trait_def_id. is_some_and ( |trait_def_id| trait_def_id == poly_trait_ref. def_id ( ) ) 
502+                 } ) 
503+                 && let  Some ( confirmed)  = self . try_overloaded_call_trait ( 
504+                     call_expr, 
505+                     call_ty, 
506+                     Some ( arg_exprs) , 
507+                     opt_trait_def_id, 
508+                     method_name, 
509+                     borrow, 
510+                 ) 
511+             { 
512+                 return  Some ( confirmed) ; 
513+             } 
514+         } 
515+ 
516+         None 
517+     } 
518+ 
404519    /// Give appropriate suggestion when encountering `||{/* not callable */}()`, where the 
405520/// likely intention is to call the closure, suggest `(||{})()`. (#55851) 
406521fn  identify_bad_closure_def_and_call ( 
0 commit comments