Skip to content

Commit 1995cd9

Browse files
committed
Remove artificial flag from generator variants
- Literally, variants are not artificial. We have `yield` statements, upvars and inner variables in the source code. - Functionally, we don't want debuggers to suppress the variants. It contains the state of the generator, which is useful when debugging. So they shouldn't be marked artificial. - Debuggers may use artificial flags to find the active variant. In this case, marking variants artificial will make debuggers not work properly. Fixes rust-lang#79009.
1 parent 060deec commit 1995cd9

File tree

7 files changed

+83
-70
lines changed

7 files changed

+83
-70
lines changed

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

+8-25
Original file line numberDiff line numberDiff line change
@@ -1495,10 +1495,6 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
14951495
} else {
14961496
type_metadata(cx, self.enum_type, self.span)
14971497
};
1498-
let flags = match self.enum_type.kind() {
1499-
ty::Generator(..) => DIFlags::FlagArtificial,
1500-
_ => DIFlags::FlagZero,
1501-
};
15021498

15031499
match self.layout.variants {
15041500
Variants::Single { index } => {
@@ -1533,7 +1529,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
15331529
offset: Size::ZERO,
15341530
size: self.layout.size,
15351531
align: self.layout.align.abi,
1536-
flags,
1532+
flags: DIFlags::FlagZero,
15371533
discriminant: None,
15381534
source_info: variant_info.source_info(cx),
15391535
}]
@@ -1588,7 +1584,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
15881584
offset: Size::ZERO,
15891585
size: self.layout.size,
15901586
align: self.layout.align.abi,
1591-
flags,
1587+
flags: DIFlags::FlagZero,
15921588
discriminant: Some(
15931589
self.layout.ty.discriminant_for_variant(cx.tcx, i).unwrap().val
15941590
as u64,
@@ -1672,7 +1668,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
16721668
offset: Size::ZERO,
16731669
size: variant.size,
16741670
align: variant.align.abi,
1675-
flags,
1671+
flags: DIFlags::FlagZero,
16761672
discriminant: None,
16771673
source_info: variant_info.source_info(cx),
16781674
}]
@@ -1723,7 +1719,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
17231719
offset: Size::ZERO,
17241720
size: self.layout.size,
17251721
align: self.layout.align.abi,
1726-
flags,
1722+
flags: DIFlags::FlagZero,
17271723
discriminant: niche_value,
17281724
source_info: variant_info.source_info(cx),
17291725
}
@@ -1855,13 +1851,6 @@ impl<'tcx> VariantInfo<'_, 'tcx> {
18551851
}
18561852
None
18571853
}
1858-
1859-
fn is_artificial(&self) -> bool {
1860-
match self {
1861-
VariantInfo::Generator { .. } => true,
1862-
VariantInfo::Adt(..) => false,
1863-
}
1864-
}
18651854
}
18661855

18671856
/// Returns a tuple of (1) `type_metadata_stub` of the variant, (2) a
@@ -1887,8 +1876,7 @@ fn describe_enum_variant(
18871876
&variant_name,
18881877
unique_type_id,
18891878
Some(containing_scope),
1890-
// FIXME(tmandry): This doesn't seem to have any effect.
1891-
if variant.is_artificial() { DIFlags::FlagArtificial } else { DIFlags::FlagZero },
1879+
DIFlags::FlagZero,
18921880
)
18931881
});
18941882

