@@ -8,15 +8,19 @@ use tracing::debug;
88use crate :: {
99 Abi , AbiAndPrefAlign , Align , FieldsShape , IndexSlice , IndexVec , Integer , LayoutS , Niche ,
1010 NonZeroUsize , Primitive , ReprOptions , Scalar , Size , StructKind , TagEncoding , TargetDataLayout ,
11- VariantIdx , Variants , WrappingRange , FIRST_VARIANT ,
11+ Variants , WrappingRange ,
1212} ;
1313pub trait LayoutCalculator {
1414 type TargetDataLayoutRef : Borrow < TargetDataLayout > ;
1515
1616 fn delay_bug ( & self , txt : String ) ;
1717 fn current_data_layout ( & self ) -> Self :: TargetDataLayoutRef ;
1818
19- fn scalar_pair < FieldIdx : Idx > ( & self , a : Scalar , b : Scalar ) -> LayoutS < FieldIdx > {
19+ fn scalar_pair < FieldIdx : Idx , VariantIdx : Idx > (
20+ & self ,
21+ a : Scalar ,
22+ b : Scalar ,
23+ ) -> LayoutS < FieldIdx , VariantIdx > {
2024 let dl = self . current_data_layout ( ) ;
2125 let dl = dl. borrow ( ) ;
2226 let b_align = b. align ( dl) ;
@@ -32,7 +36,7 @@ pub trait LayoutCalculator {
3236 . max_by_key ( |niche| niche. available ( dl) ) ;
3337
3438 LayoutS {
35- variants : Variants :: Single { index : FIRST_VARIANT } ,
39+ variants : Variants :: Single { index : VariantIdx :: new ( 0 ) } ,
3640 fields : FieldsShape :: Arbitrary {
3741 offsets : [ Size :: ZERO , b_offset] . into ( ) ,
3842 memory_index : [ 0 , 1 ] . into ( ) ,
@@ -46,13 +50,18 @@ pub trait LayoutCalculator {
4650 }
4751 }
4852
49- fn univariant < ' a , FieldIdx : Idx , F : Deref < Target = & ' a LayoutS < FieldIdx > > + fmt:: Debug > (
53+ fn univariant <
54+ ' a ,
55+ FieldIdx : Idx ,
56+ VariantIdx : Idx ,
57+ F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
58+ > (
5059 & self ,
5160 dl : & TargetDataLayout ,
5261 fields : & IndexSlice < FieldIdx , F > ,
5362 repr : & ReprOptions ,
5463 kind : StructKind ,
55- ) -> Option < LayoutS < FieldIdx > > {
64+ ) -> Option < LayoutS < FieldIdx , VariantIdx > > {
5665 let layout = univariant ( self , dl, fields, repr, kind, NicheBias :: Start ) ;
5766 // Enums prefer niches close to the beginning or the end of the variants so that other
5867 // (smaller) data-carrying variants can be packed into the space after/before the niche.
@@ -115,11 +124,13 @@ pub trait LayoutCalculator {
115124 layout
116125 }
117126
118- fn layout_of_never_type < FieldIdx : Idx > ( & self ) -> LayoutS < FieldIdx > {
127+ fn layout_of_never_type < FieldIdx : Idx , VariantIdx : Idx > (
128+ & self ,
129+ ) -> LayoutS < FieldIdx , VariantIdx > {
119130 let dl = self . current_data_layout ( ) ;
120131 let dl = dl. borrow ( ) ;
121132 LayoutS {
122- variants : Variants :: Single { index : FIRST_VARIANT } ,
133+ variants : Variants :: Single { index : VariantIdx :: new ( 0 ) } ,
123134 fields : FieldsShape :: Primitive ,
124135 abi : Abi :: Uninhabited ,
125136 largest_niche : None ,
@@ -133,7 +144,8 @@ pub trait LayoutCalculator {
133144 fn layout_of_struct_or_enum <
134145 ' a ,
135146 FieldIdx : Idx ,
136- F : Deref < Target = & ' a LayoutS < FieldIdx > > + fmt:: Debug ,
147+ VariantIdx : Idx ,
148+ F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
137149 > (
138150 & self ,
139151 repr : & ReprOptions ,
@@ -145,7 +157,7 @@ pub trait LayoutCalculator {
145157 discriminants : impl Iterator < Item = ( VariantIdx , i128 ) > ,
146158 dont_niche_optimize_enum : bool ,
147159 always_sized : bool ,
148- ) -> Option < LayoutS < FieldIdx > > {
160+ ) -> Option < LayoutS < FieldIdx , VariantIdx > > {
149161 let dl = self . current_data_layout ( ) ;
150162 let dl = dl. borrow ( ) ;
151163
@@ -181,7 +193,7 @@ pub trait LayoutCalculator {
181193 }
182194 // If it's a struct, still compute a layout so that we can still compute the
183195 // field offsets.
184- None => FIRST_VARIANT ,
196+ None => VariantIdx :: new ( 0 ) ,
185197 } ;
186198
187199 let is_struct = !is_enum ||
@@ -284,12 +296,12 @@ pub trait LayoutCalculator {
284296 // variant layouts, so we can't store them in the
285297 // overall LayoutS. Store the overall LayoutS
286298 // and the variant LayoutSs here until then.
287- struct TmpLayout < FieldIdx : Idx > {
288- layout : LayoutS < FieldIdx > ,
289- variants : IndexVec < VariantIdx , LayoutS < FieldIdx > > ,
299+ struct TmpLayout < FieldIdx : Idx , VariantIdx : Idx > {
300+ layout : LayoutS < FieldIdx , VariantIdx > ,
301+ variants : IndexVec < VariantIdx , LayoutS < FieldIdx , VariantIdx > > ,
290302 }
291303
292- let calculate_niche_filling_layout = || -> Option < TmpLayout < FieldIdx > > {
304+ let calculate_niche_filling_layout = || -> Option < TmpLayout < FieldIdx , VariantIdx > > {
293305 if dont_niche_optimize_enum {
294306 return None ;
295307 }
@@ -327,7 +339,8 @@ pub trait LayoutCalculator {
327339 let niche_variants = all_indices. clone ( ) . find ( |v| needs_disc ( * v) ) . unwrap ( )
328340 ..=all_indices. rev ( ) . find ( |v| needs_disc ( * v) ) . unwrap ( ) ;
329341
330- let count = niche_variants. size_hint ( ) . 1 . unwrap ( ) as u128 ;
342+ let count =
343+ niche_variants. end ( ) . index ( ) as u128 - niche_variants. start ( ) . index ( ) as u128 ;
331344
332345 // Find the field with the largest niche
333346 let ( field_index, niche, ( niche_start, niche_scalar) ) = variants[ largest_variant_index]
@@ -660,7 +673,7 @@ pub trait LayoutCalculator {
660673 // Common prim might be uninit.
661674 Scalar :: Union { value : prim }
662675 } ;
663- let pair = self . scalar_pair ( tag, prim_scalar) ;
676+ let pair = self . scalar_pair :: < FieldIdx , VariantIdx > ( tag, prim_scalar) ;
664677 let pair_offsets = match pair. fields {
665678 FieldsShape :: Arbitrary { ref offsets, ref memory_index } => {
666679 assert_eq ! ( memory_index. raw, [ 0 , 1 ] ) ;
@@ -726,7 +739,7 @@ pub trait LayoutCalculator {
726739 // pick the layout with the larger niche; otherwise,
727740 // pick tagged as it has simpler codegen.
728741 use cmp:: Ordering :: * ;
729- let niche_size = |tmp_l : & TmpLayout < FieldIdx > | {
742+ let niche_size = |tmp_l : & TmpLayout < FieldIdx , VariantIdx > | {
730743 tmp_l. layout . largest_niche . map_or ( 0 , |n| n. available ( dl) )
731744 } ;
732745 match ( tl. layout . size . cmp ( & nl. layout . size ) , niche_size ( & tl) . cmp ( & niche_size ( & nl) ) ) {
@@ -748,11 +761,16 @@ pub trait LayoutCalculator {
748761 Some ( best_layout. layout )
749762 }
750763
751- fn layout_of_union < ' a , FieldIdx : Idx , F : Deref < Target = & ' a LayoutS < FieldIdx > > + fmt:: Debug > (
764+ fn layout_of_union <
765+ ' a ,
766+ FieldIdx : Idx ,
767+ VariantIdx : Idx ,
768+ F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
769+ > (
752770 & self ,
753771 repr : & ReprOptions ,
754772 variants : & IndexSlice < VariantIdx , IndexVec < FieldIdx , F > > ,
755- ) -> Option < LayoutS < FieldIdx > > {
773+ ) -> Option < LayoutS < FieldIdx , VariantIdx > > {
756774 let dl = self . current_data_layout ( ) ;
757775 let dl = dl. borrow ( ) ;
758776 let mut align = if repr. pack . is_some ( ) { dl. i8_align } else { dl. aggregate_align } ;
@@ -769,7 +787,7 @@ pub trait LayoutCalculator {
769787 } ;
770788
771789 let mut size = Size :: ZERO ;
772- let only_variant = & variants[ FIRST_VARIANT ] ;
790+ let only_variant = & variants[ VariantIdx :: new ( 0 ) ] ;
773791 for field in only_variant {
774792 if field. is_unsized ( ) {
775793 self . delay_bug ( "unsized field in union" . to_string ( ) ) ;
@@ -836,7 +854,7 @@ pub trait LayoutCalculator {
836854 } ;
837855
838856 Some ( LayoutS {
839- variants : Variants :: Single { index : FIRST_VARIANT } ,
857+ variants : Variants :: Single { index : VariantIdx :: new ( 0 ) } ,
840858 fields : FieldsShape :: Union ( NonZeroUsize :: new ( only_variant. len ( ) ) ?) ,
841859 abi,
842860 largest_niche : None ,
@@ -854,14 +872,19 @@ enum NicheBias {
854872 End ,
855873}
856874
857- fn univariant < ' a , FieldIdx : Idx , F : Deref < Target = & ' a LayoutS < FieldIdx > > + fmt:: Debug > (
875+ fn univariant <
876+ ' a ,
877+ FieldIdx : Idx ,
878+ VariantIdx : Idx ,
879+ F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
880+ > (
858881 this : & ( impl LayoutCalculator + ?Sized ) ,
859882 dl : & TargetDataLayout ,
860883 fields : & IndexSlice < FieldIdx , F > ,
861884 repr : & ReprOptions ,
862885 kind : StructKind ,
863886 niche_bias : NicheBias ,
864- ) -> Option < LayoutS < FieldIdx > > {
887+ ) -> Option < LayoutS < FieldIdx , VariantIdx > > {
865888 let pack = repr. pack ;
866889 let mut align = if pack. is_some ( ) { dl. i8_align } else { dl. aggregate_align } ;
867890 let mut max_repr_align = repr. align ;
@@ -1120,7 +1143,7 @@ fn univariant<'a, FieldIdx: Idx, F: Deref<Target = &'a LayoutS<FieldIdx>> + fmt:
11201143 } else {
11211144 ( ( j, b) , ( i, a) )
11221145 } ;
1123- let pair = this. scalar_pair ( a, b) ;
1146+ let pair = this. scalar_pair :: < FieldIdx , VariantIdx > ( a, b) ;
11241147 let pair_offsets = match pair. fields {
11251148 FieldsShape :: Arbitrary { ref offsets, ref memory_index } => {
11261149 assert_eq ! ( memory_index. raw, [ 0 , 1 ] ) ;
@@ -1162,7 +1185,7 @@ fn univariant<'a, FieldIdx: Idx, F: Deref<Target = &'a LayoutS<FieldIdx>> + fmt:
11621185 } ;
11631186
11641187 Some ( LayoutS {
1165- variants : Variants :: Single { index : FIRST_VARIANT } ,
1188+ variants : Variants :: Single { index : VariantIdx :: new ( 0 ) } ,
11661189 fields : FieldsShape :: Arbitrary { offsets, memory_index } ,
11671190 abi,
11681191 largest_niche,
@@ -1173,8 +1196,13 @@ fn univariant<'a, FieldIdx: Idx, F: Deref<Target = &'a LayoutS<FieldIdx>> + fmt:
11731196 } )
11741197}
11751198
1176- fn format_field_niches < ' a , FieldIdx : Idx , F : Deref < Target = & ' a LayoutS < FieldIdx > > + fmt:: Debug > (
1177- layout : & LayoutS < FieldIdx > ,
1199+ fn format_field_niches <
1200+ ' a ,
1201+ FieldIdx : Idx ,
1202+ VariantIdx : Idx ,
1203+ F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
1204+ > (
1205+ layout : & LayoutS < FieldIdx , VariantIdx > ,
11781206 fields : & IndexSlice < FieldIdx , F > ,
11791207 dl : & TargetDataLayout ,
11801208) -> String {
0 commit comments