@@ -325,10 +325,6 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
325
325
offsets. len( ) , ty) ;
326
326
}
327
327
328
- if field. abi == Abi :: Uninhabited {
329
- return Ok ( LayoutDetails :: uninhabited ( fields. len ( ) ) ) ;
330
- }
331
-
332
328
if field. is_unsized ( ) {
333
329
sized = false ;
334
330
}
@@ -451,6 +447,10 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
451
447
}
452
448
}
453
449
450
+ if sized && fields. iter ( ) . any ( |f| f. abi == Abi :: Uninhabited ) {
451
+ abi = Abi :: Uninhabited ;
452
+ }
453
+
454
454
Ok ( LayoutDetails {
455
455
variants : Variants :: Single { index : 0 } ,
456
456
fields : FieldPlacement :: Arbitrary {
@@ -497,7 +497,13 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
497
497
498
498
// The never type.
499
499
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
+ } )
501
507
}
502
508
503
509
// Potentially-fat pointers.
@@ -711,27 +717,37 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
711
717
} ) ) ;
712
718
}
713
719
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] )
717
733
} ) ;
718
- ( inh_variants . next ( ) , inh_variants . next ( ) )
734
+ ( present_variants . next ( ) , present_variants . next ( ) )
719
735
} ;
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 ) ) ;
723
739
}
724
740
725
741
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 ( ) &&
728
744
// Representation optimizations are allowed.
729
745
!def. repr . inhibit_enum_layout_opt ( ) ) ;
730
746
if is_struct {
731
747
// Struct, or univariant enum equivalent to a struct.
732
748
// (Typechecking will reject discriminant-sizing attrs.)
733
749
734
- let v = inh_first . unwrap ( ) ;
750
+ let v = present_first . unwrap ( ) ;
735
751
let kind = if def. is_enum ( ) || variants[ v] . len ( ) == 0 {
736
752
StructKind :: AlwaysSized
737
753
} else {
@@ -773,7 +789,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
773
789
774
790
// Find one non-ZST variant.
775
791
' variants: for ( v, fields) in variants. iter ( ) . enumerate ( ) {
776
- if fields . iter ( ) . any ( |f| f . abi == Abi :: Uninhabited ) {
792
+ if absent ( fields ) {
777
793
continue ' variants;
778
794
}
779
795
for f in fields {
@@ -816,7 +832,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
816
832
let offset = st[ i] . fields . offset ( field_index) + offset;
817
833
let size = st[ i] . size ;
818
834
819
- let abi = match st[ i] . abi {
835
+ let mut abi = match st[ i] . abi {
820
836
Abi :: Scalar ( _) => Abi :: Scalar ( niche. clone ( ) ) ,
821
837
Abi :: ScalarPair ( ref first, ref second) => {
822
838
// We need to use scalar_unit to reset the
@@ -833,6 +849,10 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
833
849
_ => Abi :: Aggregate { sized : true } ,
834
850
} ;
835
851
852
+ if st. iter ( ) . all ( |v| v. abi == Abi :: Uninhabited ) {
853
+ abi = Abi :: Uninhabited ;
854
+ }
855
+
836
856
return Ok ( tcx. intern_layout ( LayoutDetails {
837
857
variants : Variants :: NicheFilling {
838
858
dataful_variant : i,
@@ -959,9 +979,6 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
959
979
let old_ity_size = min_ity. size ( ) ;
960
980
let new_ity_size = ity. size ( ) ;
961
981
for variant in & mut layout_variants {
962
- if variant. abi == Abi :: Uninhabited {
963
- continue ;
964
- }
965
982
match variant. fields {
966
983
FieldPlacement :: Arbitrary { ref mut offsets, .. } => {
967
984
for i in offsets {
@@ -1055,6 +1072,11 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
1055
1072
}
1056
1073
}
1057
1074
}
1075
+
1076
+ if layout_variants. iter ( ) . all ( |v| v. abi == Abi :: Uninhabited ) {
1077
+ abi = Abi :: Uninhabited ;
1078
+ }
1079
+
1058
1080
tcx. intern_layout ( LayoutDetails {
1059
1081
variants : Variants :: Tagged {
1060
1082
tag,
@@ -1523,9 +1545,14 @@ impl<'a, 'tcx, C> TyLayoutMethods<'tcx, C> for Ty<'tcx>
1523
1545
ty:: TyAdt ( def, _) => def. variants [ variant_index] . fields . len ( ) ,
1524
1546
_ => bug ! ( )
1525
1547
} ;
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
+ } )
1529
1556
}
1530
1557
1531
1558
Variants :: NicheFilling { ref variants, .. } |
0 commit comments