@@ -369,44 +369,38 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
369
369
}
370
370
371
371
/// Evaluate the arguments of a function call
372
- fn eval_fn_call_arguments (
372
+ fn eval_fn_call_argument (
373
373
& 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.
382
399
FnArg :: Copy ( op)
383
400
}
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
+ } )
410
404
}
411
405
412
406
/// Shared part of `Call` and `TailCall` implementation — finding and evaluating all the
@@ -418,7 +412,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
418
412
args : & [ Spanned < mir:: Operand < ' tcx > > ] ,
419
413
) -> InterpResult < ' tcx , EvaluatedCalleeAndArgs < ' tcx , M > > {
420
414
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 < _ > > > ( ) ?;
422
419
423
420
let fn_sig_binder = func. layout . ty . fn_sig ( * self . tcx ) ;
424
421
let fn_sig = self . tcx . normalize_erasing_late_bound_regions ( self . param_env , fn_sig_binder) ;
0 commit comments