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 #79009.
This commit is contained in:
lrh2000 2021-04-30 20:02:53 +08:00
parent 060deec4b1
commit 5bf989ece9
7 changed files with 83 additions and 70 deletions

View File

@ -1495,10 +1495,6 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
} else {
type_metadata(cx, self.enum_type, self.span)
};
let flags = match self.enum_type.kind() {
ty::Generator(..) => DIFlags::FlagArtificial,
_ => DIFlags::FlagZero,
};
match self.layout.variants {
Variants::Single { index } => {
@ -1533,7 +1529,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
offset: Size::ZERO,
size: self.layout.size,
align: self.layout.align.abi,
flags,
flags: DIFlags::FlagZero,
discriminant: None,
source_info: variant_info.source_info(cx),
}]
@ -1588,7 +1584,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
offset: Size::ZERO,
size: self.layout.size,
align: self.layout.align.abi,
flags,
flags: DIFlags::FlagZero,
discriminant: Some(
self.layout.ty.discriminant_for_variant(cx.tcx, i).unwrap().val
as u64,
@ -1672,7 +1668,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
offset: Size::ZERO,
size: variant.size,
align: variant.align.abi,
flags,
flags: DIFlags::FlagZero,
discriminant: None,
source_info: variant_info.source_info(cx),
}]
@ -1723,7 +1719,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
offset: Size::ZERO,
size: self.layout.size,
align: self.layout.align.abi,
flags,
flags: DIFlags::FlagZero,
discriminant: niche_value,
source_info: variant_info.source_info(cx),
}
@ -1855,13 +1851,6 @@ impl<'tcx> VariantInfo<'_, 'tcx> {
}
None
}
fn is_artificial(&self) -> bool {
match self {
VariantInfo::Generator { .. } => true,
VariantInfo::Adt(..) => false,
}
}
}
/// Returns a tuple of (1) `type_metadata_stub` of the variant, (2) a
@ -1887,8 +1876,7 @@ fn describe_enum_variant(
&variant_name,
unique_type_id,
Some(containing_scope),
// FIXME(tmandry): This doesn't seem to have any effect.
if variant.is_artificial() { DIFlags::FlagArtificial } else { DIFlags::FlagZero },
DIFlags::FlagZero,
)
});
@ -1951,11 +1939,6 @@ fn prepare_enum_metadata(
) -> RecursiveTypeDescription<'ll, 'tcx> {
let tcx = cx.tcx;
let enum_name = compute_debuginfo_type_name(tcx, enum_type, false);
// FIXME(tmandry): This doesn't seem to have any effect.
let enum_flags = match enum_type.kind() {
ty::Generator(..) => DIFlags::FlagArtificial,
_ => DIFlags::FlagZero,
};
let containing_scope = get_namespace_for_item(cx, enum_def_id);
// FIXME: This should emit actual file metadata for the enum, but we
@ -2088,7 +2071,7 @@ fn prepare_enum_metadata(
UNKNOWN_LINE_NUMBER,
layout.size.bits(),
layout.align.abi.bits() as u32,
enum_flags,
DIFlags::FlagZero,
None,
0, // RuntimeLang
unique_type_id_str.as_ptr().cast(),
@ -2210,7 +2193,7 @@ fn prepare_enum_metadata(
UNKNOWN_LINE_NUMBER,
layout.size.bits(),
layout.align.abi.bits() as u32,
enum_flags,
DIFlags::FlagZero,
discriminator_metadata,
empty_array,
variant_part_unique_type_id_str.as_ptr().cast(),
@ -2239,7 +2222,7 @@ fn prepare_enum_metadata(
UNKNOWN_LINE_NUMBER,
layout.size.bits(),
layout.align.abi.bits() as u32,
enum_flags,
DIFlags::FlagZero,
None,
type_array,
0,

View File

@ -1,7 +1,7 @@
// Verify debuginfo for generators:
// - Each variant points to the file and line of its yield point
// - The generator types and variants are marked artificial
// - Captured vars from the source are not marked artificial
// - The discriminants are marked artificial
// - Other fields are not marked artificial
//
//
// compile-flags: -C debuginfo=2 --edition=2018
@ -17,26 +17,32 @@ async fn async_fn_test() {
// FIXME: No way to reliably check the filename.
// CHECK-DAG: [[ASYNC_FN:!.*]] = !DINamespace(name: "async_fn_test"
// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "generator-0", scope: [[ASYNC_FN]], {{.*}}flags: DIFlagArtificial
// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "generator-0", scope: [[ASYNC_FN]]
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
// For brevity, we only check the struct name and members of the last variant.
// CHECK-SAME: file: [[FILE:![0-9]*]], line: 11,
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
// CHECK-SAME: file: [[FILE]], line: 15,
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
// CHECK-SAME: file: [[FILE]], line: 15,
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
// CHECK-SAME: file: [[FILE]], line: 12,
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
// CHECK-SAME: file: [[FILE]], line: 14,
// CHECK-SAME: baseType: [[VARIANT:![0-9]*]]
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: [[S1:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[ASYNC_FN]],
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "RUST$ENUM$DISR", scope: [[S1]],
// CHECK-SAME: flags: DIFlagArtificial
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[S1]]

View File

@ -1,7 +1,7 @@
// Verify debuginfo for async fn:
// - Each variant points to the file and line of its yield point
// - The generator types and variants are marked artificial
// - Captured vars from the source are not marked artificial
// - The discriminants are marked artificial
// - Other fields are not marked artificial
//
//
// compile-flags: -C debuginfo=2 --edition=2018
@ -17,29 +17,36 @@ async fn async_fn_test() {
// FIXME: No way to reliably check the filename.
// CHECK-DAG: [[ASYNC_FN:!.*]] = !DINamespace(name: "async_fn_test"
// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "generator-0", scope: [[ASYNC_FN]], {{.*}}flags: DIFlagArtificial
// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "generator-0", scope: [[ASYNC_FN]]
// CHECK: [[VARIANT:!.*]] = !DICompositeType(tag: DW_TAG_variant_part, scope: [[ASYNC_FN]],
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: discriminator: [[DISC:![0-9]*]]
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "0", scope: [[VARIANT]],
// CHECK-SAME: file: [[FILE:![0-9]*]], line: 11,
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "Unresumed", scope: [[GEN]],
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "1", scope: [[VARIANT]],
// CHECK-SAME: file: [[FILE]], line: 15,
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "2", scope: [[VARIANT]],
// CHECK-SAME: file: [[FILE]], line: 15,
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "3", scope: [[VARIANT]],
// CHECK-SAME: file: [[FILE]], line: 12,
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "4", scope: [[VARIANT]],
// CHECK-SAME: file: [[FILE]], line: 14,
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: [[S1:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN]],
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[S1]]
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )

View File

@ -1,7 +1,7 @@
// Verify debuginfo for generators:
// - Each variant points to the file and line of its yield point
// - The generator types and variants are marked artificial
// - Captured vars from the source are not marked artificial
// - The discriminants are marked artificial
// - Other fields are not marked artificial
//
//
// compile-flags: -C debuginfo=2
@ -21,26 +21,32 @@ fn generator_test() -> impl Generator<Yield = i32, Return = ()> {
// FIXME: No way to reliably check the filename.
// CHECK-DAG: [[GEN_FN:!.*]] = !DINamespace(name: "generator_test"
// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "generator-0", scope: [[GEN_FN]], {{.*}}flags: DIFlagArtificial
// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "generator-0", scope: [[GEN_FN]]
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
// For brevity, we only check the struct name and members of the last variant.
// CHECK-SAME: file: [[FILE:![0-9]*]], line: 14,
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
// CHECK-SAME: file: [[FILE]], line: 18,
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
// CHECK-SAME: file: [[FILE]], line: 18,
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
// CHECK-SAME: file: [[FILE]], line: 15,
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
// CHECK-SAME: file: [[FILE]], line: 17,
// CHECK-SAME: baseType: [[VARIANT:![0-9]*]]
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: [[S1:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN_FN]],
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "RUST$ENUM$DISR", scope: [[S1]],
// CHECK-SAME: flags: DIFlagArtificial
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[S1]]

View File

@ -1,7 +1,7 @@
// Verify debuginfo for generators:
// - Each variant points to the file and line of its yield point
// - The generator types and variants are marked artificial
// - Captured vars from the source are not marked artificial
// - The discriminants are marked artificial
// - Other fields are not marked artificial
//
//
// compile-flags: -C debuginfo=2 --edition=2018
@ -21,29 +21,36 @@ fn generator_test() -> impl Generator<Yield = i32, Return = ()> {
// FIXME: No way to reliably check the filename.
// CHECK-DAG: [[GEN_FN:!.*]] = !DINamespace(name: "generator_test"
// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "generator-0", scope: [[GEN_FN]], {{.*}}flags: DIFlagArtificial
// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "generator-0", scope: [[GEN_FN]]
// CHECK: [[VARIANT:!.*]] = !DICompositeType(tag: DW_TAG_variant_part, scope: [[GEN_FN]],
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: discriminator: [[DISC:![0-9]*]]
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "0", scope: [[VARIANT]],
// CHECK-SAME: file: [[FILE:![0-9]*]], line: 14,
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "Unresumed", scope: [[GEN]],
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "1", scope: [[VARIANT]],
// CHECK-SAME: file: [[FILE]], line: 18,
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "2", scope: [[VARIANT]],
// CHECK-SAME: file: [[FILE]], line: 18,
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "3", scope: [[VARIANT]],
// CHECK-SAME: file: [[FILE]], line: 15,
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "4", scope: [[VARIANT]],
// CHECK-SAME: file: [[FILE]], line: 17,
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: [[S1:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN]],
// CHECK-SAME: flags: DIFlagArtificial
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[S1]]
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )

View File

@ -1,22 +1,26 @@
// Require a gdb that can read DW_TAG_variant_part.
// min-gdb-version: 8.2
// LLDB without native Rust support cannot read DW_TAG_variant_part,
// so it prints nothing for generators. But those tests are kept to
// ensure that LLDB won't crash at least (like #57822).
// compile-flags:-g
// === GDB TESTS ===================================================================================
// gdb-command:run
// gdb-command:print b
// gdb-check:$1 = <error reading variable>
// gdb-check:$1 = generator_objects::main::generator-0::Unresumed(0x[...])
// gdb-command:continue
// gdb-command:print b
// gdb-check:$2 = <error reading variable>
// gdb-check:$2 = generator_objects::main::generator-0::Suspend0{c: 6, d: 7, __0: 0x[...]}
// gdb-command:continue
// gdb-command:print b
// gdb-check:$3 = <error reading variable>
// gdb-check:$3 = generator_objects::main::generator-0::Suspend1{c: 7, d: 8, __0: 0x[...]}
// gdb-command:continue
// gdb-command:print b
// gdb-check:$4 = <error reading variable>
// gdb-check:$4 = generator_objects::main::generator-0::Returned(0x[...])
// === LLDB TESTS ==================================================================================

View File

@ -14,7 +14,7 @@
// gdb-check:$1 = issue_57822::main::closure-1 (issue_57822::main::closure-0 (1))
// gdb-command:print b
// gdb-check:$2 = <error reading variable>
// gdb-check:$2 = issue_57822::main::generator-3::Unresumed(issue_57822::main::generator-2::Unresumed(2))
// === LLDB TESTS ==================================================================================