@@ -1534,6 +1534,19 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
15341534 ..
15351535 } => {
15361536 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.
15371550 Some ( DirectTag {
15381551 tag_field : Field :: from ( tag_field) ,
15391552 tag_type_metadata : self . tag_type_metadata . unwrap ( ) ,
@@ -1613,6 +1626,25 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
16131626 // For MSVC, we will generate a union of two structs, one for the dataful variant and one that just points to
16141627 // the discriminant field. We also create an enum that contains tag values for the non-dataful variants and
16151628 // 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.
16161648 if fallback {
16171649 let unique_type_id = debug_context ( cx)
16181650 . type_map
@@ -1938,9 +1970,7 @@ fn describe_enum_variant(
19381970 // We have the layout of an enum variant, we need the layout of the outer enum
19391971 let enum_layout = cx. layout_of ( layout. ty ) ;
19401972 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 ) ;
19441974 ( Some ( offset) , Some ( args) )
19451975 }
19461976 _ => ( None , None ) ,
0 commit comments