From 5bf989ece9e29941f2c517a39289a60bfb8595c0 Mon Sep 17 00:00:00 2001 From: lrh2000 Date: Fri, 30 Apr 2021 20:02:53 +0800 Subject: [PATCH] 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. --- .../src/debuginfo/metadata.rs | 33 +++++-------------- src/test/codegen/async-fn-debug-msvc.rs | 24 +++++++++----- src/test/codegen/async-fn-debug.rs | 29 +++++++++------- src/test/codegen/generator-debug-msvc.rs | 24 +++++++++----- src/test/codegen/generator-debug.rs | 29 +++++++++------- src/test/debuginfo/generator-objects.rs | 12 ++++--- src/test/debuginfo/issue-57822.rs | 2 +- 7 files changed, 83 insertions(+), 70 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 800133b5f0fac..280d9a4d37021 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -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, diff --git a/src/test/codegen/async-fn-debug-msvc.rs b/src/test/codegen/async-fn-debug-msvc.rs index 2b8c0dfc229a3..f2641404aae21 100644 --- a/src/test/codegen/async-fn-debug-msvc.rs +++ b/src/test/codegen/async-fn-debug-msvc.rs @@ -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]] diff --git a/src/test/codegen/async-fn-debug.rs b/src/test/codegen/async-fn-debug.rs index e9b774b48c3e7..7de115f7e9194 100644 --- a/src/test/codegen/async-fn-debug.rs +++ b/src/test/codegen/async-fn-debug.rs @@ -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: ) diff --git a/src/test/codegen/generator-debug-msvc.rs b/src/test/codegen/generator-debug-msvc.rs index 4f8a320ee9b17..44be71f3b9b80 100644 --- a/src/test/codegen/generator-debug-msvc.rs +++ b/src/test/codegen/generator-debug-msvc.rs @@ -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 { // 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]] diff --git a/src/test/codegen/generator-debug.rs b/src/test/codegen/generator-debug.rs index 86ac6db702ab9..8b87a2f064604 100644 --- a/src/test/codegen/generator-debug.rs +++ b/src/test/codegen/generator-debug.rs @@ -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 { // 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: ) diff --git a/src/test/debuginfo/generator-objects.rs b/src/test/debuginfo/generator-objects.rs index 3437b295e6e9c..1beed1c835d97 100644 --- a/src/test/debuginfo/generator-objects.rs +++ b/src/test/debuginfo/generator-objects.rs @@ -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 = +// gdb-check:$1 = generator_objects::main::generator-0::Unresumed(0x[...]) // gdb-command:continue // gdb-command:print b -// gdb-check:$2 = +// 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 = +// 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 = +// gdb-check:$4 = generator_objects::main::generator-0::Returned(0x[...]) // === LLDB TESTS ================================================================================== diff --git a/src/test/debuginfo/issue-57822.rs b/src/test/debuginfo/issue-57822.rs index 3a9eaecd5e75e..6b2b12edda5d7 100644 --- a/src/test/debuginfo/issue-57822.rs +++ b/src/test/debuginfo/issue-57822.rs @@ -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 = +// gdb-check:$2 = issue_57822::main::generator-3::Unresumed(issue_57822::main::generator-2::Unresumed(2)) // === LLDB TESTS ==================================================================================