@@ -1951,11 +1939,6 @@ fn prepare_enum_metadata(
19511939
) -> RecursiveTypeDescription<'ll, 'tcx> {
19521940
let tcx = cx.tcx;
19531941
let enum_name = compute_debuginfo_type_name(tcx, enum_type, false);
1954-
// FIXME(tmandry): This doesn't seem to have any effect.
1955-
let enum_flags = match enum_type.kind() {
1956-
ty::Generator(..) => DIFlags::FlagArtificial,
1957-
_ => DIFlags::FlagZero,
1958-
};
19591942

19601943
let containing_scope = get_namespace_for_item(cx, enum_def_id);
19611944
// FIXME: This should emit actual file metadata for the enum, but we
@@ -2088,7 +2071,7 @@ fn prepare_enum_metadata(
20882071
UNKNOWN_LINE_NUMBER,
20892072
layout.size.bits(),
20902073
layout.align.abi.bits() as u32,
2091-
enum_flags,
2074+
DIFlags::FlagZero,
20922075
None,
20932076
0, // RuntimeLang
20942077
unique_type_id_str.as_ptr().cast(),
@@ -2210,7 +2193,7 @@ fn prepare_enum_metadata(
22102193
UNKNOWN_LINE_NUMBER,
22112194
layout.size.bits(),
22122195
layout.align.abi.bits() as u32,
2213-
enum_flags,
2196+
DIFlags::FlagZero,
22142197
discriminator_metadata,
22152198
empty_array,
22162199
variant_part_unique_type_id_str.as_ptr().cast(),
@@ -2239,7 +2222,7 @@ fn prepare_enum_metadata(
22392222
UNKNOWN_LINE_NUMBER,
22402223
layout.size.bits(),
22412224
layout.align.abi.bits() as u32,
2242-
enum_flags,
2225+
DIFlags::FlagZero,
22432226
None,
22442227
type_array,
22452228
0,

src/test/codegen/async-fn-debug-msvc.rs

+15-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Verify debuginfo for generators:
22
// - Each variant points to the file and line of its yield point
3-
// - The generator types and variants are marked artificial
4-
// - Captured vars from the source are not marked artificial
3+
// - The discriminants are marked artificial
4+
// - Other fields are not marked artificial
55
//
66
//
77
// compile-flags: -C debuginfo=2 --edition=2018
@@ -17,26 +17,32 @@ async fn async_fn_test() {
1717
// FIXME: No way to reliably check the filename.
1818

1919
// CHECK-DAG: [[ASYNC_FN:!.*]] = !DINamespace(name: "async_fn_test"
20-
// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "generator-0", scope: [[ASYNC_FN]], {{.*}}flags: DIFlagArtificial
20+
// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "generator-0", scope: [[ASYNC_FN]]
2121
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
2222
// For brevity, we only check the struct name and members of the last variant.
2323
// CHECK-SAME: file: [[FILE:![0-9]*]], line: 11,
24-
// CHECK-SAME: flags: DIFlagArtificial
24+
// CHECK-NOT: flags: DIFlagArtificial
25+
// CHECK-SAME: )
2526
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
2627
// CHECK-SAME: file: [[FILE]], line: 15,
27-
// CHECK-SAME: flags: DIFlagArtificial
28+
// CHECK-NOT: flags: DIFlagArtificial
29+
// CHECK-SAME: )
2830
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
2931
// CHECK-SAME: file: [[FILE]], line: 15,
30-
// CHECK-SAME: flags: DIFlagArtificial
32+
// CHECK-NOT: flags: DIFlagArtificial
33+
// CHECK-SAME: )
3134
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
3235
// CHECK-SAME: file: [[FILE]], line: 12,
33-
// CHECK-SAME: flags: DIFlagArtificial
36+
// CHECK-NOT: flags: DIFlagArtificial
37+
// CHECK-SAME: )
3438
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
3539
// CHECK-SAME: file: [[FILE]], line: 14,
3640
// CHECK-SAME: baseType: [[VARIANT:![0-9]*]]
37-
// CHECK-SAME: flags: DIFlagArtificial
41+
// CHECK-NOT: flags: DIFlagArtificial
42+
// CHECK-SAME: )
3843
// CHECK: [[S1:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[ASYNC_FN]],
39-
// CHECK-SAME: flags: DIFlagArtificial
44+
// CHECK-NOT: flags: DIFlagArtificial
45+
// CHECK-SAME: )
4046
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "RUST$ENUM$DISR", scope: [[S1]],
4147
// CHECK-SAME: flags: DIFlagArtificial
4248
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[S1]]

src/test/codegen/async-fn-debug.rs

+18-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Verify debuginfo for async fn:
22
// - Each variant points to the file and line of its yield point
3-
// - The generator types and variants are marked artificial
4-
// - Captured vars from the source are not marked artificial
3+
// - The discriminants are marked artificial
4+
// - Other fields are not marked artificial
55
//
66
//
77
// compile-flags: -C debuginfo=2 --edition=2018
@@ -17,29 +17,36 @@ async fn async_fn_test() {
1717
// FIXME: No way to reliably check the filename.
1818

1919
// CHECK-DAG: [[ASYNC_FN:!.*]] = !DINamespace(name: "async_fn_test"
20-
// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "generator-0", scope: [[ASYNC_FN]], {{.*}}flags: DIFlagArtificial
20+
// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "generator-0", scope: [[ASYNC_FN]]
2121
// CHECK: [[VARIANT:!.*]] = !DICompositeType(tag: DW_TAG_variant_part, scope: [[ASYNC_FN]],
22-
// CHECK-SAME: flags: DIFlagArtificial
22+
// CHECK-NOT: flags: DIFlagArtificial
2323
// CHECK-SAME: discriminator: [[DISC:![0-9]*]]
2424
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "0", scope: [[VARIANT]],
2525
// CHECK-SAME: file: [[FILE:![0-9]*]], line: 11,
26-
// CHECK-SAME: flags: DIFlagArtificial
26+
// CHECK-NOT: flags: DIFlagArtificial
27+
// CHECK-SAME: )
2728
// CHECK: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "Unresumed", scope: [[GEN]],
28-
// CHECK-SAME: flags: DIFlagArtificial
29+
// CHECK-NOT: flags: DIFlagArtificial
30+
// CHECK-SAME: )
2931
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "1", scope: [[VARIANT]],
3032
// CHECK-SAME: file: [[FILE]], line: 15,
31-
// CHECK-SAME: flags: DIFlagArtificial
33+
// CHECK-NOT: flags: DIFlagArtificial
34+
// CHECK-SAME: )
3235
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "2", scope: [[VARIANT]],
3336
// CHECK-SAME: file: [[FILE]], line: 15,
34-
// CHECK-SAME: flags: DIFlagArtificial
37+
// CHECK-NOT: flags: DIFlagArtificial
38+
// CHECK-SAME: )
3539
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "3", scope: [[VARIANT]],
3640
// CHECK-SAME: file: [[FILE]], line: 12,
37-
// CHECK-SAME: flags: DIFlagArtificial
41+
// CHECK-NOT: flags: DIFlagArtificial
42+
// CHECK-SAME: )
3843
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "4", scope: [[VARIANT]],
3944
// CHECK-SAME: file: [[FILE]], line: 14,
40-
// CHECK-SAME: flags: DIFlagArtificial
45+
// CHECK-NOT: flags: DIFlagArtificial
46+
// CHECK-SAME: )
4147
// CHECK: [[S1:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN]],
42-
// CHECK-SAME: flags: DIFlagArtificial
48+
// CHECK-NOT: flags: DIFlagArtificial
49+
// CHECK-SAME: )
4350
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[S1]]
4451
// CHECK-NOT: flags: DIFlagArtificial
4552
// CHECK-SAME: )

src/test/codegen/generator-debug-msvc.rs

+15-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Verify debuginfo for generators:
22
// - Each variant points to the file and line of its yield point
3-
// - The generator types and variants are marked artificial
4-
// - Captured vars from the source are not marked artificial
3+
// - The discriminants are marked artificial
4+
// - Other fields are not marked artificial
55
//
66
//
77
// compile-flags: -C debuginfo=2
@@ -21,26 +21,32 @@ fn generator_test() -> impl Generator<Yield = i32, Return = ()> {
2121
// FIXME: No way to reliably check the filename.
2222

2323
// CHECK-DAG: [[GEN_FN:!.*]] = !DINamespace(name: "generator_test"
24-
// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "generator-0", scope: [[GEN_FN]], {{.*}}flags: DIFlagArtificial
24+
// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "generator-0", scope: [[GEN_FN]]
2525
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
2626
// For brevity, we only check the struct name and members of the last variant.
2727
// CHECK-SAME: file: [[FILE:![0-9]*]], line: 14,
28-
// CHECK-SAME: flags: DIFlagArtificial
28+
// CHECK-NOT: flags: DIFlagArtificial
29+
// CHECK-SAME: )
2930
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
3031
// CHECK-SAME: file: [[FILE]], line: 18,
31-
// CHECK-SAME: flags: DIFlagArtificial
32+
// CHECK-NOT: flags: DIFlagArtificial
33+
// CHECK-SAME: )
3234
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
3335
// CHECK-SAME: file: [[FILE]], line: 18,
34-
// CHECK-SAME: flags: DIFlagArtificial
36+
// CHECK-NOT: flags: DIFlagArtificial
37+
// CHECK-SAME: )
3538
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
3639
// CHECK-SAME: file: [[FILE]], line: 15,
37-
// CHECK-SAME: flags: DIFlagArtificial
40+
// CHECK-NOT: flags: DIFlagArtificial
41+
// CHECK-SAME: )
3842
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
3943
// CHECK-SAME: file: [[FILE]], line: 17,
4044
// CHECK-SAME: baseType: [[VARIANT:![0-9]*]]
41-
// CHECK-SAME: flags: DIFlagArtificial
45+
// CHECK-NOT: flags: DIFlagArtificial
46+
// CHECK-SAME: )
4247
// CHECK: [[S1:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN_FN]],
43-
// CHECK-SAME: flags: DIFlagArtificial
48+
// CHECK-NOT: flags: DIFlagArtificial
49+
// CHECK-SAME: )
4450
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "RUST$ENUM$DISR", scope: [[S1]],
4551
// CHECK-SAME: flags: DIFlagArtificial
4652
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[S1]]

src/test/codegen/generator-debug.rs

+18-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Verify debuginfo for generators:
22
// - Each variant points to the file and line of its yield point
3-
// - The generator types and variants are marked artificial
4-
// - Captured vars from the source are not marked artificial
3+
// - The discriminants are marked artificial
4+
// - Other fields are not marked artificial
55
//
66
//
77
// compile-flags: -C debuginfo=2 --edition=2018
@@ -21,29 +21,36 @@ fn generator_test() -> impl Generator<Yield = i32, Return = ()> {
2121
// FIXME: No way to reliably check the filename.
2222

2323
// CHECK-DAG: [[GEN_FN:!.*]] = !DINamespace(name: "generator_test"
24-
// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "generator-0", scope: [[GEN_FN]], {{.*}}flags: DIFlagArtificial
24+
// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "generator-0", scope: [[GEN_FN]]
2525
// CHECK: [[VARIANT:!.*]] = !DICompositeType(tag: DW_TAG_variant_part, scope: [[GEN_FN]],
26-
// CHECK-SAME: flags: DIFlagArtificial
26+
// CHECK-NOT: flags: DIFlagArtificial
2727
// CHECK-SAME: discriminator: [[DISC:![0-9]*]]
2828
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "0", scope: [[VARIANT]],
2929
// CHECK-SAME: file: [[FILE:![0-9]*]], line: 14,
30-
// CHECK-SAME: flags: DIFlagArtificial
30+
// CHECK-NOT: flags: DIFlagArtificial
31+
// CHECK-SAME: )
3132
// CHECK: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "Unresumed", scope: [[GEN]],
32-
// CHECK-SAME: flags: DIFlagArtificial
33+
// CHECK-NOT: flags: DIFlagArtificial
34+
// CHECK-SAME: )
3335
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "1", scope: [[VARIANT]],
3436
// CHECK-SAME: file: [[FILE]], line: 18,
35-
// CHECK-SAME: flags: DIFlagArtificial
37+
// CHECK-NOT: flags: DIFlagArtificial
38+
// CHECK-SAME: )
3639
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "2", scope: [[VARIANT]],
3740
// CHECK-SAME: file: [[FILE]], line: 18,
38-
// CHECK-SAME: flags: DIFlagArtificial
41+
// CHECK-NOT: flags: DIFlagArtificial
42+
// CHECK-SAME: )
3943
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "3", scope: [[VARIANT]],
4044
// CHECK-SAME: file: [[FILE]], line: 15,
41-
// CHECK-SAME: flags: DIFlagArtificial
45+
// CHECK-NOT: flags: DIFlagArtificial
46+
// CHECK-SAME: )
4247
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "4", scope: [[VARIANT]],
4348
// CHECK-SAME: file: [[FILE]], line: 17,
44-
// CHECK-SAME: flags: DIFlagArtificial
49+
// CHECK-NOT: flags: DIFlagArtificial
50+
// CHECK-SAME: )
4551
// CHECK: [[S1:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN]],
46-
// CHECK-SAME: flags: DIFlagArtificial
52+
// CHECK-NOT: flags: DIFlagArtificial
53+
// CHECK-SAME: )
4754
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[S1]]
4855
// CHECK-NOT: flags: DIFlagArtificial
4956
// CHECK-SAME: )

src/test/debuginfo/generator-objects.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,26 @@
11
// Require a gdb that can read DW_TAG_variant_part.
22
// min-gdb-version: 8.2
33

4+
// LLDB without native Rust support cannot read DW_TAG_variant_part,
5+
// so it prints nothing for generators. But those tests are kept to
6+
// ensure that LLDB won't crash at least (like #57822).
7+
48
// compile-flags:-g
59

610
// === GDB TESTS ===================================================================================
711

812
// gdb-command:run
913
// gdb-command:print b
10-
// gdb-check:$1 = <error reading variable>
14+
// gdb-check:$1 = generator_objects::main::generator-0::Unresumed(0x[...])
1115
// gdb-command:continue
1216
// gdb-command:print b
13-
// gdb-check:$2 = <error reading variable>
17+
// gdb-check:$2 = generator_objects::main::generator-0::Suspend0{c: 6, d: 7, __0: 0x[...]}
1418
// gdb-command:continue
1519
// gdb-command:print b
16-
// gdb-check:$3 = <error reading variable>
20+
// gdb-check:$3 = generator_objects::main::generator-0::Suspend1{c: 7, d: 8, __0: 0x[...]}
1721
// gdb-command:continue
1822
// gdb-command:print b
19-
// gdb-check:$4 = <error reading variable>
23+
// gdb-check:$4 = generator_objects::main::generator-0::Returned([...])
2024

2125
// === LLDB TESTS ==================================================================================
2226

src/test/debuginfo/issue-57822.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
// gdb-check:$1 = issue_57822::main::closure-1 (issue_57822::main::closure-0 (1))
1515

1616
// gdb-command:print b
17-
// gdb-check:$2 = <error reading variable>
17+
// gdb-check:$2 = issue_57822::main::generator-3::Unresumed(issue_57822::main::generator-2::Unresumed(2))
1818

1919
// === LLDB TESTS ==================================================================================
2020

0 commit comments

Comments
 (0)