@@ -4,7 +4,7 @@ use rustc::ty::layout::LayoutOf;
4
4
use syntax:: codemap:: Span ;
5
5
use rustc_target:: spec:: abi:: Abi ;
6
6
7
- use rustc:: mir:: interpret:: { EvalResult , Scalar , Value } ;
7
+ use rustc:: mir:: interpret:: { EvalResult , Value } ;
8
8
use super :: { EvalContext , Place , Machine , ValTy } ;
9
9
10
10
use rustc_data_structures:: indexed_vec:: Idx ;
@@ -338,65 +338,39 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
338
338
339
339
// unpack and write all other args
340
340
let layout = self . layout_of ( args[ 1 ] . ty ) ?;
341
- if let ty:: TyTuple ( ..) = args[ 1 ] . ty . sty {
341
+ if let ty:: TyTuple ( _) = args[ 1 ] . ty . sty {
342
+ if layout. is_zst ( ) {
343
+ // Nothing to do, no need to unpack zsts
344
+ return Ok ( ( ) ) ;
345
+ }
342
346
if self . frame ( ) . mir . args_iter ( ) . count ( ) == layout. fields . count ( ) + 1 {
343
- match args[ 1 ] . value {
344
- Value :: ByRef ( ptr, align) => {
345
- for ( i, arg_local) in arg_locals. enumerate ( ) {
346
- let field = layout. field ( & self , i) ?;
347
- let offset = layout. fields . offset ( i) ;
348
- let arg = Value :: ByRef ( ptr. ptr_offset ( offset, & self ) ?,
349
- align. min ( field. align ) ) ;
350
- let dest =
351
- self . eval_place ( & mir:: Place :: Local ( arg_local) ) ?;
352
- trace ! (
353
- "writing arg {:?} to {:?} (type: {})" ,
354
- arg,
355
- dest,
356
- field. ty
357
- ) ;
358
- let valty = ValTy {
359
- value : arg,
360
- ty : field. ty ,
361
- } ;
362
- self . write_value ( valty, dest) ?;
363
- }
364
- }
365
- Value :: Scalar ( Scalar :: Bits { defined : 0 , .. } ) => { }
366
- other => {
367
- trace ! ( "{:#?}, {:#?}" , other, layout) ;
368
- let mut layout = layout;
369
- ' outer: loop {
370
- for i in 0 ..layout. fields . count ( ) {
371
- let field = layout. field ( & self , i) ?;
372
- if layout. fields . offset ( i) . bytes ( ) == 0 && layout. size == field. size {
373
- layout = field;
374
- continue ' outer;
375
- }
376
- }
377
- break ;
378
- }
379
- {
380
- let mut write_next = |value| {
381
- let dest = self . eval_place ( & mir:: Place :: Local (
382
- arg_locals. next ( ) . unwrap ( ) ,
383
- ) ) ?;
384
- let valty = ValTy {
385
- value : Value :: Scalar ( value) ,
386
- ty : layout. ty ,
387
- } ;
388
- self . write_value ( valty, dest)
389
- } ;
390
- match other {
391
- Value :: Scalar ( value) | Value :: ScalarPair ( value, _) => write_next ( value) ?,
392
- _ => unreachable ! ( ) ,
393
- }
394
- if let Value :: ScalarPair ( _, value) = other {
395
- write_next ( value) ?;
396
- }
397
- }
398
- assert ! ( arg_locals. next( ) . is_none( ) ) ;
347
+ for ( i, arg_local) in arg_locals. enumerate ( ) {
348
+ let field = layout. field ( & self , i) ?;
349
+ if field. is_zst ( ) {
350
+ continue ;
399
351
}
352
+ let offset = layout. fields . offset ( i) ;
353
+ let value = match args[ 1 ] . value {
354
+ Value :: ByRef ( ptr, align) => Value :: ByRef (
355
+ ptr. ptr_offset ( offset, & self ) ?,
356
+ align. min ( field. align ) ,
357
+ ) ,
358
+ other if field. size == layout. size => {
359
+ // this is the case where the field covers the entire type
360
+ assert_eq ! ( offset. bytes( ) , 0 ) ;
361
+ other
362
+ } ,
363
+ Value :: ScalarPair ( a, _) if offset. bytes ( ) == 0 => Value :: Scalar ( a) ,
364
+ Value :: ScalarPair ( _, b) => Value :: Scalar ( b) ,
365
+ Value :: Scalar ( _) => bug ! ( "Scalar does not cover entire type" ) ,
366
+ } ;
367
+ let dest =
368
+ self . eval_place ( & mir:: Place :: Local ( arg_local) ) ?;
369
+ let valty = ValTy {
370
+ value,
371
+ ty : field. ty ,
372
+ } ;
373
+ self . write_value ( valty, dest) ?;
400
374
}
401
375
} else {
402
376
trace ! ( "manual impl of rust-call ABI" ) ;
0 commit comments