@@ -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 :: method:: TreatNotYetDefinedOpaques ;
2829use crate :: { errors, fluent_generated} ;
2930
3031/// Checks that it is legal to call methods of the trait corresponding
@@ -78,7 +79,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
7879 _ => self . check_expr ( callee_expr) ,
7980 } ;
8081
81- let expr_ty = self . structurally_resolve_type ( call_expr. span , original_callee_ty) ;
82+ let expr_ty = self . try_structurally_resolve_type ( call_expr. span , original_callee_ty) ;
8283
8384 let mut autoderef = self . autoderef ( callee_expr. span , expr_ty) ;
8485 let mut result = None ;
@@ -200,7 +201,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
200201 arg_exprs : & ' tcx [ hir:: Expr < ' tcx > ] ,
201202 autoderef : & Autoderef < ' a , ' tcx > ,
202203 ) -> Option < CallStep < ' tcx > > {
203- let adjusted_ty = self . structurally_resolve_type ( autoderef. span ( ) , autoderef. final_ty ( ) ) ;
204+ let adjusted_ty =
205+ self . try_structurally_resolve_type ( autoderef. span ( ) , autoderef. final_ty ( ) ) ;
204206
205207 // If the callee is a function pointer or a closure, then we're all set.
206208 match * adjusted_ty. kind ( ) {
@@ -297,6 +299,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
297299 return None ;
298300 }
299301
302+ ty:: Infer ( ty:: TyVar ( vid) ) => {
303+ // If we end up with an inference variable which is not the hidden type of
304+ // an opaque, emit an error.
305+ if !self . has_opaques_with_sub_unified_hidden_type ( vid) {
306+ self . type_must_be_known_at_this_point ( autoderef. span ( ) , adjusted_ty) ;
307+ return None ;
308+ }
309+ }
310+
300311 ty:: Error ( _) => {
301312 return None ;
302313 }
@@ -367,26 +378,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
367378 Ty :: new_tup_from_iter ( self . tcx , arg_exprs. iter ( ) . map ( |e| self . next_ty_var ( e. span ) ) )
368379 } ) ;
369380
381+ // We use `TreatNotYetDefinedOpaques::AsRigid` here so that if the `adjusted_ty`
382+ // is `Box<impl FnOnce()>` we choose `FnOnce` instead of `Fn`.
383+ //
384+ // We try all the different call traits in order and choose the first
385+ // one which may apply. So if we treat opaques as inference variables
386+ // `Box<impl FnOnce()>: Fn` is considered ambiguous and chosen.
370387 if let Some ( ok) = self . lookup_method_for_operator (
371388 self . misc ( call_expr. span ) ,
372389 method_name,
373390 trait_def_id,
374391 adjusted_ty,
375392 opt_input_type,
393+ TreatNotYetDefinedOpaques :: AsRigid ,
376394 ) {
377395 let method = self . register_infer_ok_obligations ( ok) ;
378396 let mut autoref = None ;
379397 if borrow {
380398 // Check for &self vs &mut self in the method signature. Since this is either
381399 // the Fn or FnMut trait, it should be one of those.
382- let ty:: Ref ( _, _, mutbl) = method. sig . inputs ( ) [ 0 ] . kind ( ) else {
400+ let ty:: Ref ( _, _, mutbl) = * method. sig . inputs ( ) [ 0 ] . kind ( ) else {
383401 bug ! ( "Expected `FnMut`/`Fn` to take receiver by-ref/by-mut" )
384402 } ;
385403
386404 // For initial two-phase borrow
387405 // deployment, conservatively omit
388406 // overloaded function call ops.
389- let mutbl = AutoBorrowMutability :: new ( * mutbl, AllowTwoPhase :: No ) ;
407+ let mutbl = AutoBorrowMutability :: new ( mutbl, AllowTwoPhase :: No ) ;
390408
391409 autoref = Some ( Adjustment {
392410 kind : Adjust :: Borrow ( AutoBorrow :: Ref ( mutbl) ) ,
0 commit comments