@@ -40,7 +40,7 @@ pub trait LayoutCalculator {
4040 largest_niche,
4141 align,
4242 size,
43- repr_align : None ,
43+ max_repr_align : None ,
4444 unadjusted_abi_align : align. abi ,
4545 }
4646 }
@@ -124,7 +124,7 @@ pub trait LayoutCalculator {
124124 largest_niche : None ,
125125 align : dl. i8_align ,
126126 size : Size :: ZERO ,
127- repr_align : None ,
127+ max_repr_align : None ,
128128 unadjusted_abi_align : dl. i8_align . abi ,
129129 }
130130 }
@@ -293,6 +293,7 @@ pub trait LayoutCalculator {
293293 }
294294
295295 let mut align = dl. aggregate_align ;
296+ let mut max_repr_align = repr. align ;
296297 let mut unadjusted_abi_align = align. abi ;
297298
298299 let mut variant_layouts = variants
@@ -302,6 +303,7 @@ pub trait LayoutCalculator {
302303 st. variants = Variants :: Single { index : j } ;
303304
304305 align = align. max ( st. align ) ;
306+ max_repr_align = max_repr_align. max ( st. max_repr_align ) ;
305307 unadjusted_abi_align = unadjusted_abi_align. max ( st. unadjusted_abi_align ) ;
306308
307309 Some ( st)
@@ -429,7 +431,7 @@ pub trait LayoutCalculator {
429431 largest_niche,
430432 size,
431433 align,
432- repr_align : repr . align ,
434+ max_repr_align ,
433435 unadjusted_abi_align,
434436 } ;
435437
@@ -465,6 +467,7 @@ pub trait LayoutCalculator {
465467 let ( min_ity, signed) = discr_range_of_repr ( min, max) ; //Integer::repr_discr(tcx, ty, &repr, min, max);
466468
467469 let mut align = dl. aggregate_align ;
470+ let mut max_repr_align = repr. align ;
468471 let mut unadjusted_abi_align = align. abi ;
469472
470473 let mut size = Size :: ZERO ;
@@ -509,6 +512,7 @@ pub trait LayoutCalculator {
509512 }
510513 size = cmp:: max ( size, st. size ) ;
511514 align = align. max ( st. align ) ;
515+ max_repr_align = max_repr_align. max ( st. max_repr_align ) ;
512516 unadjusted_abi_align = unadjusted_abi_align. max ( st. unadjusted_abi_align ) ;
513517 Some ( st)
514518 } )
@@ -703,7 +707,7 @@ pub trait LayoutCalculator {
703707 abi,
704708 align,
705709 size,
706- repr_align : repr . align ,
710+ max_repr_align ,
707711 unadjusted_abi_align,
708712 } ;
709713
@@ -744,6 +748,7 @@ pub trait LayoutCalculator {
744748 let dl = self . current_data_layout ( ) ;
745749 let dl = dl. borrow ( ) ;
746750 let mut align = if repr. pack . is_some ( ) { dl. i8_align } else { dl. aggregate_align } ;
751+ let mut max_repr_align = repr. align ;
747752
748753 // If all the non-ZST fields have the same ABI and union ABI optimizations aren't
749754 // disabled, we can use that common ABI for the union as a whole.
@@ -761,6 +766,7 @@ pub trait LayoutCalculator {
761766 assert ! ( field. 0 . is_sized( ) ) ;
762767
763768 align = align. max ( field. align ( ) ) ;
769+ max_repr_align = max_repr_align. max ( field. max_repr_align ( ) ) ;
764770 size = cmp:: max ( size, field. size ( ) ) ;
765771
766772 if field. 0 . is_zst ( ) {
@@ -827,7 +833,7 @@ pub trait LayoutCalculator {
827833 largest_niche : None ,
828834 align,
829835 size : size. align_to ( align. abi ) ,
830- repr_align : repr . align ,
836+ max_repr_align ,
831837 unadjusted_abi_align,
832838 } )
833839 }
@@ -849,6 +855,7 @@ fn univariant(
849855) -> Option < LayoutS > {
850856 let pack = repr. pack ;
851857 let mut align = if pack. is_some ( ) { dl. i8_align } else { dl. aggregate_align } ;
858+ let mut max_repr_align = repr. align ;
852859 let mut inverse_memory_index: IndexVec < u32 , FieldIdx > = fields. indices ( ) . collect ( ) ;
853860 let optimize = !repr. inhibit_struct_field_reordering_opt ( ) ;
854861 if optimize && fields. len ( ) > 1 {
@@ -1017,6 +1024,7 @@ fn univariant(
10171024 } ;
10181025 offset = offset. align_to ( field_align. abi ) ;
10191026 align = align. max ( field_align) ;
1027+ max_repr_align = max_repr_align. max ( field. max_repr_align ( ) ) ;
10201028
10211029 debug ! ( "univariant offset: {:?} field: {:#?}" , offset, field) ;
10221030 offsets[ i] = offset;
@@ -1133,28 +1141,16 @@ fn univariant(
11331141 abi = Abi :: Uninhabited ;
11341142 }
11351143
1136- let ( repr_align , unadjusted_abi_align) = if repr. transparent ( ) {
1144+ let unadjusted_abi_align = if repr. transparent ( ) {
11371145 match layout_of_single_non_zst_field {
1138- Some ( l) => ( l . repr_align ( ) , l . unadjusted_abi_align ( ) ) ,
1146+ Some ( l) => l . unadjusted_abi_align ( ) ,
11391147 None => {
11401148 // `repr(transparent)` with all ZST fields.
1141- //
1142- // Using `None` for `repr_align` here is technically incorrect, since one of
1143- // the ZSTs could have `repr(align(1))`. It's an interesting question, if you have
1144- // `#{repr(transparent)] struct Foo((), ZstWithReprAlign1)`, which of those ZSTs'
1145- // ABIs is forwarded by `repr(transparent)`? The answer to that question determines
1146- // whether we should use `None` or `Some(align 1)` here. Thanksfully, two things
1147- // together mean this doesn't matter:
1148- // - You're not allowed to have a `repr(transparent)` struct that contains
1149- // `repr(align)` > 1 ZSTs. See error E0691.
1150- // - MSVC never treats requested align 1 differently from natural align 1.
1151- // (And the `repr_align` field is only used on i686-windows, see `LayoutS` docs.)
1152- // So just use `None` for now.
1153- ( None , align. abi )
1149+ align. abi
11541150 }
11551151 }
11561152 } else {
1157- ( repr . align , unadjusted_abi_align)
1153+ unadjusted_abi_align
11581154 } ;
11591155
11601156 Some ( LayoutS {
@@ -1164,7 +1160,7 @@ fn univariant(
11641160 largest_niche,
11651161 align,
11661162 size,
1167- repr_align ,
1163+ max_repr_align ,
11681164 unadjusted_abi_align,
11691165 } )
11701166}
0 commit comments