1
- use self :: EnumTagInfo :: * ;
2
1
use self :: MemberDescriptionFactory :: * ;
3
2
use self :: RecursiveTypeDescription :: * ;
4
3
@@ -28,7 +27,7 @@ use rustc_hir::def::CtorKind;
28
27
use rustc_hir:: def_id:: { DefId , LOCAL_CRATE } ;
29
28
use rustc_index:: vec:: { Idx , IndexVec } ;
30
29
use rustc_middle:: ich:: NodeIdHashingMode ;
31
- use rustc_middle:: mir:: { self , Field , GeneratorLayout } ;
30
+ use rustc_middle:: mir:: { self , GeneratorLayout } ;
32
31
use rustc_middle:: ty:: layout:: { self , IntegerExt , PrimitiveExt , TyAndLayout } ;
33
32
use rustc_middle:: ty:: subst:: GenericArgKind ;
34
33
use rustc_middle:: ty:: Instance ;
@@ -1188,7 +1187,7 @@ enum MemberDescriptionFactory<'ll, 'tcx> {
1188
1187
TupleMDF ( TupleMemberDescriptionFactory < ' tcx > ) ,
1189
1188
EnumMDF ( EnumMemberDescriptionFactory < ' ll , ' tcx > ) ,
1190
1189
UnionMDF ( UnionMemberDescriptionFactory < ' tcx > ) ,
1191
- VariantMDF ( VariantMemberDescriptionFactory < ' ll , ' tcx > ) ,
1190
+ VariantMDF ( VariantMemberDescriptionFactory < ' tcx > ) ,
1192
1191
}
1193
1192
1194
1193
impl MemberDescriptionFactory < ' ll , ' tcx > {
@@ -1505,14 +1504,8 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
1505
1504
}
1506
1505
1507
1506
let variant_info = variant_info_for ( index) ;
1508
- let ( variant_type_metadata, member_description_factory) = describe_enum_variant (
1509
- cx,
1510
- self . layout ,
1511
- variant_info,
1512
- None ,
1513
- self_metadata,
1514
- self . span ,
1515
- ) ;
1507
+ let ( variant_type_metadata, member_description_factory) =
1508
+ describe_enum_variant ( cx, self . layout , variant_info, self_metadata, self . span ) ;
1516
1509
1517
1510
let member_descriptions = member_description_factory. create_member_descriptions ( cx) ;
1518
1511
@@ -1524,7 +1517,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
1524
1517
Some ( & self . common_members ) ,
1525
1518
) ;
1526
1519
vec ! [ MemberDescription {
1527
- name: if fallback { String :: new ( ) } else { variant_info. variant_name( ) } ,
1520
+ name: variant_info. variant_name( ) ,
1528
1521
type_metadata: variant_type_metadata,
1529
1522
offset: Size :: ZERO ,
1530
1523
size: self . layout. size,
@@ -1540,28 +1533,38 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
1540
1533
ref variants,
1541
1534
..
1542
1535
} => {
1543
- let tag_info = if fallback {
1544
- // For MSVC, we generate a union of structs for each variant with an explicit
1545
- // discriminant field roughly equivalent to the following C:
1536
+ let fallback_discr_variant = if fallback {
1537
+ // For MSVC, we generate a union of structs for each variant and an
1538
+ // explicit discriminant field roughly equivalent to the following C:
1546
1539
// ```c
1547
1540
// union enum$<{name}> {
1548
1541
// struct {variant 0 name} {
1549
- // tag$ variant$;
1550
1542
// <variant 0 fields>
1551
1543
// } variant0;
1552
1544
// <other variant structs>
1545
+ // {name} discriminant;
1553
1546
// }
1554
1547
// ```
1555
- // The natvis in `intrinsic.nativs ` then matches on `this.variant0.variant$ ` to
1548
+ // The natvis in `intrinsic.natvis ` then matches on `this.discriminant ` to
1556
1549
// determine which variant is active and then displays it.
1557
- Some ( DirectTag {
1558
- tag_field : Field :: from ( tag_field) ,
1559
- tag_type_metadata : self . tag_type_metadata . unwrap ( ) ,
1550
+ let enum_layout = self . layout ;
1551
+ let offset = enum_layout. fields . offset ( tag_field) ;
1552
+ let discr_ty = enum_layout. field ( cx, tag_field) . ty ;
1553
+ let ( size, align) = cx. size_and_align_of ( discr_ty) ;
1554
+ Some ( MemberDescription {
1555
+ name : "discriminant" . into ( ) ,
1556
+ type_metadata : self . tag_type_metadata . unwrap ( ) ,
1557
+ offset,
1558
+ size,
1559
+ align,
1560
+ flags : DIFlags :: FlagZero ,
1561
+ discriminant : None ,
1562
+ source_info : None ,
1560
1563
} )
1561
1564
} else {
1562
- // This doesn't matter in this case.
1563
1565
None
1564
1566
} ;
1567
+
1565
1568
variants
1566
1569
. iter_enumerated ( )
1567
1570
. map ( |( i, _) | {
@@ -1571,7 +1574,6 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
1571
1574
cx,
1572
1575
variant,
1573
1576
variant_info,
1574
- tag_info,
1575
1577
self_metadata,
1576
1578
self . span ,
1577
1579
) ;
@@ -1605,6 +1607,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
1605
1607
source_info : variant_info. source_info ( cx) ,
1606
1608
}
1607
1609
} )
1610
+ . chain ( fallback_discr_variant. into_iter ( ) )
1608
1611
. collect ( )
1609
1612
}
1610
1613
Variants :: Multiple {
@@ -1702,7 +1705,6 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
1702
1705
cx,
1703
1706
dataful_variant_layout,
1704
1707
variant_info,
1705
- Some ( NicheTag ) ,
1706
1708
self_metadata,
1707
1709
self . span ,
1708
1710
) ;
@@ -1754,7 +1756,6 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
1754
1756
cx,
1755
1757
variant,
1756
1758
variant_info,
1757
- Some ( NicheTag ) ,
1758
1759
self_metadata,
1759
1760
self . span ,
1760
1761
) ;
@@ -1791,39 +1792,27 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
1791
1792
}
1792
1793
1793
1794
// Creates `MemberDescription`s for the fields of a single enum variant.
1794
- struct VariantMemberDescriptionFactory < ' ll , ' tcx > {
1795
+ struct VariantMemberDescriptionFactory < ' tcx > {
1795
1796
/// Cloned from the `layout::Struct` describing the variant.
1796
1797
offsets : Vec < Size > ,
1797
1798
args : Vec < ( String , Ty < ' tcx > ) > ,
1798
- tag_type_metadata : Option < & ' ll DIType > ,
1799
1799
span : Span ,
1800
1800
}
1801
1801
1802
- impl VariantMemberDescriptionFactory < ' ll , ' tcx > {
1802
+ impl VariantMemberDescriptionFactory < ' tcx > {
1803
1803
fn create_member_descriptions ( & self , cx : & CodegenCx < ' ll , ' tcx > ) -> Vec < MemberDescription < ' ll > > {
1804
1804
self . args
1805
1805
. iter ( )
1806
1806
. enumerate ( )
1807
1807
. map ( |( i, & ( ref name, ty) ) | {
1808
- // Discriminant is always the first field of our variant
1809
- // when using the enum fallback.
1810
- let is_artificial_discr = use_enum_fallback ( cx) && i == 0 ;
1811
1808
let ( size, align) = cx. size_and_align_of ( ty) ;
1812
1809
MemberDescription {
1813
1810
name : name. to_string ( ) ,
1814
- type_metadata : if is_artificial_discr {
1815
- self . tag_type_metadata . unwrap_or_else ( || type_metadata ( cx, ty, self . span ) )
1816
- } else {
1817
- type_metadata ( cx, ty, self . span )
1818
- } ,
1811
+ type_metadata : type_metadata ( cx, ty, self . span ) ,
1819
1812
offset : self . offsets [ i] ,
1820
1813
size,
1821
1814
align,
1822
- flags : if is_artificial_discr {
1823
- DIFlags :: FlagArtificial
1824
- } else {
1825
- DIFlags :: FlagZero
1826
- } ,
1815
+ flags : DIFlags :: FlagZero ,
1827
1816
discriminant : None ,
1828
1817
source_info : None ,
1829
1818
}
@@ -1832,12 +1821,6 @@ impl VariantMemberDescriptionFactory<'ll, 'tcx> {
1832
1821
}
1833
1822
}
1834
1823
1835
- #[ derive( Copy , Clone ) ]
1836
- enum EnumTagInfo < ' ll > {
1837
- DirectTag { tag_field : Field , tag_type_metadata : & ' ll DIType } ,
1838
- NicheTag ,
1839
- }
1840
-
1841
1824
#[ derive( Copy , Clone ) ]
1842
1825
enum VariantInfo < ' a , ' tcx > {
1843
1826
Adt ( & ' tcx ty:: VariantDef ) ,
@@ -1916,7 +1899,6 @@ fn describe_enum_variant(
1916
1899
cx : & CodegenCx < ' ll , ' tcx > ,
1917
1900
layout : layout:: TyAndLayout < ' tcx > ,
1918
1901
variant : VariantInfo < ' _ , ' tcx > ,
1919
- discriminant_info : Option < EnumTagInfo < ' ll > > ,
1920
1902
containing_scope : & ' ll DIScope ,
1921
1903
span : Span ,
1922
1904
) -> ( & ' ll DICompositeType , MemberDescriptionFactory < ' ll , ' tcx > ) {
@@ -1935,50 +1917,13 @@ fn describe_enum_variant(
1935
1917
)
1936
1918
} ) ;
1937
1919
1938
- // Build an array of (field name, field type) pairs to be captured in the factory closure.
1939
- let ( offsets, args) = if use_enum_fallback ( cx) {
1940
- // If this is not a univariant enum, there is also the discriminant field.
1941
- let ( discr_offset, discr_arg) = match discriminant_info {
1942
- Some ( DirectTag { tag_field, .. } ) => {
1943
- // We have the layout of an enum variant, we need the layout of the outer enum
1944
- let enum_layout = cx. layout_of ( layout. ty ) ;
1945
- let offset = enum_layout. fields . offset ( tag_field. as_usize ( ) ) ;
1946
- let args = ( "variant$" . to_owned ( ) , enum_layout. field ( cx, tag_field. as_usize ( ) ) . ty ) ;
1947
- ( Some ( offset) , Some ( args) )
1948
- }
1949
- _ => ( None , None ) ,
1950
- } ;
1951
- (
1952
- discr_offset
1953
- . into_iter ( )
1954
- . chain ( ( 0 ..layout. fields . count ( ) ) . map ( |i| layout. fields . offset ( i) ) )
1955
- . collect ( ) ,
1956
- discr_arg
1957
- . into_iter ( )
1958
- . chain (
1959
- ( 0 ..layout. fields . count ( ) )
1960
- . map ( |i| ( variant. field_name ( i) , layout. field ( cx, i) . ty ) ) ,
1961
- )
1962
- . collect ( ) ,
1963
- )
1964
- } else {
1965
- (
1966
- ( 0 ..layout. fields . count ( ) ) . map ( |i| layout. fields . offset ( i) ) . collect ( ) ,
1967
- ( 0 ..layout. fields . count ( ) )
1968
- . map ( |i| ( variant. field_name ( i) , layout. field ( cx, i) . ty ) )
1969
- . collect ( ) ,
1970
- )
1971
- } ;
1920
+ let offsets = ( 0 ..layout. fields . count ( ) ) . map ( |i| layout. fields . offset ( i) ) . collect ( ) ;
1921
+ let args = ( 0 ..layout. fields . count ( ) )
1922
+ . map ( |i| ( variant. field_name ( i) , layout. field ( cx, i) . ty ) )
1923
+ . collect ( ) ;
1972
1924
1973
- let member_description_factory = VariantMDF ( VariantMemberDescriptionFactory {
1974
- offsets,
1975
- args,
1976
- tag_type_metadata : match discriminant_info {
1977
- Some ( DirectTag { tag_type_metadata, .. } ) => Some ( tag_type_metadata) ,
1978
- _ => None ,
1979
- } ,
1980
- span,
1981
- } ) ;
1925
+ let member_description_factory =
1926
+ VariantMDF ( VariantMemberDescriptionFactory { offsets, args, span } ) ;
1982
1927
1983
1928
( metadata_stub, member_description_factory)
1984
1929
}
0 commit comments