@@ -548,8 +548,12 @@ pub type FieldPath = Vec<u32>;
548548/// A structure, a product type in ADT terms. 
549549#[ derive( PartialEq ,  Eq ,  Hash ,  Debug ) ]  
550550pub  struct  Struct  { 
551+     /// Maximum alignment of fields and repr alignment. 
551552     pub  align :  Align , 
552553
554+     /// Primitive alignment of fields without repr alignment. 
555+      pub  primitive_align :  Align , 
556+ 
553557    /// If true, no alignment padding is used. 
554558     pub  packed :  bool , 
555559
@@ -583,10 +587,20 @@ impl<'a, 'gcx, 'tcx> Struct {
583587    fn  new ( dl :  & TargetDataLayout ,  fields :  & Vec < & ' a  Layout > , 
584588                  repr :  & ReprOptions ,  kind :  StructKind , 
585589                  scapegoat :  Ty < ' gcx > )  -> Result < Struct ,  LayoutError < ' gcx > >  { 
586-         let  packed = repr. packed ( ) ; 
590+         if  repr. packed ( )  && repr. align  > 0  { 
591+             bug ! ( "Struct cannot be packed and aligned" ) ; 
592+         } 
593+ 
594+         let  align = if  repr. packed ( )  { 
595+             dl. i8_align 
596+         }  else  { 
597+             dl. aggregate_align 
598+         } ; 
599+ 
587600        let  mut  ret = Struct  { 
588-             align :  if  packed {  dl. i8_align  }  else  {  dl. aggregate_align  } , 
589-             packed :  packed, 
601+             align :  align, 
602+             primitive_align :  align, 
603+             packed :  repr. packed ( ) , 
590604            sized :  true , 
591605            offsets :  vec ! [ ] , 
592606            memory_index :  vec ! [ ] , 
@@ -660,7 +674,9 @@ impl<'a, 'gcx, 'tcx> Struct {
660674            // Invariant: offset < dl.obj_size_bound() <= 1<<61 
661675            if  !ret. packed  { 
662676                let  align = field. align ( dl) ; 
677+                 let  primitive_align = field. primitive_align ( dl) ; 
663678                ret. align  = ret. align . max ( align) ; 
679+                 ret. primitive_align  = ret. primitive_align . max ( primitive_align) ; 
664680                offset = offset. abi_align ( align) ; 
665681            } 
666682
@@ -671,6 +687,11 @@ impl<'a, 'gcx, 'tcx> Struct {
671687                           . map_or ( Err ( LayoutError :: SizeOverflow ( scapegoat) ) ,  Ok ) ?; 
672688        } 
673689
690+         if  repr. align  > 0  { 
691+             let  repr_align = repr. align  as  u64 ; 
692+             ret. align  = ret. align . max ( Align :: from_bytes ( repr_align,  repr_align) . unwrap ( ) ) ; 
693+             debug ! ( "Struct::new repr_align: {:?}" ,  repr_align) ; 
694+         } 
674695
675696        debug ! ( "Struct::new min_size: {:?}" ,  offset) ; 
676697        ret. min_size  = offset; 
@@ -836,12 +857,23 @@ impl<'a, 'gcx, 'tcx> Struct {
836857        } 
837858        Ok ( None ) 
838859    } 
860+ 
861+     pub  fn  over_align ( & self )  -> Option < u32 >  { 
862+         let  align = self . align . abi ( ) ; 
863+         let  primitive_align = self . primitive_align . abi ( ) ; 
864+         if  align > primitive_align { 
865+             Some ( align as  u32 ) 
866+         }  else  { 
867+             None 
868+         } 
869+     } 
839870} 
840871
841872/// An untagged union. 
842873#[ derive( PartialEq ,  Eq ,  Hash ,  Debug ) ]  
843874pub  struct  Union  { 
844875    pub  align :  Align , 
876+     pub  primitive_align :  Align , 
845877
846878    pub  min_size :  Size , 
847879
@@ -851,8 +883,10 @@ pub struct Union {
851883
852884impl < ' a ,  ' gcx ,  ' tcx >  Union  { 
853885    fn  new ( dl :  & TargetDataLayout ,  packed :  bool )  -> Union  { 
886+         let  align = if  packed {  dl. i8_align  }  else  {  dl. aggregate_align  } ; 
854887        Union  { 
855-             align :  if  packed {  dl. i8_align  }  else  {  dl. aggregate_align  } , 
888+             align :  align, 
889+             primitive_align :  align, 
856890            min_size :  Size :: from_bytes ( 0 ) , 
857891            packed :  packed, 
858892        } 
@@ -875,6 +909,7 @@ impl<'a, 'gcx, 'tcx> Union {
875909
876910            if  !self . packed  { 
877911                self . align  = self . align . max ( field. align ( dl) ) ; 
912+                 self . primitive_align  = self . primitive_align . max ( field. primitive_align ( dl) ) ; 
878913            } 
879914            self . min_size  = cmp:: max ( self . min_size ,  field. size ( dl) ) ; 
880915        } 
@@ -888,6 +923,16 @@ impl<'a, 'gcx, 'tcx> Union {
888923     pub  fn  stride ( & self )  -> Size  { 
889924        self . min_size . abi_align ( self . align ) 
890925    } 
926+ 
927+     pub  fn  over_align ( & self )  -> Option < u32 >  { 
928+         let  align = self . align . abi ( ) ; 
929+         let  primitive_align = self . primitive_align . abi ( ) ; 
930+         if  align > primitive_align { 
931+             Some ( align as  u32 ) 
932+         }  else  { 
933+             None 
934+         } 
935+     } 
891936} 
892937
893938/// The first half of a fat pointer. 
@@ -924,6 +969,7 @@ pub enum Layout {
924969        /// If true, the size is exact, otherwise it's only a lower bound. 
925970         sized :  bool , 
926971        align :  Align , 
972+         primitive_align :  Align , 
927973        element_size :  Size , 
928974        count :  u64 
929975    } , 
@@ -970,7 +1016,8 @@ pub enum Layout {
9701016        discr :  Integer , 
9711017        variants :  Vec < Struct > , 
9721018        size :  Size , 
973-         align :  Align 
1019+         align :  Align , 
1020+         primitive_align :  Align , 
9741021    } , 
9751022
9761023    /// Two cases distinguished by a nullable pointer: the case with discriminant 
@@ -1118,6 +1165,7 @@ impl<'a, 'gcx, 'tcx> Layout {
11181165                Array  { 
11191166                    sized :  true , 
11201167                    align :  element. align ( dl) , 
1168+                     primitive_align :  element. primitive_align ( dl) , 
11211169                    element_size :  element_size, 
11221170                    count :  count
11231171                } 
@@ -1127,6 +1175,7 @@ impl<'a, 'gcx, 'tcx> Layout {
11271175                Array  { 
11281176                    sized :  false , 
11291177                    align :  element. align ( dl) , 
1178+                     primitive_align :  element. primitive_align ( dl) , 
11301179                    element_size :  element. size ( dl) , 
11311180                    count :  0 
11321181                } 
@@ -1135,6 +1184,7 @@ impl<'a, 'gcx, 'tcx> Layout {
11351184                Array  { 
11361185                    sized :  false , 
11371186                    align :  dl. i8_align , 
1187+                     primitive_align :  dl. i8_align , 
11381188                    element_size :  Size :: from_bytes ( 1 ) , 
11391189                    count :  0 
11401190                } 
@@ -1340,6 +1390,7 @@ impl<'a, 'gcx, 'tcx> Layout {
13401390                assert ! ( discr_max >= 0 ) ; 
13411391                let  ( min_ity,  _)  = Integer :: repr_discr ( tcx,  ty,  & def. repr ,  0 ,  discr_max) ; 
13421392                let  mut  align = dl. aggregate_align ; 
1393+                 let  mut  primitive_align = dl. aggregate_align ; 
13431394                let  mut  size = Size :: from_bytes ( 0 ) ; 
13441395
13451396                // We're interested in the smallest alignment, so start large. 
@@ -1369,6 +1420,7 @@ impl<'a, 'gcx, 'tcx> Layout {
13691420                    } 
13701421                    size = cmp:: max ( size,  st. min_size ) ; 
13711422                    align = align. max ( st. align ) ; 
1423+                     primitive_align = primitive_align. max ( st. primitive_align ) ; 
13721424                    Ok ( st) 
13731425                } ) . collect :: < Result < Vec < _ > ,  _ > > ( ) ?; 
13741426
@@ -1435,7 +1487,8 @@ impl<'a, 'gcx, 'tcx> Layout {
14351487                    discr :  ity, 
14361488                    variants :  variants, 
14371489                    size :  size, 
1438-                     align :  align
1490+                     align :  align, 
1491+                     primitive_align :  primitive_align
14391492                } 
14401493            } 
14411494
@@ -1557,6 +1610,30 @@ impl<'a, 'gcx, 'tcx> Layout {
15571610        } 
15581611    } 
15591612
1613+     /// Returns alignment before repr alignment is applied 
1614+      pub  fn  primitive_align ( & self ,  dl :  & TargetDataLayout )  -> Align  { 
1615+         match  * self  { 
1616+             Array  {  primitive_align,  .. }  | General  {  primitive_align,  .. }  => primitive_align, 
1617+             Univariant  {  ref  variant,  .. }  |
1618+             StructWrappedNullablePointer  {  nonnull :  ref  variant,  .. }  => { 
1619+                 variant. primitive_align 
1620+             } , 
1621+ 
1622+             _ => self . align ( dl) 
1623+         } 
1624+     } 
1625+ 
1626+     /// Returns repr alignment if it is greater than the primitive alignment. 
1627+      pub  fn  over_align ( & self ,  dl :  & TargetDataLayout )  -> Option < u32 >  { 
1628+         let  align = self . align ( dl) ; 
1629+         let  primitive_align = self . primitive_align ( dl) ; 
1630+         if  align. abi ( )  > primitive_align. abi ( )  { 
1631+             Some ( align. abi ( )  as  u32 ) 
1632+         }  else  { 
1633+             None 
1634+         } 
1635+     } 
1636+ 
15601637    pub  fn  field_offset < C :  HasDataLayout > ( & self , 
15611638                                          cx :  C , 
15621639                                          i :  usize , 
0 commit comments