@@ -369,44 +369,38 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
369369 }
370370
371371 /// Evaluate the arguments of a function call
372- fn eval_fn_call_arguments (
372+ fn eval_fn_call_argument (
373373 & self ,
374- ops : & [ Spanned < mir:: Operand < ' tcx > > ] ,
375- ) -> InterpResult < ' tcx , Vec < FnArg < ' tcx , M :: Provenance > > > {
376- ops. iter ( )
377- . map ( |op| {
378- let arg = match & op. node {
379- mir:: Operand :: Copy ( _) | mir:: Operand :: Constant ( _) => {
380- // Make a regular copy.
381- let op = self . eval_operand ( & op. node , None ) ?;
374+ op : & mir:: Operand < ' tcx > ,
375+ ) -> InterpResult < ' tcx , FnArg < ' tcx , M :: Provenance > > {
376+ Ok ( match op {
377+ mir:: Operand :: Copy ( _) | mir:: Operand :: Constant ( _) => {
378+ // Make a regular copy.
379+ let op = self . eval_operand ( op, None ) ?;
380+ FnArg :: Copy ( op)
381+ }
382+ mir:: Operand :: Move ( place) => {
383+ // If this place lives in memory, preserve its location.
384+ // We call `place_to_op` which will be an `MPlaceTy` whenever there exists
385+ // an mplace for this place. (This is in contrast to `PlaceTy::as_mplace_or_local`
386+ // which can return a local even if that has an mplace.)
387+ let place = self . eval_place ( * place) ?;
388+ let op = self . place_to_op ( & place) ?;
389+
390+ match op. as_mplace_or_imm ( ) {
391+ Either :: Left ( mplace) => FnArg :: InPlace ( mplace) ,
392+ Either :: Right ( _imm) => {
393+ // This argument doesn't live in memory, so there's no place
394+ // to make inaccessible during the call.
395+ // We rely on there not being any stray `PlaceTy` that would let the
396+ // caller directly access this local!
397+ // This is also crucial for tail calls, where we want the `FnArg` to
398+ // stay valid when the old stack frame gets popped.
382399 FnArg :: Copy ( op)
383400 }
384- mir:: Operand :: Move ( place) => {
385- // If this place lives in memory, preserve its location.
386- // We call `place_to_op` which will be an `MPlaceTy` whenever there exists
387- // an mplace for this place. (This is in contrast to `PlaceTy::as_mplace_or_local`
388- // which can return a local even if that has an mplace.)
389- let place = self . eval_place ( * place) ?;
390- let op = self . place_to_op ( & place) ?;
391-
392- match op. as_mplace_or_imm ( ) {
393- Either :: Left ( mplace) => FnArg :: InPlace ( mplace) ,
394- Either :: Right ( _imm) => {
395- // This argument doesn't live in memory, so there's no place
396- // to make inaccessible during the call.
397- // We rely on there not being any stray `PlaceTy` that would let the
398- // caller directly access this local!
399- // This is also crucial for tail calls, where we want the `FnArg` to
400- // stay valid when the old stack frame gets popped.
401- FnArg :: Copy ( op)
402- }
403- }
404- }
405- } ;
406-
407- Ok ( arg)
408- } )
409- . collect ( )
401+ }
402+ }
403+ } )
410404 }
411405
412406 /// Shared part of `Call` and `TailCall` implementation — finding and evaluating all the
@@ -418,7 +412,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
418412 args : & [ Spanned < mir:: Operand < ' tcx > > ] ,
419413 ) -> InterpResult < ' tcx , EvaluatedCalleeAndArgs < ' tcx , M > > {
420414 let func = self . eval_operand ( func, None ) ?;
421- let args = self . eval_fn_call_arguments ( args) ?;
415+ let args = args
416+ . iter ( )
417+ . map ( |arg| self . eval_fn_call_argument ( & arg. node ) )
418+ . collect :: < InterpResult < ' tcx , Vec < _ > > > ( ) ?;
422419
423420 let fn_sig_binder = func. layout . ty . fn_sig ( * self . tcx ) ;
424421 let fn_sig = self . tcx . normalize_erasing_late_bound_regions ( self . param_env , fn_sig_binder) ;
0 commit comments