@@ -28,9 +28,7 @@ use rustc_span::{Symbol, sym};
28
28
use tracing:: { debug, instrument, trace} ;
29
29
use { rustc_abi as abi, rustc_hir as hir} ;
30
30
31
- use crate :: errors:: {
32
- MultipleArrayFieldsSimdType , NonPrimitiveSimdType , OversizedSimdType , ZeroLengthSimdType ,
33
- } ;
31
+ use crate :: errors:: { NonPrimitiveSimdType , OversizedSimdType , ZeroLengthSimdType } ;
34
32
35
33
mod invariant;
36
34
@@ -450,71 +448,26 @@ fn layout_of_uncached<'tcx>(
450
448
451
449
// SIMD vector types.
452
450
ty:: Adt ( def, args) if def. repr ( ) . simd ( ) => {
453
- if !def. is_struct ( ) {
454
- // Should have yielded E0517 by now.
455
- let guar = tcx
456
- . dcx ( )
457
- . delayed_bug ( "#[repr(simd)] was applied to an ADT that is not a struct" ) ;
458
- return Err ( error ( cx, LayoutError :: ReferencesError ( guar) ) ) ;
459
- }
460
-
461
- let fields = & def. non_enum_variant ( ) . fields ;
462
-
463
- // Supported SIMD vectors are homogeneous ADTs with at least one field:
451
+ // Supported SIMD vectors are ADTs with a single array field:
464
452
//
465
- // * #[repr(simd)] struct S(T, T, T, T);
466
- // * #[repr(simd)] struct S { x: T, y: T, z: T, w: T }
467
453
// * #[repr(simd)] struct S([T; 4])
468
454
//
469
455
// where T is a primitive scalar (integer/float/pointer).
470
-
471
- // SIMD vectors with zero fields are not supported.
472
- // (should be caught by typeck)
473
- if fields. is_empty ( ) {
474
- tcx. dcx ( ) . emit_fatal ( ZeroLengthSimdType { ty } )
475
- }
476
-
477
- // Type of the first ADT field:
478
- let f0_ty = fields[ FieldIdx :: ZERO ] . ty ( tcx, args) ;
479
-
480
- // Heterogeneous SIMD vectors are not supported:
481
- // (should be caught by typeck)
482
- for fi in fields {
483
- if fi. ty ( tcx, args) != f0_ty {
484
- let guar = tcx. dcx ( ) . delayed_bug (
485
- "#[repr(simd)] was applied to an ADT with heterogeneous field type" ,
486
- ) ;
487
- return Err ( error ( cx, LayoutError :: ReferencesError ( guar) ) ) ;
488
- }
489
- }
490
-
491
- // The element type and number of elements of the SIMD vector
492
- // are obtained from:
493
- //
494
- // * the element type and length of the single array field, if
495
- // the first field is of array type, or
496
- //
497
- // * the homogeneous field type and the number of fields.
498
- let ( e_ty, e_len, is_array) = if let ty:: Array ( e_ty, _) = f0_ty. kind ( ) {
499
- // First ADT field is an array:
500
-
501
- // SIMD vectors with multiple array fields are not supported:
502
- // Can't be caught by typeck with a generic simd type.
503
- if def. non_enum_variant ( ) . fields . len ( ) != 1 {
504
- tcx. dcx ( ) . emit_fatal ( MultipleArrayFieldsSimdType { ty } ) ;
505
- }
506
-
507
- // Extract the number of elements from the layout of the array field:
508
- let FieldsShape :: Array { count, .. } = cx. layout_of ( f0_ty) ?. layout . fields ( ) else {
509
- return Err ( error ( cx, LayoutError :: Unknown ( ty) ) ) ;
510
- } ;
511
-
512
- ( * e_ty, * count, true )
513
- } else {
514
- // First ADT field is not an array:
515
- ( f0_ty, def. non_enum_variant ( ) . fields . len ( ) as _ , false )
456
+ let Some ( ty:: Array ( e_ty, e_len) ) = def
457
+ . is_struct ( )
458
+ . then ( || & def. variant ( FIRST_VARIANT ) . fields )
459
+ . filter ( |fields| fields. len ( ) == 1 )
460
+ . map ( |fields| * fields[ FieldIdx :: ZERO ] . ty ( tcx, args) . kind ( ) )
461
+ else {
462
+ // Invalid SIMD types should have been caught by typeck by now.
463
+ let guar = tcx. dcx ( ) . delayed_bug ( "#[repr(simd)] was applied to an invalid ADT" ) ;
464
+ return Err ( error ( cx, LayoutError :: ReferencesError ( guar) ) ) ;
516
465
} ;
517
466
467
+ let e_len = extract_const_value ( cx, ty, e_len) ?
468
+ . try_to_target_usize ( tcx)
469
+ . ok_or_else ( || error ( cx, LayoutError :: Unknown ( ty) ) ) ?;
470
+
518
471
// SIMD vectors of zero length are not supported.
519
472
// Additionally, lengths are capped at 2^16 as a fixed maximum backends must
520
473
// support.
@@ -559,16 +512,12 @@ fn layout_of_uncached<'tcx>(
559
512
} ;
560
513
let size = size. align_to ( align. abi ) ;
561
514
562
- // Compute the placement of the vector fields:
563
- let fields = if is_array {
564
- FieldsShape :: Arbitrary { offsets : [ Size :: ZERO ] . into ( ) , memory_index : [ 0 ] . into ( ) }
565
- } else {
566
- FieldsShape :: Array { stride : e_ly. size , count : e_len }
567
- } ;
568
-
569
515
tcx. mk_layout ( LayoutData {
570
516
variants : Variants :: Single { index : FIRST_VARIANT } ,
571
- fields,
517
+ fields : FieldsShape :: Arbitrary {
518
+ offsets : [ Size :: ZERO ] . into ( ) ,
519
+ memory_index : [ 0 ] . into ( ) ,
520
+ } ,
572
521
backend_repr : abi,
573
522
largest_niche : e_ly. largest_niche ,
574
523
uninhabited : false ,
0 commit comments