@@ -325,10 +325,6 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
325325 offsets. len( ) , ty) ;
326326 }
327327
328- if field. abi == Abi :: Uninhabited {
329- return Ok ( LayoutDetails :: uninhabited ( fields. len ( ) ) ) ;
330- }
331-
332328 if field. is_unsized ( ) {
333329 sized = false ;
334330 }
@@ -451,6 +447,10 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
451447 }
452448 }
453449
450+ if sized && fields. iter ( ) . any ( |f| f. abi == Abi :: Uninhabited ) {
451+ abi = Abi :: Uninhabited ;
452+ }
453+
454454 Ok ( LayoutDetails {
455455 variants : Variants :: Single { index : 0 } ,
456456 fields : FieldPlacement :: Arbitrary {
@@ -497,7 +497,13 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
497497
498498 // The never type.
499499 ty:: TyNever => {
500- tcx. intern_layout ( LayoutDetails :: uninhabited ( 0 ) )
500+ tcx. intern_layout ( LayoutDetails {
501+ variants : Variants :: Single { index : 0 } ,
502+ fields : FieldPlacement :: Union ( 0 ) ,
503+ abi : Abi :: Uninhabited ,
504+ align : dl. i8_align ,
505+ size : Size :: from_bytes ( 0 )
506+ } )
501507 }
502508
503509 // Potentially-fat pointers.
@@ -711,27 +717,37 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
711717 } ) ) ;
712718 }
713719
714- let ( inh_first, inh_second) = {
715- let mut inh_variants = ( 0 ..variants. len ( ) ) . filter ( |& v| {
716- variants[ v] . iter ( ) . all ( |f| f. abi != Abi :: Uninhabited )
720+ // A variant is absent if it's uninhabited and only has ZST fields.
721+ // Present uninhabited variants only require space for their fields,
722+ // but *not* an encoding of the discriminant (e.g. a tag value).
723+ // See issue #49298 for more details on the need to leave space
724+ // for non-ZST uninhabited data (mostly partial initialization).
725+ let absent = |fields : & [ TyLayout ] | {
726+ let uninhabited = fields. iter ( ) . any ( |f| f. abi == Abi :: Uninhabited ) ;
727+ let is_zst = fields. iter ( ) . all ( |f| f. is_zst ( ) ) ;
728+ uninhabited && is_zst
729+ } ;
730+ let ( present_first, present_second) = {
731+ let mut present_variants = ( 0 ..variants. len ( ) ) . filter ( |& v| {
732+ !absent ( & variants[ v] )
717733 } ) ;
718- ( inh_variants . next ( ) , inh_variants . next ( ) )
734+ ( present_variants . next ( ) , present_variants . next ( ) )
719735 } ;
720- if inh_first . is_none ( ) {
721- // Uninhabited because it has no variants, or only uninhabited ones.
722- return Ok ( tcx. intern_layout ( LayoutDetails :: uninhabited ( 0 ) ) ) ;
736+ if present_first . is_none ( ) {
737+ // Uninhabited because it has no variants, or only absent ones.
738+ return tcx. layout_raw ( param_env . and ( tcx . types . never ) ) ;
723739 }
724740
725741 let is_struct = !def. is_enum ( ) ||
726- // Only one variant is inhabited .
727- ( inh_second . is_none ( ) &&
742+ // Only one variant is present .
743+ ( present_second . is_none ( ) &&
728744 // Representation optimizations are allowed.
729745 !def. repr . inhibit_enum_layout_opt ( ) ) ;
730746 if is_struct {
731747 // Struct, or univariant enum equivalent to a struct.
732748 // (Typechecking will reject discriminant-sizing attrs.)
733749
734- let v = inh_first . unwrap ( ) ;
750+ let v = present_first . unwrap ( ) ;
735751 let kind = if def. is_enum ( ) || variants[ v] . len ( ) == 0 {
736752 StructKind :: AlwaysSized
737753 } else {
@@ -773,7 +789,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
773789
774790 // Find one non-ZST variant.
775791 ' variants: for ( v, fields) in variants. iter ( ) . enumerate ( ) {
776- if fields . iter ( ) . any ( |f| f . abi == Abi :: Uninhabited ) {
792+ if absent ( fields ) {
777793 continue ' variants;
778794 }
779795 for f in fields {
@@ -816,7 +832,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
816832 let offset = st[ i] . fields . offset ( field_index) + offset;
817833 let size = st[ i] . size ;
818834
819- let abi = match st[ i] . abi {
835+ let mut abi = match st[ i] . abi {
820836 Abi :: Scalar ( _) => Abi :: Scalar ( niche. clone ( ) ) ,
821837 Abi :: ScalarPair ( ref first, ref second) => {
822838 // We need to use scalar_unit to reset the
@@ -833,6 +849,10 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
833849 _ => Abi :: Aggregate { sized : true } ,
834850 } ;
835851
852+ if st. iter ( ) . all ( |v| v. abi == Abi :: Uninhabited ) {
853+ abi = Abi :: Uninhabited ;
854+ }
855+
836856 return Ok ( tcx. intern_layout ( LayoutDetails {
837857 variants : Variants :: NicheFilling {
838858 dataful_variant : i,
@@ -959,9 +979,6 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
959979 let old_ity_size = min_ity. size ( ) ;
960980 let new_ity_size = ity. size ( ) ;
961981 for variant in & mut layout_variants {
962- if variant. abi == Abi :: Uninhabited {
963- continue ;
964- }
965982 match variant. fields {
966983 FieldPlacement :: Arbitrary { ref mut offsets, .. } => {
967984 for i in offsets {
@@ -1055,6 +1072,11 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
10551072 }
10561073 }
10571074 }
1075+
1076+ if layout_variants. iter ( ) . all ( |v| v. abi == Abi :: Uninhabited ) {
1077+ abi = Abi :: Uninhabited ;
1078+ }
1079+
10581080 tcx. intern_layout ( LayoutDetails {
10591081 variants : Variants :: Tagged {
10601082 tag,
@@ -1523,9 +1545,14 @@ impl<'a, 'tcx, C> TyLayoutMethods<'tcx, C> for Ty<'tcx>
15231545 ty:: TyAdt ( def, _) => def. variants [ variant_index] . fields . len ( ) ,
15241546 _ => bug ! ( )
15251547 } ;
1526- let mut details = LayoutDetails :: uninhabited ( fields) ;
1527- details. variants = Variants :: Single { index : variant_index } ;
1528- cx. tcx ( ) . intern_layout ( details)
1548+ let tcx = cx. tcx ( ) ;
1549+ tcx. intern_layout ( LayoutDetails {
1550+ variants : Variants :: Single { index : variant_index } ,
1551+ fields : FieldPlacement :: Union ( fields) ,
1552+ abi : Abi :: Uninhabited ,
1553+ align : tcx. data_layout . i8_align ,
1554+ size : Size :: from_bytes ( 0 )
1555+ } )
15291556 }
15301557
15311558 Variants :: NicheFilling { ref variants, .. } |
0 commit comments