@@ -53,24 +53,24 @@ pub trait LayoutCalculator {
53
53
kind : StructKind ,
54
54
) -> Option < LayoutS > {
55
55
let layout = univariant ( self , dl, fields, repr, kind, NicheBias :: Start ) ;
56
- // Enums prefer niches close to the beginning or the end of the variants so that other (smaller)
57
- // data-carrying variants can be packed into the space after/before the niche.
56
+ // Enums prefer niches close to the beginning or the end of the variants so that other
57
+ // (smaller) data-carrying variants can be packed into the space after/before the niche.
58
58
// If the default field ordering does not give us a niche at the front then we do a second
59
- // run and bias niches to the right and then check which one is closer to one of the struct's
60
- // edges.
59
+ // run and bias niches to the right and then check which one is closer to one of the
60
+ // struct's edges.
61
61
if let Some ( layout) = & layout {
62
62
// Don't try to calculate an end-biased layout for unsizable structs,
63
63
// otherwise we could end up with different layouts for
64
- // Foo<Type> and Foo<dyn Trait> which would break unsizing
64
+ // Foo<Type> and Foo<dyn Trait> which would break unsizing.
65
65
if !matches ! ( kind, StructKind :: MaybeUnsized ) {
66
66
if let Some ( niche) = layout. largest_niche {
67
67
let head_space = niche. offset . bytes ( ) ;
68
68
let niche_length = niche. value . size ( dl) . bytes ( ) ;
69
69
let tail_space = layout. size . bytes ( ) - head_space - niche_length;
70
70
71
- // This may end up doing redundant work if the niche is already in the last field
72
- // (e.g. a trailing bool) and there is tail padding. But it's non-trivial to get
73
- // the unpadded size so we try anyway.
71
+ // This may end up doing redundant work if the niche is already in the last
72
+ // field (e.g. a trailing bool) and there is tail padding. But it's non-trivial
73
+ // to get the unpadded size so we try anyway.
74
74
if fields. len ( ) > 1 && head_space != 0 && tail_space > 0 {
75
75
let alt_layout = univariant ( self , dl, fields, repr, kind, NicheBias :: End )
76
76
. expect ( "alt layout should always work" ) ;
@@ -684,7 +684,8 @@ pub trait LayoutCalculator {
684
684
// Also do not overwrite any already existing "clever" ABIs.
685
685
if variant. fields . count ( ) > 0 && matches ! ( variant. abi, Abi :: Aggregate { .. } ) {
686
686
variant. abi = abi;
687
- // Also need to bump up the size and alignment, so that the entire value fits in here.
687
+ // Also need to bump up the size and alignment, so that the entire value fits
688
+ // in here.
688
689
variant. size = cmp:: max ( variant. size , size) ;
689
690
variant. align . abi = cmp:: max ( variant. align . abi , align. abi ) ;
690
691
}
@@ -868,15 +869,15 @@ fn univariant(
868
869
869
870
// If `-Z randomize-layout` was enabled for the type definition we can shuffle
870
871
// the field ordering to try and catch some code making assumptions about layouts
871
- // we don't guarantee
872
+ // we don't guarantee.
872
873
if repr. can_randomize_type_layout ( ) && cfg ! ( feature = "randomize" ) {
873
874
#[ cfg( feature = "randomize" ) ]
874
875
{
875
- // `ReprOptions.layout_seed` is a deterministic seed that we can use to
876
- // randomize field ordering with
876
+ // `ReprOptions.layout_seed` is a deterministic seed we can use to randomize field
877
+ // ordering.
877
878
let mut rng = Xoshiro128StarStar :: seed_from_u64 ( repr. field_shuffle_seed . as_u64 ( ) ) ;
878
879
879
- // Shuffle the ordering of the fields
880
+ // Shuffle the ordering of the fields.
880
881
optimizing. shuffle ( & mut rng) ;
881
882
}
882
883
// Otherwise we just leave things alone and actually optimize the type's fields
@@ -892,27 +893,26 @@ fn univariant(
892
893
. max ( )
893
894
. unwrap_or ( 0 ) ;
894
895
895
- // Calculates a sort key to group fields by their alignment or possibly some size-derived
896
- // pseudo-alignment.
896
+ // Calculates a sort key to group fields by their alignment or possibly some
897
+ // size-derived pseudo-alignment.
897
898
let alignment_group_key = |layout : Layout < ' _ > | {
898
899
if let Some ( pack) = pack {
899
- // return the packed alignment in bytes
900
+ // Return the packed alignment in bytes.
900
901
layout. align ( ) . abi . min ( pack) . bytes ( )
901
902
} else {
902
- // returns log2(effective-align).
903
- // This is ok since `pack` applies to all fields equally.
904
- // The calculation assumes that size is an integer multiple of align, except for ZSTs.
905
- //
903
+ // Returns `log2(effective-align)`. This is ok since `pack` applies to all
904
+ // fields equally. The calculation assumes that size is an integer multiple of
905
+ // align, except for ZSTs.
906
906
let align = layout. align ( ) . abi . bytes ( ) ;
907
907
let size = layout. size ( ) . bytes ( ) ;
908
908
let niche_size = layout. largest_niche ( ) . map ( |n| n. available ( dl) ) . unwrap_or ( 0 ) ;
909
- // group [u8; 4] with align-4 or [u8; 6] with align-2 fields
909
+ // Group [u8; 4] with align-4 or [u8; 6] with align-2 fields.
910
910
let size_as_align = align. max ( size) . trailing_zeros ( ) ;
911
911
let size_as_align = if largest_niche_size > 0 {
912
912
match niche_bias {
913
- // Given `A(u8, [u8; 16])` and `B(bool, [u8; 16])` we want to bump the array
914
- // to the front in the first case (for aligned loads) but keep the bool in front
915
- // in the second case for its niches.
913
+ // Given `A(u8, [u8; 16])` and `B(bool, [u8; 16])` we want to bump the
914
+ // array to the front in the first case (for aligned loads) but keep
915
+ // the bool in front in the second case for its niches.
916
916
NicheBias :: Start => max_field_align. trailing_zeros ( ) . min ( size_as_align) ,
917
917
// When moving niches towards the end of the struct then for
918
918
// A((u8, u8, u8, bool), (u8, bool, u8)) we want to keep the first tuple
@@ -931,14 +931,14 @@ fn univariant(
931
931
932
932
match kind {
933
933
StructKind :: AlwaysSized | StructKind :: MaybeUnsized => {
934
- // Currently `LayoutS` only exposes a single niche so sorting is usually sufficient
935
- // to get one niche into the preferred position. If it ever supported multiple niches
936
- // then a more advanced pick-and-pack approach could provide better results.
937
- // But even for the single-niche cache it's not optimal. E.g. for
938
- // A(u32, (bool, u8), u16) it would be possible to move the bool to the front
939
- // but it would require packing the tuple together with the u16 to build a 4-byte
940
- // group so that the u32 can be placed after it without padding. This kind
941
- // of packing can't be achieved by sorting.
934
+ // Currently `LayoutS` only exposes a single niche so sorting is usually
935
+ // sufficient to get one niche into the preferred position. If it ever
936
+ // supported multiple niches then a more advanced pick-and-pack approach could
937
+ // provide better results. But even for the single-niche cache it's not
938
+ // optimal. E.g. for A(u32, (bool, u8), u16) it would be possible to move the
939
+ // bool to the front but it would require packing the tuple together with the
940
+ // u16 to build a 4-byte group so that the u32 can be placed after it without
941
+ // padding. This kind of packing can't be achieved by sorting.
942
942
optimizing. sort_by_key ( |& x| {
943
943
let f = fields[ x] ;
944
944
let field_size = f. size ( ) . bytes ( ) ;
0 commit comments