@@ -178,9 +178,6 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
178
178
}
179
179
180
180
Abi :: Rust | Abi :: RustCall => {
181
- // TODO(solson): Adjust the first argument when calling a Fn or
182
- // FnMut closure via FnOnce::call_once.
183
-
184
181
let mut arg_srcs = Vec :: new ( ) ;
185
182
for arg in args {
186
183
let src = self . eval_operand_to_ptr ( arg) ?;
@@ -196,25 +193,6 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
196
193
( def_id, substs)
197
194
} ;
198
195
199
- if fn_ty. abi == Abi :: RustCall {
200
- if let Some ( ( last, last_ty) ) = arg_srcs. pop ( ) {
201
- let last_layout = self . type_layout ( last_ty) ;
202
- match ( & last_ty. sty , last_layout) {
203
- ( & ty:: TyTuple ( fields) ,
204
- & Layout :: Univariant { ref variant, .. } ) => {
205
- let offsets = iter:: once ( 0 )
206
- . chain ( variant. offset_after_field . iter ( )
207
- . map ( |s| s. bytes ( ) ) ) ;
208
- for ( offset, ty) in offsets. zip ( fields) {
209
- let src = last. offset ( offset as isize ) ;
210
- arg_srcs. push ( ( src, ty) ) ;
211
- }
212
- }
213
- ty => bug ! ( "expected tuple as last argument in function with 'rust-call' ABI, got {:?}" , ty) ,
214
- }
215
- }
216
- }
217
-
218
196
let mir = self . load_mir ( resolved_def_id) ;
219
197
let ( return_ptr, return_to_block) = match destination {
220
198
Some ( ( ptr, block) ) => ( Some ( ptr) , StackPopCleanup :: Goto ( block) ) ,
@@ -366,6 +344,25 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
366
344
} )
367
345
}
368
346
347
+ fn unpack_fn_args ( & self , args : & mut Vec < ( Pointer , Ty < ' tcx > ) > ) {
348
+ if let Some ( ( last, last_ty) ) = args. pop ( ) {
349
+ let last_layout = self . type_layout ( last_ty) ;
350
+ match ( & last_ty. sty , last_layout) {
351
+ ( & ty:: TyTuple ( fields) ,
352
+ & Layout :: Univariant { ref variant, .. } ) => {
353
+ let offsets = iter:: once ( 0 )
354
+ . chain ( variant. offset_after_field . iter ( )
355
+ . map ( |s| s. bytes ( ) ) ) ;
356
+ for ( offset, ty) in offsets. zip ( fields) {
357
+ let src = last. offset ( offset as isize ) ;
358
+ args. push ( ( src, ty) ) ;
359
+ }
360
+ }
361
+ ty => bug ! ( "expected tuple as last argument in function with 'rust-call' ABI, got {:?}" , ty) ,
362
+ }
363
+ }
364
+ }
365
+
369
366
/// Trait method, which has to be resolved to an impl method.
370
367
fn trait_method (
371
368
& mut self ,
@@ -395,6 +392,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
395
392
. expect ( "The substitutions should have no type parameters remaining after passing through fulfill_obligation" ) ;
396
393
let closure_kind = self . tcx . closure_kind ( vtable_closure. closure_def_id ) ;
397
394
trace ! ( "closures {:?}, {:?}" , closure_kind, trait_closure_kind) ;
395
+ self . unpack_fn_args ( args) ;
398
396
match ( closure_kind, trait_closure_kind) {
399
397
( ty:: ClosureKind :: Fn , ty:: ClosureKind :: Fn ) |
400
398
( ty:: ClosureKind :: FnMut , ty:: ClosureKind :: FnMut ) |
@@ -426,6 +424,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
426
424
traits:: VtableFnPointer ( vtable_fn_ptr) => {
427
425
if let ty:: TyFnDef ( did, ref substs, _) = vtable_fn_ptr. fn_ty . sty {
428
426
args. remove ( 0 ) ;
427
+ self . unpack_fn_args ( args) ;
429
428
Ok ( ( did, substs) )
430
429
} else {
431
430
bug ! ( "VtableFnPointer did not contain a concrete function: {:?}" , vtable_fn_ptr)
0 commit comments