1- use self :: EnumTagInfo :: * ;
21use self :: MemberDescriptionFactory :: * ;
32use self :: RecursiveTypeDescription :: * ;
43
@@ -28,7 +27,7 @@ use rustc_hir::def::CtorKind;
2827use rustc_hir:: def_id:: { DefId , LOCAL_CRATE } ;
2928use rustc_index:: vec:: { Idx , IndexVec } ;
3029use rustc_middle:: ich:: NodeIdHashingMode ;
31- use rustc_middle:: mir:: { self , Field , GeneratorLayout } ;
30+ use rustc_middle:: mir:: { self , GeneratorLayout } ;
3231use rustc_middle:: ty:: layout:: { self , IntegerExt , PrimitiveExt , TyAndLayout } ;
3332use rustc_middle:: ty:: subst:: GenericArgKind ;
3433use rustc_middle:: ty:: Instance ;
@@ -1188,7 +1187,7 @@ enum MemberDescriptionFactory<'ll, 'tcx> {
11881187 TupleMDF ( TupleMemberDescriptionFactory < ' tcx > ) ,
11891188 EnumMDF ( EnumMemberDescriptionFactory < ' ll , ' tcx > ) ,
11901189 UnionMDF ( UnionMemberDescriptionFactory < ' tcx > ) ,
1191- VariantMDF ( VariantMemberDescriptionFactory < ' ll , ' tcx > ) ,
1190+ VariantMDF ( VariantMemberDescriptionFactory < ' tcx > ) ,
11921191}
11931192
11941193impl MemberDescriptionFactory < ' ll , ' tcx > {
@@ -1505,14 +1504,8 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
15051504 }
15061505
15071506 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 ) ;
15161509
15171510 let member_descriptions = member_description_factory. create_member_descriptions ( cx) ;
15181511
@@ -1524,7 +1517,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
15241517 Some ( & self . common_members ) ,
15251518 ) ;
15261519 vec ! [ MemberDescription {
1527- name: if fallback { String :: new ( ) } else { variant_info. variant_name( ) } ,
1520+ name: variant_info. variant_name( ) ,
15281521 type_metadata: variant_type_metadata,
15291522 offset: Size :: ZERO ,
15301523 size: self . layout. size,
@@ -1540,28 +1533,38 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
15401533 ref variants,
15411534 ..
15421535 } => {
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:
15461539 // ```c
15471540 // union enum$<{name}> {
15481541 // struct {variant 0 name} {
1549- // tag$ variant$;
15501542 // <variant 0 fields>
15511543 // } variant0;
15521544 // <other variant structs>
1545+ // {name} discriminant;
15531546 // }
15541547 // ```
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
15561549 // 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 ,
15601563 } )
15611564 } else {
1562- // This doesn't matter in this case.
15631565 None
15641566 } ;
1567+
15651568 variants
15661569 . iter_enumerated ( )
15671570 . map ( |( i, _) | {
@@ -1571,7 +1574,6 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
15711574 cx,
15721575 variant,
15731576 variant_info,
1574- tag_info,
15751577 self_metadata,
15761578 self . span ,
15771579 ) ;
@@ -1605,6 +1607,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
16051607 source_info : variant_info. source_info ( cx) ,
16061608 }
16071609 } )
1610+ . chain ( fallback_discr_variant. into_iter ( ) )
16081611 . collect ( )
16091612 }
16101613 Variants :: Multiple {
@@ -1702,7 +1705,6 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
17021705 cx,
17031706 dataful_variant_layout,
17041707 variant_info,
1705- Some ( NicheTag ) ,
17061708 self_metadata,
17071709 self . span ,
17081710 ) ;
@@ -1754,7 +1756,6 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
17541756 cx,
17551757 variant,
17561758 variant_info,
1757- Some ( NicheTag ) ,
17581759 self_metadata,
17591760 self . span ,
17601761 ) ;
@@ -1791,39 +1792,27 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
17911792}
17921793
17931794// Creates `MemberDescription`s for the fields of a single enum variant.
1794- struct VariantMemberDescriptionFactory < ' ll , ' tcx > {
1795+ struct VariantMemberDescriptionFactory < ' tcx > {
17951796 /// Cloned from the `layout::Struct` describing the variant.
17961797 offsets : Vec < Size > ,
17971798 args : Vec < ( String , Ty < ' tcx > ) > ,
1798- tag_type_metadata : Option < & ' ll DIType > ,
17991799 span : Span ,
18001800}
18011801
1802- impl VariantMemberDescriptionFactory < ' ll , ' tcx > {
1802+ impl VariantMemberDescriptionFactory < ' tcx > {
18031803 fn create_member_descriptions ( & self , cx : & CodegenCx < ' ll , ' tcx > ) -> Vec < MemberDescription < ' ll > > {
18041804 self . args
18051805 . iter ( )
18061806 . enumerate ( )
18071807 . 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 ;
18111808 let ( size, align) = cx. size_and_align_of ( ty) ;
18121809 MemberDescription {
18131810 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 ) ,
18191812 offset : self . offsets [ i] ,
18201813 size,
18211814 align,
1822- flags : if is_artificial_discr {
1823- DIFlags :: FlagArtificial
1824- } else {
1825- DIFlags :: FlagZero
1826- } ,
1815+ flags : DIFlags :: FlagZero ,
18271816 discriminant : None ,
18281817 source_info : None ,
18291818 }
@@ -1832,12 +1821,6 @@ impl VariantMemberDescriptionFactory<'ll, 'tcx> {
18321821 }
18331822}
18341823
1835- #[ derive( Copy , Clone ) ]
1836- enum EnumTagInfo < ' ll > {
1837- DirectTag { tag_field : Field , tag_type_metadata : & ' ll DIType } ,
1838- NicheTag ,
1839- }
1840-
18411824#[ derive( Copy , Clone ) ]
18421825enum VariantInfo < ' a , ' tcx > {
18431826 Adt ( & ' tcx ty:: VariantDef ) ,
@@ -1916,7 +1899,6 @@ fn describe_enum_variant(
19161899 cx : & CodegenCx < ' ll , ' tcx > ,
19171900 layout : layout:: TyAndLayout < ' tcx > ,
19181901 variant : VariantInfo < ' _ , ' tcx > ,
1919- discriminant_info : Option < EnumTagInfo < ' ll > > ,
19201902 containing_scope : & ' ll DIScope ,
19211903 span : Span ,
19221904) -> ( & ' ll DICompositeType , MemberDescriptionFactory < ' ll , ' tcx > ) {
@@ -1935,50 +1917,13 @@ fn describe_enum_variant(
19351917 )
19361918 } ) ;
19371919
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 ( ) ;
19721924
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 } ) ;
19821927
19831928 ( metadata_stub, member_description_factory)
19841929}
0 commit comments