diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 51e789b17880a..928532a1f4760 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -683,11 +683,13 @@ pub fn type_metadata( } ty::Closure(def_id, substs) => { let upvar_tys : Vec<_> = substs.upvar_tys(def_id, cx.tcx).collect(); + let containing_scope = get_namespace_for_item(cx, def_id); prepare_tuple_metadata(cx, t, &upvar_tys, unique_type_id, - usage_site_span).finalize(cx) + usage_site_span, + Some(containing_scope)).finalize(cx) } ty::Generator(def_id, substs, _) => { let upvar_tys : Vec<_> = substs.prefix_tys(def_id, cx.tcx).map(|t| { @@ -728,7 +730,8 @@ pub fn type_metadata( t, &tys, unique_type_id, - usage_site_span).finalize(cx) + usage_site_span, + NO_SCOPE_METADATA).finalize(cx) } _ => { bug!("debuginfo: unexpected type in type_metadata: {:?}", t) @@ -1205,6 +1208,7 @@ fn prepare_tuple_metadata( component_types: &[Ty<'tcx>], unique_type_id: UniqueTypeId, span: Span, + containing_scope: Option<&'ll DIScope>, ) -> RecursiveTypeDescription<'ll, 'tcx> { let tuple_name = compute_debuginfo_type_name(cx.tcx, tuple_type, false); @@ -1212,7 +1216,7 @@ fn prepare_tuple_metadata( tuple_type, &tuple_name[..], unique_type_id, - NO_SCOPE_METADATA); + containing_scope); create_and_register_recursive_type_forward_declaration( cx, diff --git a/src/librustc_codegen_ssa/debuginfo/type_names.rs b/src/librustc_codegen_ssa/debuginfo/type_names.rs index ea39913d4b91b..9b5ad94ecd7cb 100644 --- a/src/librustc_codegen_ssa/debuginfo/type_names.rs +++ b/src/librustc_codegen_ssa/debuginfo/type_names.rs @@ -190,11 +190,17 @@ pub fn push_debuginfo_type_name<'tcx>( // processing visited.remove(t); }, - ty::Closure(..) => { - output.push_str("closure"); + ty::Closure(def_id, ..) => { + output.push_str(&format!( + "closure-{}", + tcx.def_key(def_id).disambiguated_data.disambiguator + )); } - ty::Generator(..) => { - output.push_str("generator"); + ty::Generator(def_id, ..) => { + output.push_str(&format!( + "generator-{}", + tcx.def_key(def_id).disambiguated_data.disambiguator + )); } ty::Error | ty::Infer(_) | diff --git a/src/test/debuginfo/generator-objects.rs b/src/test/debuginfo/generator-objects.rs index c6f98e5782b1f..bfa7a05cad057 100644 --- a/src/test/debuginfo/generator-objects.rs +++ b/src/test/debuginfo/generator-objects.rs @@ -10,31 +10,31 @@ // gdb-command:run // gdb-command:print b -// gdb-check:$1 = generator_objects::main::generator {__0: 0x[...], <>: {__state: 0, 0: generator_objects::main::generator::Unresumed, 1: generator_objects::main::generator::Returned, 2: generator_objects::main::generator::Panicked, 3: generator_objects::main::generator::Suspend0 {[...]}, 4: generator_objects::main::generator::Suspend1 {[...]}}} +// gdb-check:$1 = generator_objects::main::generator-0 {__0: 0x[...], <>: {__state: 0, 0: generator_objects::main::generator-0::Unresumed, 1: generator_objects::main::generator-0::Returned, 2: generator_objects::main::generator-0::Panicked, 3: generator_objects::main::generator-0::Suspend0 {[...]}, 4: generator_objects::main::generator-0::Suspend1 {[...]}}} // gdb-command:continue // gdb-command:print b -// gdb-check:$2 = generator_objects::main::generator {__0: 0x[...], <>: {__state: 3, 0: generator_objects::main::generator::Unresumed, 1: generator_objects::main::generator::Returned, 2: generator_objects::main::generator::Panicked, 3: generator_objects::main::generator::Suspend0 {c: 6, d: 7}, 4: generator_objects::main::generator::Suspend1 {[...]}}} +// gdb-check:$2 = generator_objects::main::generator-0 {__0: 0x[...], <>: {__state: 3, 0: generator_objects::main::generator-0::Unresumed, 1: generator_objects::main::generator-0::Returned, 2: generator_objects::main::generator-0::Panicked, 3: generator_objects::main::generator-0::Suspend0 {c: 6, d: 7}, 4: generator_objects::main::generator-0::Suspend1 {[...]}}} // gdb-command:continue // gdb-command:print b -// gdb-check:$3 = generator_objects::main::generator {__0: 0x[...], <>: {__state: 4, 0: generator_objects::main::generator::Unresumed, 1: generator_objects::main::generator::Returned, 2: generator_objects::main::generator::Panicked, 3: generator_objects::main::generator::Suspend0 {[...]}, 4: generator_objects::main::generator::Suspend1 {c: 7, d: 8}}} +// gdb-check:$3 = generator_objects::main::generator-0 {__0: 0x[...], <>: {__state: 4, 0: generator_objects::main::generator-0::Unresumed, 1: generator_objects::main::generator-0::Returned, 2: generator_objects::main::generator-0::Panicked, 3: generator_objects::main::generator-0::Suspend0 {[...]}, 4: generator_objects::main::generator-0::Suspend1 {c: 7, d: 8}}} // gdb-command:continue // gdb-command:print b -// gdb-check:$4 = generator_objects::main::generator {__0: 0x[...], <>: {__state: 1, 0: generator_objects::main::generator::Unresumed, 1: generator_objects::main::generator::Returned, 2: generator_objects::main::generator::Panicked, 3: generator_objects::main::generator::Suspend0 {[...]}, 4: generator_objects::main::generator::Suspend1 {[...]}}} +// gdb-check:$4 = generator_objects::main::generator-0 {__0: 0x[...], <>: {__state: 1, 0: generator_objects::main::generator-0::Unresumed, 1: generator_objects::main::generator-0::Returned, 2: generator_objects::main::generator-0::Panicked, 3: generator_objects::main::generator-0::Suspend0 {[...]}, 4: generator_objects::main::generator-0::Suspend1 {[...]}}} // === LLDB TESTS ================================================================================== // lldb-command:run // lldb-command:print b -// lldbg-check:(generator_objects::main::generator) $0 = generator(&0x[...]) +// lldbg-check:(generator_objects::main::generator-0) $0 = generator-0(&0x[...]) // lldb-command:continue // lldb-command:print b -// lldbg-check:(generator_objects::main::generator) $1 = generator(&0x[...]) +// lldbg-check:(generator_objects::main::generator-0) $1 = generator-0(&0x[...]) // lldb-command:continue // lldb-command:print b -// lldbg-check:(generator_objects::main::generator) $2 = generator(&0x[...]) +// lldbg-check:(generator_objects::main::generator-0) $2 = generator-0(&0x[...]) // lldb-command:continue // lldb-command:print b -// lldbg-check:(generator_objects::main::generator) $3 = generator(&0x[...]) +// lldbg-check:(generator_objects::main::generator-0) $3 = generator-0(&0x[...]) #![feature(omit_gdb_pretty_printer_section, generators, generator_trait)] #![omit_gdb_pretty_printer_section] diff --git a/src/test/debuginfo/issue-57822.rs b/src/test/debuginfo/issue-57822.rs new file mode 100644 index 0000000000000..f18e41db0e6ba --- /dev/null +++ b/src/test/debuginfo/issue-57822.rs @@ -0,0 +1,55 @@ +// This test makes sure that the LLDB pretty printer does not throw an exception +// for nested closures and generators. + +// Require LLVM with DW_TAG_variant_part and a gdb that can read it. +// min-system-llvm-version: 8.0 +// min-gdb-version: 8.2 +// ignore-tidy-linelength + +// compile-flags:-g + +// === GDB TESTS =================================================================================== + +// gdb-command:run + +// gdb-command:print g +// gdb-check:$1 = issue_57822::main::closure-1 (issue_57822::main::closure-0 (1)) + +// gdb-command:print b +// gdb-check:$2 = issue_57822::main::generator-3 {__0: issue_57822::main::generator-2 {__0: 2, <>: {[...]}}, <>: {[...]}} + +// === LLDB TESTS ================================================================================== + +// lldb-command:run + +// lldb-command:print g +// lldbg-check:(issue_57822::main::closure-1) $0 = closure-1(closure-0(1)) + +// lldb-command:print b +// lldbg-check:(issue_57822::main::generator-3) $1 = generator-3(generator-2(2)) + +#![feature(omit_gdb_pretty_printer_section, generators, generator_trait)] +#![omit_gdb_pretty_printer_section] + +use std::ops::Generator; +use std::pin::Pin; + +fn main() { + let mut x = 1; + let f = move || x; + let g = move || f(); + + let mut y = 2; + let mut a = move || { + y += 1; + yield; + }; + let mut b = move || { + Pin::new(&mut a).resume(); + yield; + }; + + zzz(); // #break +} + +fn zzz() { () }