@@ -350,21 +350,21 @@ fn trans_type_impl<'tcx>(
350
350
}
351
351
. def_with_name ( cx, span, TyLayoutNameKey :: from ( ty) ) ,
352
352
Abi :: Scalar ( ref scalar) => trans_scalar ( cx, span, ty, scalar, None , is_immediate) ,
353
- Abi :: ScalarPair ( ref one, ref two) => {
354
- // Note! Do not pass through is_immediate here - they're wrapped in a struct, hence, not immediate.
355
- let one_spirv = trans_scalar ( cx, span, ty, one, Some ( 0 ) , false ) ;
356
- let two_spirv = trans_scalar ( cx, span, ty, two, Some ( 1 ) , false ) ;
353
+ Abi :: ScalarPair ( ref a, ref b) => {
357
354
// Note: We can't use auto_struct_layout here because the spirv types here might be undefined due to
358
355
// recursive pointer types.
359
- let one_offset = Size :: ZERO ;
360
- let two_offset = one. value . size ( cx) . align_to ( two. value . align ( cx) . abi ) ;
356
+ let a_offset = Size :: ZERO ;
357
+ let b_offset = a. value . size ( cx) . align_to ( b. value . align ( cx) . abi ) ;
358
+ // Note! Do not pass through is_immediate here - they're wrapped in a struct, hence, not immediate.
359
+ let a = trans_scalar ( cx, span, ty, a, Some ( a_offset) , false ) ;
360
+ let b = trans_scalar ( cx, span, ty, b, Some ( b_offset) , false ) ;
361
361
let size = if ty. is_unsized ( ) { None } else { Some ( ty. size ) } ;
362
362
SpirvType :: Adt {
363
363
def_id : def_id_for_spirv_type_adt ( ty) ,
364
364
size,
365
365
align : ty. align . abi ,
366
- field_types : vec ! [ one_spirv , two_spirv ] ,
367
- field_offsets : vec ! [ one_offset , two_offset ] ,
366
+ field_types : vec ! [ a , b ] ,
367
+ field_offsets : vec ! [ a_offset , b_offset ] ,
368
368
field_names : None ,
369
369
}
370
370
. def_with_name ( cx, span, TyLayoutNameKey :: from ( ty) )
@@ -390,11 +390,16 @@ pub fn scalar_pair_element_backend_type<'tcx>(
390
390
index : usize ,
391
391
is_immediate : bool ,
392
392
) -> Word {
393
- let scalar = match & ty. layout . abi {
394
- Abi :: ScalarPair ( a, b) => [ a, b] [ index ] ,
393
+ let [ a , b ] = match & ty. layout . abi {
394
+ Abi :: ScalarPair ( a, b) => [ a, b] ,
395
395
other => bug ! ( "scalar_pair_element_backend_type invalid abi: {:?}" , other) ,
396
396
} ;
397
- trans_scalar ( cx, span, ty, scalar, Some ( index) , is_immediate)
397
+ let offset = match index {
398
+ 0 => Size :: ZERO ,
399
+ 1 => a. value . size ( cx) . align_to ( b. value . align ( cx) . abi ) ,
400
+ _ => unreachable ! ( ) ,
401
+ } ;
402
+ trans_scalar ( cx, span, ty, [ a, b] [ index] , Some ( offset) , is_immediate)
398
403
}
399
404
400
405
/// A "scalar" is a basic building block: bools, ints, floats, pointers. (i.e. not something complex like a struct)
@@ -409,7 +414,7 @@ fn trans_scalar<'tcx>(
409
414
span : Span ,
410
415
ty : TyAndLayout < ' tcx > ,
411
416
scalar : & Scalar ,
412
- scalar_pair_field_index : Option < usize > ,
417
+ scalar_pair_field_offset : Option < Size > ,
413
418
is_immediate : bool ,
414
419
) -> Word {
415
420
if is_immediate && scalar. is_bool ( ) {
@@ -423,7 +428,7 @@ fn trans_scalar<'tcx>(
423
428
Primitive :: F32 => SpirvType :: Float ( 32 ) . def ( span, cx) ,
424
429
Primitive :: F64 => SpirvType :: Float ( 64 ) . def ( span, cx) ,
425
430
Primitive :: Pointer => {
426
- let pointee_ty = dig_scalar_pointee ( cx, ty, scalar_pair_field_index ) ;
431
+ let pointee_ty = dig_scalar_pointee ( cx, ty, scalar_pair_field_offset ) ;
427
432
// Pointers can be recursive. So, record what we're currently translating, and if we're already translating
428
433
// the same type, emit an OpTypeForwardPointer and use that ID.
429
434
if let Some ( predefined_result) = cx
@@ -455,16 +460,21 @@ fn trans_scalar<'tcx>(
455
460
fn dig_scalar_pointee < ' tcx > (
456
461
cx : & CodegenCx < ' tcx > ,
457
462
ty : TyAndLayout < ' tcx > ,
458
- scalar_pair_field_index : Option < usize > ,
463
+ scalar_pair_field_offset : Option < Size > ,
459
464
) -> PointeeTy < ' tcx > {
460
465
match * ty. ty . kind ( ) {
461
466
TyKind :: Ref ( _, elem_ty, _) | TyKind :: RawPtr ( TypeAndMut { ty : elem_ty, .. } ) => {
462
467
let elem = cx. layout_of ( elem_ty) ;
463
- match scalar_pair_field_index {
468
+ match scalar_pair_field_offset {
464
469
None => PointeeTy :: Ty ( elem) ,
465
- Some ( scalar_pair_field_index ) => {
470
+ Some ( scalar_pair_field_offset ) => {
466
471
if elem. is_unsized ( ) {
467
- dig_scalar_pointee ( cx, ty. field ( cx, scalar_pair_field_index) , None )
472
+ let field_idx = if scalar_pair_field_offset == Size :: ZERO {
473
+ 0
474
+ } else {
475
+ 1
476
+ } ;
477
+ dig_scalar_pointee ( cx, ty. field ( cx, field_idx) , None )
468
478
} else {
469
479
// This can sometimes happen in weird cases when going through the Adt case below - an ABI
470
480
// of ScalarPair could be deduced, but it's actually e.g. a sized pointer followed by some other
@@ -475,25 +485,25 @@ fn dig_scalar_pointee<'tcx>(
475
485
}
476
486
}
477
487
}
478
- TyKind :: FnPtr ( sig) if scalar_pair_field_index . is_none ( ) => PointeeTy :: Fn ( sig) ,
488
+ TyKind :: FnPtr ( sig) if scalar_pair_field_offset . is_none ( ) => PointeeTy :: Fn ( sig) ,
479
489
TyKind :: Adt ( def, _) if def. is_box ( ) => {
480
490
let ptr_ty = cx. layout_of ( cx. tcx . mk_mut_ptr ( ty. ty . boxed_ty ( ) ) ) ;
481
- dig_scalar_pointee ( cx, ptr_ty, scalar_pair_field_index )
491
+ dig_scalar_pointee ( cx, ptr_ty, scalar_pair_field_offset )
482
492
}
483
493
TyKind :: Tuple ( _) | TyKind :: Adt ( ..) | TyKind :: Closure ( ..) => {
484
- dig_scalar_pointee_adt ( cx, ty, scalar_pair_field_index )
494
+ dig_scalar_pointee_adt ( cx, ty, scalar_pair_field_offset )
485
495
}
486
496
ref kind => cx. tcx . sess . fatal ( & format ! (
487
- "TODO: Unimplemented Primitive::Pointer TyKind scalar_pair_field_index ={:?} ({:#?}):\n {:#?}" ,
488
- scalar_pair_field_index , kind, ty
497
+ "TODO: Unimplemented Primitive::Pointer TyKind scalar_pair_field_offset ={:?} ({:#?}):\n {:#?}" ,
498
+ scalar_pair_field_offset , kind, ty
489
499
) ) ,
490
500
}
491
501
}
492
502
493
503
fn dig_scalar_pointee_adt < ' tcx > (
494
504
cx : & CodegenCx < ' tcx > ,
495
505
ty : TyAndLayout < ' tcx > ,
496
- scalar_pair_field_index : Option < usize > ,
506
+ scalar_pair_field_offset : Option < Size > ,
497
507
) -> PointeeTy < ' tcx > {
498
508
match & ty. variants {
499
509
// If it's a Variants::Multiple, then we want to emit the type of the dataful variant, not the type of the
@@ -519,7 +529,7 @@ fn dig_scalar_pointee_adt<'tcx>(
519
529
assert_eq ! ( 1 , adt. variants[ dataful_variant] . fields. len( ) ) ;
520
530
assert_eq ! ( 0 , * tag_field) ;
521
531
let field_ty = adt. variants [ dataful_variant] . fields [ 0 ] . ty ( cx. tcx , substs) ;
522
- dig_scalar_pointee ( cx, cx. layout_of ( field_ty) , scalar_pair_field_index )
532
+ dig_scalar_pointee ( cx, cx. layout_of ( field_ty) , scalar_pair_field_offset )
523
533
} else {
524
534
bug ! ( "Variants::Multiple not TyKind::Adt: {:#?}" , ty)
525
535
}
@@ -533,11 +543,18 @@ fn dig_scalar_pointee_adt<'tcx>(
533
543
. map ( |f| ty. field ( cx, f) )
534
544
. filter ( |f| !f. is_zst ( ) )
535
545
. collect :: < Vec < _ > > ( ) ;
536
- match scalar_pair_field_index {
537
- Some ( scalar_pair_field_index ) => match fields. len ( ) {
538
- 1 => dig_scalar_pointee ( cx, fields[ 0 ] , Some ( scalar_pair_field_index ) ) ,
546
+ match scalar_pair_field_offset {
547
+ Some ( scalar_pair_field_offset ) => match fields. len ( ) {
548
+ 1 => dig_scalar_pointee ( cx, fields[ 0 ] , Some ( scalar_pair_field_offset ) ) ,
539
549
// This case right here is the cause of the comment handling TyKind::Ref.
540
- 2 => dig_scalar_pointee ( cx, fields[ scalar_pair_field_index] , None ) ,
550
+ 2 => {
551
+ let field_idx = if scalar_pair_field_offset == Size :: ZERO {
552
+ 0
553
+ } else {
554
+ 1
555
+ } ;
556
+ dig_scalar_pointee ( cx, fields[ field_idx] , None )
557
+ }
541
558
other => cx. tcx . sess . fatal ( & format ! (
542
559
"Unable to dig scalar pair pointer type: fields length {}" ,
543
560
other
0 commit comments