Skip to content

Commit 3780684

Browse files
committed
Update directly tagged enums to visualize the same as niche-layout enums
Previously, directly tagged enums had a `variant$` field which would show the name of the active variant. We now show the variant using a `[variant]` synthetic item just like we do for niche-layout enums.
1 parent 798baeb commit 3780684

File tree

4 files changed

+61
-95
lines changed

4 files changed

+61
-95
lines changed

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

Lines changed: 34 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use self::EnumTagInfo::*;
21
use self::MemberDescriptionFactory::*;
32
use self::RecursiveTypeDescription::*;
43

@@ -28,7 +27,7 @@ use rustc_hir::def::CtorKind;
2827
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
2928
use rustc_index::vec::{Idx, IndexVec};
3029
use rustc_middle::ich::NodeIdHashingMode;
31-
use rustc_middle::mir::{self, Field, GeneratorLayout};
30+
use rustc_middle::mir::{self, GeneratorLayout};
3231
use rustc_middle::ty::layout::{self, IntegerExt, PrimitiveExt, TyAndLayout};
3332
use rustc_middle::ty::subst::GenericArgKind;
3433
use 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

11941193
impl 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

@@ -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.nativs` 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)]
18421825
enum 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
}

src/etc/natvis/intrinsic.natvis

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@
150150
</Expand>
151151
</Type>
152152
<Type Name="enum$&lt;*&gt;">
153-
<Intrinsic Name="tag" Expression="variant0.variant$" />
153+
<Intrinsic Name="tag" Expression="discriminant" />
154154
<DisplayString Condition="tag() == 0">{tag(),en}</DisplayString>
155155
<DisplayString Condition="tag() == 1" Optional="true">{tag(),en}</DisplayString>
156156
<DisplayString Condition="tag() == 2" Optional="true">{tag(),en}</DisplayString>
@@ -169,6 +169,9 @@
169169
<DisplayString Condition="tag() == 15" Optional="true">{tag(),en}</DisplayString>
170170

171171
<Expand>
172+
<Synthetic Name="[variant]">
173+
<DisplayString>{tag(),en}</DisplayString>
174+
</Synthetic>
172175
<ExpandedItem Condition="tag() == 0">variant0</ExpandedItem>
173176
<ExpandedItem Condition="tag() == 1" Optional="true">variant1</ExpandedItem>
174177
<ExpandedItem Condition="tag() == 2" Optional="true">variant2</ExpandedItem>

src/test/debuginfo/msvc-pretty-enums.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,30 @@
4848
// cdb-check: [+0x000] __0 : 0x0 [Type: unsigned int *]
4949
// cdb-check: [+0x000] discriminant : None (0x0) [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>::Discriminant$]
5050

51+
// cdb-command: dx -r2 h,!
52+
// cdb-check:h,! : Some [Type: enum$<core::option::Option<u32> >]
53+
// cdb-check: [+0x000] variant0 [Type: enum$<core::option::Option<u32> >::None]
54+
// cdb-check: [+0x000] variant1 [Type: enum$<core::option::Option<u32> >::Some]
55+
// cdb-check: [+0x004] __0 : 0xc [Type: unsigned int]
56+
// cdb-check: [+0x000] discriminant : Some (0x1) [Type: core::option::Option]
57+
5158
// cdb-command: dx h
5259
// cdb-check:h : Some [Type: enum$<core::option::Option<u32> >]
53-
// cdb-check: [+0x000] variant$ : Some (0x1) [Type: core::option::Option]
60+
// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<u32> >]
61+
// cdb-check: [variant] : Some
5462
// cdb-check: [+0x004] __0 : 0xc [Type: unsigned int]
5563

64+
// cdb-command: dx -r2 i,!
65+
// cdb-check:i,! : None [Type: enum$<core::option::Option<u32> >]
66+
// cdb-check: [+0x000] variant0 [Type: enum$<core::option::Option<u32> >::None]
67+
// cdb-check: [+0x000] variant1 [Type: enum$<core::option::Option<u32> >::Some]
68+
// cdb-check: [+0x004] __0 : 0x5c0065 [Type: unsigned int]
69+
// cdb-check: [+0x000] discriminant : None (0x0) [Type: core::option::Option]
70+
5671
// cdb-command: dx i
5772
// cdb-check:i : None [Type: enum$<core::option::Option<u32> >]
58-
// cdb-check: [+0x000] variant$ : None (0x0) [Type: core::option::Option]
73+
// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<u32> >]
74+
// cdb-check: [variant] : None
5975

6076
// cdb-command: dx j
6177
// cdb-check:j : High (0x10) [Type: msvc_pretty_enums::CStyleEnum]

src/test/debuginfo/pretty-std.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,14 @@
116116

117117
// cdb-command: dx some
118118
// cdb-check:some : Some [Type: enum$<core::option::Option<i16> >]
119-
// cdb-check: [...] variant$ : Some (0x1) [Type: core::option::Option]
120-
// cdb-check: [...] __0 : 8 [Type: short]
119+
// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<i16> >]
120+
// cdb-check: [variant] : Some
121+
// cdb-check: [+0x002] __0 : 8 [Type: short]
121122

122123
// cdb-command: dx none
123124
// cdb-check:none : None [Type: enum$<core::option::Option<i64> >]
124-
// cdb-check: [...] variant$ : None (0x0) [Type: core::option::Option]
125+
// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<i64> >]
126+
// cdb-check: [variant] : None
125127

126128
// cdb-command: dx some_string
127129
// NOTE: cdb fails to interpret debug info of Option enums on i686.

0 commit comments

Comments
 (0)