@@ -1404,7 +1404,6 @@ impl AddressSpace {
1404
1404
#[ derive( Clone , Copy , PartialEq , Eq , Hash , Debug ) ]
1405
1405
#[ cfg_attr( feature = "nightly" , derive( HashStable_Generic ) ) ]
1406
1406
pub enum BackendRepr {
1407
- Uninhabited ,
1408
1407
Scalar ( Scalar ) ,
1409
1408
ScalarPair ( Scalar , Scalar ) ,
1410
1409
Vector {
@@ -1423,10 +1422,9 @@ impl BackendRepr {
1423
1422
#[ inline]
1424
1423
pub fn is_unsized ( & self ) -> bool {
1425
1424
match * self {
1426
- BackendRepr :: Uninhabited
1427
- | BackendRepr :: Scalar ( _)
1428
- | BackendRepr :: ScalarPair ( ..)
1429
- | BackendRepr :: Vector { .. } => false ,
1425
+ BackendRepr :: Scalar ( _) | BackendRepr :: ScalarPair ( ..) | BackendRepr :: Vector { .. } => {
1426
+ false
1427
+ }
1430
1428
BackendRepr :: Memory { sized } => !sized,
1431
1429
}
1432
1430
}
@@ -1445,12 +1443,6 @@ impl BackendRepr {
1445
1443
}
1446
1444
}
1447
1445
1448
- /// Returns `true` if this is an uninhabited type
1449
- #[ inline]
1450
- pub fn is_uninhabited ( & self ) -> bool {
1451
- matches ! ( * self , BackendRepr :: Uninhabited )
1452
- }
1453
-
1454
1446
/// Returns `true` if this is a scalar type
1455
1447
#[ inline]
1456
1448
pub fn is_scalar ( & self ) -> bool {
@@ -1471,7 +1463,7 @@ impl BackendRepr {
1471
1463
BackendRepr :: Vector { element, count } => {
1472
1464
cx. data_layout ( ) . vector_align ( element. size ( cx) * count)
1473
1465
}
1474
- BackendRepr :: Uninhabited | BackendRepr :: Memory { .. } => return None ,
1466
+ BackendRepr :: Memory { .. } => return None ,
1475
1467
} )
1476
1468
}
1477
1469
@@ -1492,7 +1484,7 @@ impl BackendRepr {
1492
1484
// to make the size a multiple of align (e.g. for vectors of size 3).
1493
1485
( element. size ( cx) * count) . align_to ( self . inherent_align ( cx) ?. abi )
1494
1486
}
1495
- BackendRepr :: Uninhabited | BackendRepr :: Memory { .. } => return None ,
1487
+ BackendRepr :: Memory { .. } => return None ,
1496
1488
} )
1497
1489
}
1498
1490
@@ -1506,9 +1498,7 @@ impl BackendRepr {
1506
1498
BackendRepr :: Vector { element, count } => {
1507
1499
BackendRepr :: Vector { element : element. to_union ( ) , count }
1508
1500
}
1509
- BackendRepr :: Uninhabited | BackendRepr :: Memory { .. } => {
1510
- BackendRepr :: Memory { sized : true }
1511
- }
1501
+ BackendRepr :: Memory { .. } => BackendRepr :: Memory { sized : true } ,
1512
1502
}
1513
1503
}
1514
1504
@@ -1704,6 +1694,11 @@ pub struct LayoutData<FieldIdx: Idx, VariantIdx: Idx> {
1704
1694
/// The leaf scalar with the largest number of invalid values
1705
1695
/// (i.e. outside of its `valid_range`), if it exists.
1706
1696
pub largest_niche : Option < Niche > ,
1697
+ /// Is this type known to be uninhabted?
1698
+ ///
1699
+ /// This is separate from BackendRepr because uninhabited return types can affect ABI,
1700
+ /// especially in the case of by-pointer struct returns, which allocate stack even when unused.
1701
+ pub uninhabited : bool ,
1707
1702
1708
1703
pub align : AbiAndPrefAlign ,
1709
1704
pub size : Size ,
@@ -1735,14 +1730,14 @@ impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
1735
1730
/// Returns `true` if this is an aggregate type (including a ScalarPair!)
1736
1731
pub fn is_aggregate ( & self ) -> bool {
1737
1732
match self . backend_repr {
1738
- BackendRepr :: Uninhabited | BackendRepr :: Scalar ( _) | BackendRepr :: Vector { .. } => false ,
1733
+ BackendRepr :: Scalar ( _) | BackendRepr :: Vector { .. } => false ,
1739
1734
BackendRepr :: ScalarPair ( ..) | BackendRepr :: Memory { .. } => true ,
1740
1735
}
1741
1736
}
1742
1737
1743
1738
/// Returns `true` if this is an uninhabited type
1744
1739
pub fn is_uninhabited ( & self ) -> bool {
1745
- self . backend_repr . is_uninhabited ( )
1740
+ self . uninhabited
1746
1741
}
1747
1742
1748
1743
pub fn scalar < C : HasDataLayout > ( cx : & C , scalar : Scalar ) -> Self {
@@ -1778,6 +1773,7 @@ impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
1778
1773
fields : FieldsShape :: Primitive ,
1779
1774
backend_repr : BackendRepr :: Scalar ( scalar) ,
1780
1775
largest_niche,
1776
+ uninhabited : false ,
1781
1777
size,
1782
1778
align,
1783
1779
max_repr_align : None ,
@@ -1802,6 +1798,7 @@ where
1802
1798
backend_repr,
1803
1799
fields,
1804
1800
largest_niche,
1801
+ uninhabited,
1805
1802
variants,
1806
1803
max_repr_align,
1807
1804
unadjusted_abi_align,
@@ -1813,6 +1810,7 @@ where
1813
1810
. field ( "abi" , backend_repr)
1814
1811
. field ( "fields" , fields)
1815
1812
. field ( "largest_niche" , largest_niche)
1813
+ . field ( "uninhabited" , uninhabited)
1816
1814
. field ( "variants" , variants)
1817
1815
. field ( "max_repr_align" , max_repr_align)
1818
1816
. field ( "unadjusted_abi_align" , unadjusted_abi_align)
@@ -1877,7 +1875,6 @@ impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
1877
1875
BackendRepr :: Scalar ( _) | BackendRepr :: ScalarPair ( ..) | BackendRepr :: Vector { .. } => {
1878
1876
false
1879
1877
}
1880
- BackendRepr :: Uninhabited => self . size . bytes ( ) == 0 ,
1881
1878
BackendRepr :: Memory { sized } => sized && self . size . bytes ( ) == 0 ,
1882
1879
}
1883
1880
}
0 commit comments