@@ -1534,6 +1534,19 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
1534
1534
..
1535
1535
} => {
1536
1536
let tag_info = if fallback {
1537
+ // For MSVC, we generate a union of structs for each variant with an explicit
1538
+ // discriminant field roughly equivalent to the following C:
1539
+ // ```c
1540
+ // union _enum<{name}> {
1541
+ // struct {variant 0 name} {
1542
+ // tag$ variant$;
1543
+ // <variant 0 fields>
1544
+ // } Variant0;
1545
+ // <other variant structs>
1546
+ // }
1547
+ // ```
1548
+ // The natvis in `intrinsic.nativs` then matches on `this.Variant0.variant$` to
1549
+ // determine which variant is active and then displays it.
1537
1550
Some ( DirectTag {
1538
1551
tag_field : Field :: from ( tag_field) ,
1539
1552
tag_type_metadata : self . tag_type_metadata . unwrap ( ) ,
@@ -1613,6 +1626,25 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
1613
1626
// For MSVC, we will generate a union of two structs, one for the dataful variant and one that just points to
1614
1627
// the discriminant field. We also create an enum that contains tag values for the non-dataful variants and
1615
1628
// make the discriminant field that type. We then use natvis to render the enum type correctly in Windbg/VS.
1629
+ // This will generate debuginfo roughly equivalent to the following C:
1630
+ // ```c
1631
+ // union _enum<{name}, {min niche}, {max niche}, {dataful variant name} {
1632
+ // struct dataful_variant {
1633
+ // <fields in dataful variant>
1634
+ // },
1635
+ // struct discriminant$ {
1636
+ // enum tag$ {
1637
+ // <non-dataful variants>
1638
+ // } discriminant;
1639
+ // }
1640
+ // }
1641
+ // ```
1642
+ // The natvis in `intrinsic.natvis` matches on the type name `_enum<*, *, *, *>`
1643
+ // and evaluates `this.discriminant$.discriminant`. If the value is between
1644
+ // the min niche and max niche, then the enum is in the dataful variant and
1645
+ // `this.dataful_variant` is rendered. Otherwise, the enum is in one of the
1646
+ // non-dataful variants. In that case, we just need to render the name of the
1647
+ // `this.discriminant$.discriminant` enum.
1616
1648
if fallback {
1617
1649
let unique_type_id = debug_context ( cx)
1618
1650
. type_map
@@ -1938,9 +1970,7 @@ fn describe_enum_variant(
1938
1970
// We have the layout of an enum variant, we need the layout of the outer enum
1939
1971
let enum_layout = cx. layout_of ( layout. ty ) ;
1940
1972
let offset = enum_layout. fields . offset ( tag_field. as_usize ( ) ) ;
1941
- let tag_name =
1942
- if cx. tcx . sess . target . is_like_msvc { "variant$" } else { "RUST$ENUM$DISR" } ;
1943
- let args = ( tag_name. to_owned ( ) , enum_layout. field ( cx, tag_field. as_usize ( ) ) . ty ) ;
1973
+ let args = ( "variant$" . to_owned ( ) , enum_layout. field ( cx, tag_field. as_usize ( ) ) . ty ) ;
1944
1974
( Some ( offset) , Some ( args) )
1945
1975
}
1946
1976
_ => ( None , None ) ,
0 commit comments