@@ -175,7 +175,7 @@ pub(crate) mod rustc {
175175 use rustc_middle:: ty:: { self , AdtDef , AdtKind , List , ScalarInt , Ty , TyCtxt , TypeVisitableExt } ;
176176 use rustc_span:: ErrorGuaranteed ;
177177 use rustc_target:: abi:: {
178- FieldIdx , FieldsShape , Layout , Size , TyAndLayout , VariantIdx , Variants ,
178+ FieldIdx , FieldsShape , Layout , Size , TagEncoding , TyAndLayout , VariantIdx , Variants ,
179179 } ;
180180
181181 use super :: Tree ;
@@ -319,11 +319,17 @@ pub(crate) mod rustc {
319319 assert ! ( def. is_enum( ) ) ;
320320
321321 // Computes the variant of a given index.
322- let layout_of_variant = |index| {
322+ let layout_of_variant = |index, encoding : Option < TagEncoding < VariantIdx > > | {
323323 let tag = cx. tcx . tag_for_variant ( ( cx. tcx . erase_regions ( ty) , index) ) ;
324324 let variant_def = Def :: Variant ( def. variant ( index) ) ;
325325 let variant_layout = ty_variant ( cx, ( ty, layout) , index) ;
326- Self :: from_variant ( variant_def, tag, ( ty, variant_layout) , layout. size , cx)
326+ Self :: from_variant (
327+ variant_def,
328+ tag. map ( |tag| ( tag, index, encoding. unwrap ( ) ) ) ,
329+ ( ty, variant_layout) ,
330+ layout. size ,
331+ cx,
332+ )
327333 } ;
328334
329335 // We consider three kinds of enums, each demanding a different
@@ -345,9 +351,9 @@ pub(crate) mod rustc {
345351 Variants :: Single { index } => {
346352 // `Variants::Single` on enums with variants denotes that
347353 // the enum delegates its layout to the variant at `index`.
348- layout_of_variant ( * index)
354+ layout_of_variant ( * index, None )
349355 }
350- Variants :: Multiple { tag_field, .. } => {
356+ Variants :: Multiple { tag , tag_encoding , tag_field, .. } => {
351357 // `Variants::Multiple` denotes an enum with multiple
352358 // variants. The layout of such an enum is the disjunction
353359 // of the layouts of its tagged variants.
@@ -359,7 +365,7 @@ pub(crate) mod rustc {
359365 let variants = def. discriminants ( cx. tcx ( ) ) . try_fold (
360366 Self :: uninhabited ( ) ,
361367 |variants, ( idx, ref discriminant) | {
362- let variant = layout_of_variant ( idx) ?;
368+ let variant = layout_of_variant ( idx, Some ( tag_encoding . clone ( ) ) ) ?;
363369 Result :: < Self , Err > :: Ok ( variants. or ( variant) )
364370 } ,
365371 ) ?;
@@ -380,7 +386,7 @@ pub(crate) mod rustc {
380386 /// `0`.
381387 fn from_variant (
382388 def : Def < ' tcx > ,
383- tag : Option < ScalarInt > ,
389+ tag : Option < ( ScalarInt , VariantIdx , TagEncoding < VariantIdx > ) > ,
384390 ( ty, layout) : ( Ty < ' tcx > , Layout < ' tcx > ) ,
385391 total_size : Size ,
386392 cx : LayoutCx < ' tcx , TyCtxt < ' tcx > > ,
@@ -400,9 +406,18 @@ pub(crate) mod rustc {
400406 let mut struct_tree = Self :: def ( def) ;
401407
402408 // If a `tag` is provided, place it at the start of the layout.
403- if let Some ( tag) = tag {
404- size += tag. size ( ) ;
405- struct_tree = struct_tree. then ( Self :: from_tag ( tag, cx. tcx ) ) ;
409+ if let Some ( ( tag, index, encoding) ) = & tag {
410+ match encoding {
411+ TagEncoding :: Direct => {
412+ size += tag. size ( ) ;
413+ }
414+ TagEncoding :: Niche { niche_variants, .. } => {
415+ if !niche_variants. contains ( index) {
416+ size += tag. size ( ) ;
417+ }
418+ }
419+ }
420+ struct_tree = struct_tree. then ( Self :: from_tag ( * tag, cx. tcx ) ) ;
406421 }
407422
408423 // Append the fields, in memory order, to the layout.
0 commit comments