@@ -898,123 +898,72 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
898898 if !def. repr . inhibit_enum_layout_opt ( ) && no_explicit_discriminants {
899899 let mut dataful_variant = None ;
900900 let mut niche_variants = VariantIdx :: MAX ..=VariantIdx :: new ( 0 ) ;
901- let mut max_size = Size :: ZERO ;
902- let mut second_max_size = Size :: ZERO ;
903- let mut align = dl. aggregate_align ;
904901
905- // The size computations below assume that the padding is minimum.
906- // This is the case when fields are re-ordered.
907- let struct_reordering_opt = !def. repr . inhibit_struct_field_reordering_opt ( ) ;
908-
909- let mut extend_niche_range = |d| {
910- niche_variants =
911- * niche_variants. start ( ) . min ( & d) ..=* niche_variants. end ( ) . max ( & d) ;
912- } ;
913-
914- // Find the largest and second largest variant.
915- for ( v, fields) in variants. iter_enumerated ( ) {
902+ // Find one non-ZST variant.
903+ ' variants: for ( v, fields) in variants. iter_enumerated ( ) {
916904 if absent ( fields) {
917- continue ;
905+ continue ' variants ;
918906 }
919- let mut size = Size :: ZERO ;
920- for & f in fields {
921- align = align. max ( f. align ) ;
922- size += f. size ;
923- }
924- if size > max_size {
925- second_max_size = max_size;
926- max_size = size;
927- if let Some ( d) = dataful_variant {
928- extend_niche_range ( d) ;
929- }
930- dataful_variant = Some ( v) ;
931- } else if size == max_size {
932- if let Some ( d) = dataful_variant {
933- extend_niche_range ( d) ;
907+ for f in fields {
908+ if !f. is_zst ( ) {
909+ if dataful_variant. is_none ( ) {
910+ dataful_variant = Some ( v) ;
911+ continue ' variants;
912+ } else {
913+ dataful_variant = None ;
914+ break ' variants;
915+ }
934916 }
935- dataful_variant = None ;
936- extend_niche_range ( v) ;
937- } else {
938- second_max_size = second_max_size. max ( size) ;
939- extend_niche_range ( v) ;
940917 }
918+ niche_variants = * niche_variants. start ( ) . min ( & v) ..=v;
941919 }
942920
943921 if niche_variants. start ( ) > niche_variants. end ( ) {
944922 dataful_variant = None ;
945923 }
946924
947- if let Some ( dataful_variant ) = dataful_variant {
925+ if let Some ( i ) = dataful_variant {
948926 let count = ( niche_variants. end ( ) . as_u32 ( )
949927 - niche_variants. start ( ) . as_u32 ( )
950928 + 1 ) as u128 ;
951929
952930 // Find the field with the largest niche
953- let niche_candidate = variants[ dataful_variant ]
931+ let niche_candidate = variants[ i ]
954932 . iter ( )
955933 . enumerate ( )
956934 . filter_map ( |( j, & field) | Some ( ( j, field. largest_niche . as_ref ( ) ?) ) )
957- . max_by_key ( |( _, n) | ( n. available ( dl) , cmp:: Reverse ( n. offset ) ) )
958- . and_then ( |( field_index, niche) | {
959- if !struct_reordering_opt && second_max_size > Size :: ZERO {
960- return None ;
961- }
962- // make sure there is enough room for the other variants
963- if max_size - ( niche. offset + niche. scalar . value . size ( dl) )
964- < second_max_size
965- {
966- return None ;
967- }
968- Some ( ( field_index, niche, niche. reserve ( self , count) ?) )
969- } ) ;
935+ . max_by_key ( |( _, niche) | niche. available ( dl) ) ;
970936
971937 if let Some ( ( field_index, niche, ( niche_start, niche_scalar) ) ) =
972- niche_candidate
938+ niche_candidate. and_then ( |( field_index, niche) | {
939+ Some ( ( field_index, niche, niche. reserve ( self , count) ?) )
940+ } )
973941 {
974- let prefix = niche . offset + niche . scalar . value . size ( dl ) ;
942+ let mut align = dl . aggregate_align ;
975943 let st = variants
976944 . iter_enumerated ( )
977945 . map ( |( j, v) | {
978946 let mut st = self . univariant_uninterned (
979947 ty,
980948 v,
981949 & def. repr ,
982- if j == dataful_variant || second_max_size == Size :: ZERO {
983- StructKind :: AlwaysSized
984- } else {
985- StructKind :: Prefixed (
986- prefix,
987- Align :: from_bytes ( 1 ) . unwrap ( ) ,
988- )
989- } ,
950+ StructKind :: AlwaysSized ,
990951 ) ?;
991952 st. variants = Variants :: Single { index : j } ;
992953
993- debug_assert_eq ! ( align, align. max( st. align) ) ;
954+ align = align. max ( st. align ) ;
955+
994956 Ok ( st)
995957 } )
996958 . collect :: < Result < IndexVec < VariantIdx , _ > , _ > > ( ) ?;
997959
998- let offset = if struct_reordering_opt {
999- debug_assert_eq ! (
1000- st[ dataful_variant] . fields. offset( field_index) ,
1001- Size :: ZERO
1002- ) ;
1003- niche. offset
1004- } else {
1005- st[ dataful_variant] . fields . offset ( field_index) + niche. offset
1006- } ;
1007-
1008- let size = st[ dataful_variant] . size . align_to ( align. abi ) ;
1009- debug_assert ! (
1010- !struct_reordering_opt || size == max_size. align_to( align. abi)
1011- ) ;
1012- debug_assert ! ( st. iter( ) . all( |v| v. size <= size) ) ;
960+ let offset = st[ i] . fields . offset ( field_index) + niche. offset ;
961+ let size = st[ i] . size ;
1013962
1014963 let abi = if st. iter ( ) . all ( |v| v. abi . is_uninhabited ( ) ) {
1015964 Abi :: Uninhabited
1016- } else if second_max_size == Size :: ZERO {
1017- match st[ dataful_variant ] . abi {
965+ } else {
966+ match st[ i ] . abi {
1018967 Abi :: Scalar ( _) => Abi :: Scalar ( niche_scalar. clone ( ) ) ,
1019968 Abi :: ScalarPair ( ref first, ref second) => {
1020969 // We need to use scalar_unit to reset the
@@ -1036,8 +985,6 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
1036985 }
1037986 _ => Abi :: Aggregate { sized : true } ,
1038987 }
1039- } else {
1040- Abi :: Aggregate { sized : true }
1041988 } ;
1042989
1043990 let largest_niche =
@@ -1047,7 +994,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
1047994 variants : Variants :: Multiple {
1048995 tag : niche_scalar,
1049996 tag_encoding : TagEncoding :: Niche {
1050- dataful_variant,
997+ dataful_variant : i ,
1051998 niche_variants,
1052999 niche_start,
10531000 } ,
0 commit comments