@@ -164,6 +164,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
164
164
substs,
165
165
Lvalue :: from_ptr ( Pointer :: zst_ptr ( ) ) ,
166
166
StackPopCleanup :: None ,
167
+ Vec :: new ( ) ,
167
168
) ?;
168
169
let mut arg_locals = self . frame ( ) . mir . args_iter ( ) ;
169
170
let first = arg_locals. next ( ) . expect ( "drop impl has self arg" ) ;
@@ -211,11 +212,11 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
211
212
}
212
213
213
214
// Only trait methods can have a Self parameter.
214
- let ( resolved_def_id, resolved_substs) =
215
+ let ( resolved_def_id, resolved_substs, temporaries ) =
215
216
if let Some ( trait_id) = self . tcx . trait_of_item ( def_id) {
216
217
self . trait_method ( trait_id, def_id, substs, & mut args) ?
217
218
} else {
218
- ( def_id, substs)
219
+ ( def_id, substs, Vec :: new ( ) )
219
220
} ;
220
221
221
222
let mir = self . load_mir ( resolved_def_id) ?;
@@ -235,6 +236,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
235
236
resolved_substs,
236
237
return_lvalue,
237
238
return_to_block,
239
+ temporaries,
238
240
) ?;
239
241
240
242
let arg_locals = self . frame ( ) . mir . args_iter ( ) ;
@@ -430,7 +432,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
430
432
def_id : DefId ,
431
433
substs : & ' tcx Substs < ' tcx > ,
432
434
args : & mut Vec < ( Value , Ty < ' tcx > ) > ,
433
- ) -> EvalResult < ' tcx , ( DefId , & ' tcx Substs < ' tcx > ) > {
435
+ ) -> EvalResult < ' tcx , ( DefId , & ' tcx Substs < ' tcx > , Vec < Value > ) > {
434
436
let trait_ref = ty:: TraitRef :: from_method ( self . tcx , trait_id, substs) ;
435
437
let trait_ref = self . tcx . normalize_associated_type ( & ty:: Binder ( trait_ref) ) ;
436
438
@@ -442,7 +444,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
442
444
// and those from the method:
443
445
let ( did, substs) = find_method ( self . tcx , substs, impl_did, vtable_impl. substs , mname) ;
444
446
445
- Ok ( ( did, substs) )
447
+ Ok ( ( did, substs, Vec :: new ( ) ) )
446
448
}
447
449
448
450
traits:: VtableClosure ( vtable_closure) => {
@@ -453,6 +455,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
453
455
let closure_kind = self . tcx . closure_kind ( vtable_closure. closure_def_id ) ;
454
456
trace ! ( "closures {:?}, {:?}" , closure_kind, trait_closure_kind) ;
455
457
self . unpack_fn_args ( args) ?;
458
+ let mut temporaries = Vec :: new ( ) ;
456
459
match ( closure_kind, trait_closure_kind) {
457
460
( ty:: ClosureKind :: Fn , ty:: ClosureKind :: Fn ) |
458
461
( ty:: ClosureKind :: FnMut , ty:: ClosureKind :: FnMut ) |
@@ -472,23 +475,36 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
472
475
473
476
// Interpreter magic: insert an intermediate pointer, so we can skip the
474
477
// intermediate function call.
475
- // FIXME: this is a memory leak, should probably add the pointer to the
476
- // current stack.
477
- let first = self . value_to_ptr_dont_use ( args[ 0 ] . 0 , args[ 0 ] . 1 ) ?;
478
- args[ 0 ] . 0 = Value :: ByVal ( PrimVal :: from_ptr ( first) ) ;
478
+ let ptr = match args[ 0 ] . 0 {
479
+ Value :: ByRef ( ptr) => ptr,
480
+ Value :: ByVal ( primval) => {
481
+ let ptr = self . alloc_ptr ( args[ 0 ] . 1 ) ?;
482
+ let kind = self . ty_to_primval_kind ( args[ 0 ] . 1 ) ?;
483
+ self . memory . write_primval ( ptr, primval, kind) ?;
484
+ temporaries. push ( Value :: ByRef ( ptr) ) ;
485
+ ptr
486
+ } ,
487
+ Value :: ByValPair ( a, b) => {
488
+ let ptr = self . alloc_ptr ( args[ 0 ] . 1 ) ?;
489
+ self . write_pair_to_ptr ( a, b, ptr, args[ 0 ] . 1 ) ?;
490
+ temporaries. push ( Value :: ByRef ( ptr) ) ;
491
+ ptr
492
+ } ,
493
+ } ;
494
+ args[ 0 ] . 0 = Value :: ByVal ( PrimVal :: from_ptr ( ptr) ) ;
479
495
args[ 0 ] . 1 = self . tcx . mk_mut_ptr ( args[ 0 ] . 1 ) ;
480
496
}
481
497
482
498
_ => bug ! ( "cannot convert {:?} to {:?}" , closure_kind, trait_closure_kind) ,
483
499
}
484
- Ok ( ( vtable_closure. closure_def_id , vtable_closure. substs . substs ) )
500
+ Ok ( ( vtable_closure. closure_def_id , vtable_closure. substs . substs , temporaries ) )
485
501
}
486
502
487
503
traits:: VtableFnPointer ( vtable_fn_ptr) => {
488
504
if let ty:: TyFnDef ( did, ref substs, _) = vtable_fn_ptr. fn_ty . sty {
489
505
args. remove ( 0 ) ;
490
506
self . unpack_fn_args ( args) ?;
491
- Ok ( ( did, substs) )
507
+ Ok ( ( did, substs, Vec :: new ( ) ) )
492
508
} else {
493
509
bug ! ( "VtableFnPointer did not contain a concrete function: {:?}" , vtable_fn_ptr)
494
510
}
@@ -504,7 +520,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
504
520
let fn_ptr = self . memory . read_ptr ( vtable. offset ( offset) ) ?;
505
521
let ( def_id, substs, _abi, sig) = self . memory . get_fn ( fn_ptr. alloc_id ) ?;
506
522
* first_ty = sig. inputs [ 0 ] ;
507
- Ok ( ( def_id, substs) )
523
+ Ok ( ( def_id, substs, Vec :: new ( ) ) )
508
524
} else {
509
525
Err ( EvalError :: VtableForArgumentlessMethod )
510
526
}
0 commit comments