@@ -28,9 +28,7 @@ use rustc_span::{Symbol, sym};
2828use tracing:: { debug, instrument, trace} ;
2929use { rustc_abi as abi, rustc_hir as hir} ;
3030
31- use crate :: errors:: {
32- MultipleArrayFieldsSimdType , NonPrimitiveSimdType , OversizedSimdType , ZeroLengthSimdType ,
33- } ;
31+ use crate :: errors:: { NonPrimitiveSimdType , OversizedSimdType , ZeroLengthSimdType } ;
3432
3533mod invariant;
3634
@@ -450,71 +448,26 @@ fn layout_of_uncached<'tcx>(
450448
451449 // SIMD vector types.
452450 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:
464452 //
465- // * #[repr(simd)] struct S(T, T, T, T);
466- // * #[repr(simd)] struct S { x: T, y: T, z: T, w: T }
467453 // * #[repr(simd)] struct S([T; 4])
468454 //
469455 // 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) ) ) ;
516465 } ;
517466
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+
518471 // SIMD vectors of zero length are not supported.
519472 // Additionally, lengths are capped at 2^16 as a fixed maximum backends must
520473 // support.
@@ -559,16 +512,12 @@ fn layout_of_uncached<'tcx>(
559512 } ;
560513 let size = size. align_to ( align. abi ) ;
561514
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-
569515 tcx. mk_layout ( LayoutData {
570516 variants : Variants :: Single { index : FIRST_VARIANT } ,
571- fields,
517+ fields : FieldsShape :: Arbitrary {
518+ offsets : [ Size :: ZERO ] . into ( ) ,
519+ memory_index : [ 0 ] . into ( ) ,
520+ } ,
572521 backend_repr : abi,
573522 largest_niche : e_ly. largest_niche ,
574523 uninhabited : false ,
0 commit comments