@@ -118,7 +118,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
118
118
let mut drops = Vec :: new ( ) ;
119
119
self . drop ( lval, ty, & mut drops) ?;
120
120
self . goto_block ( target) ;
121
- self . eval_drop_impls ( drops) ?;
121
+ self . eval_drop_impls ( drops, terminator . source_info . span ) ?;
122
122
}
123
123
124
124
Assert { ref cond, expected, ref msg, target, .. } => {
@@ -151,12 +151,10 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
151
151
Ok ( ( ) )
152
152
}
153
153
154
- pub fn eval_drop_impls ( & mut self , drops : Vec < ( DefId , Value , & ' tcx Substs < ' tcx > ) > ) -> EvalResult < ' tcx , ( ) > {
155
- let span = self . frame ( ) . span ;
154
+ pub fn eval_drop_impls ( & mut self , drops : Vec < ( DefId , Value , & ' tcx Substs < ' tcx > ) > , span : Span ) -> EvalResult < ' tcx , ( ) > {
156
155
// add them to the stack in reverse order, because the impl that needs to run the last
157
156
// is the one that needs to be at the bottom of the stack
158
157
for ( drop_def_id, self_arg, substs) in drops. into_iter ( ) . rev ( ) {
159
- // FIXME: supply a real span
160
158
let mir = self . load_mir ( drop_def_id) ?;
161
159
trace ! ( "substs for drop glue: {:?}" , substs) ;
162
160
self . push_stack_frame (
@@ -166,6 +164,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
166
164
substs,
167
165
Lvalue :: from_ptr ( Pointer :: zst_ptr ( ) ) ,
168
166
StackPopCleanup :: None ,
167
+ Vec :: new ( ) ,
169
168
) ?;
170
169
let mut arg_locals = self . frame ( ) . mir . args_iter ( ) ;
171
170
let first = arg_locals. next ( ) . expect ( "drop impl has self arg" ) ;
@@ -213,11 +212,11 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
213
212
}
214
213
215
214
// Only trait methods can have a Self parameter.
216
- let ( resolved_def_id, resolved_substs) =
215
+ let ( resolved_def_id, resolved_substs, temporaries ) =
217
216
if let Some ( trait_id) = self . tcx . trait_of_item ( def_id) {
218
217
self . trait_method ( trait_id, def_id, substs, & mut args) ?
219
218
} else {
220
- ( def_id, substs)
219
+ ( def_id, substs, Vec :: new ( ) )
221
220
} ;
222
221
223
222
let mir = self . load_mir ( resolved_def_id) ?;
@@ -237,6 +236,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
237
236
resolved_substs,
238
237
return_lvalue,
239
238
return_to_block,
239
+ temporaries,
240
240
) ?;
241
241
242
242
let arg_locals = self . frame ( ) . mir . args_iter ( ) ;
@@ -432,7 +432,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
432
432
def_id : DefId ,
433
433
substs : & ' tcx Substs < ' tcx > ,
434
434
args : & mut Vec < ( Value , Ty < ' tcx > ) > ,
435
- ) -> EvalResult < ' tcx , ( DefId , & ' tcx Substs < ' tcx > ) > {
435
+ ) -> EvalResult < ' tcx , ( DefId , & ' tcx Substs < ' tcx > , Vec < Pointer > ) > {
436
436
let trait_ref = ty:: TraitRef :: from_method ( self . tcx , trait_id, substs) ;
437
437
let trait_ref = self . tcx . normalize_associated_type ( & ty:: Binder ( trait_ref) ) ;
438
438
@@ -444,7 +444,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
444
444
// and those from the method:
445
445
let ( did, substs) = find_method ( self . tcx , substs, impl_did, vtable_impl. substs , mname) ;
446
446
447
- Ok ( ( did, substs) )
447
+ Ok ( ( did, substs, Vec :: new ( ) ) )
448
448
}
449
449
450
450
traits:: VtableClosure ( vtable_closure) => {
@@ -455,6 +455,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
455
455
let closure_kind = self . tcx . closure_kind ( vtable_closure. closure_def_id ) ;
456
456
trace ! ( "closures {:?}, {:?}" , closure_kind, trait_closure_kind) ;
457
457
self . unpack_fn_args ( args) ?;
458
+ let mut temporaries = Vec :: new ( ) ;
458
459
match ( closure_kind, trait_closure_kind) {
459
460
( ty:: ClosureKind :: Fn , ty:: ClosureKind :: Fn ) |
460
461
( ty:: ClosureKind :: FnMut , ty:: ClosureKind :: FnMut ) |
@@ -474,23 +475,36 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
474
475
475
476
// Interpreter magic: insert an intermediate pointer, so we can skip the
476
477
// intermediate function call.
477
- // FIXME: this is a memory leak, should probably add the pointer to the
478
- // current stack.
479
- let first = self . value_to_ptr_dont_use ( args[ 0 ] . 0 , args[ 0 ] . 1 ) ?;
480
- 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 ( 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 ( ptr) ;
491
+ ptr
492
+ } ,
493
+ } ;
494
+ args[ 0 ] . 0 = Value :: ByVal ( PrimVal :: from_ptr ( ptr) ) ;
481
495
args[ 0 ] . 1 = self . tcx . mk_mut_ptr ( args[ 0 ] . 1 ) ;
482
496
}
483
497
484
498
_ => bug ! ( "cannot convert {:?} to {:?}" , closure_kind, trait_closure_kind) ,
485
499
}
486
- Ok ( ( vtable_closure. closure_def_id , vtable_closure. substs . substs ) )
500
+ Ok ( ( vtable_closure. closure_def_id , vtable_closure. substs . substs , temporaries ) )
487
501
}
488
502
489
503
traits:: VtableFnPointer ( vtable_fn_ptr) => {
490
504
if let ty:: TyFnDef ( did, ref substs, _) = vtable_fn_ptr. fn_ty . sty {
491
505
args. remove ( 0 ) ;
492
506
self . unpack_fn_args ( args) ?;
493
- Ok ( ( did, substs) )
507
+ Ok ( ( did, substs, Vec :: new ( ) ) )
494
508
} else {
495
509
bug ! ( "VtableFnPointer did not contain a concrete function: {:?}" , vtable_fn_ptr)
496
510
}
@@ -506,7 +520,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
506
520
let fn_ptr = self . memory . read_ptr ( vtable. offset ( offset) ) ?;
507
521
let ( def_id, substs, _abi, sig) = self . memory . get_fn ( fn_ptr. alloc_id ) ?;
508
522
* first_ty = sig. inputs [ 0 ] ;
509
- Ok ( ( def_id, substs) )
523
+ Ok ( ( def_id, substs, Vec :: new ( ) ) )
510
524
} else {
511
525
Err ( EvalError :: VtableForArgumentlessMethod )
512
526
}
0 commit comments