Skip to content

Commit fbe3f3e

Browse files
committed
debuginfo: give unique names to closure and generator types
Closure types have been moved to the namespace where they are defined, and both closure and generator type names now include the disambiguator. This fixes an exception when lldb prints nested closures. Fixes #57822
1 parent bea0372 commit fbe3f3e

File tree

3 files changed

+72
-5
lines changed

3 files changed

+72
-5
lines changed

src/librustc_codegen_llvm/debuginfo/metadata.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -683,11 +683,13 @@ pub fn type_metadata(
683683
}
684684
ty::Closure(def_id, substs) => {
685685
let upvar_tys : Vec<_> = substs.upvar_tys(def_id, cx.tcx).collect();
686+
let containing_scope = get_namespace_for_item(cx, def_id);
686687
prepare_tuple_metadata(cx,
687688
t,
688689
&upvar_tys,
689690
unique_type_id,
690-
usage_site_span).finalize(cx)
691+
usage_site_span,
692+
Some(containing_scope)).finalize(cx)
691693
}
692694
ty::Generator(def_id, substs, _) => {
693695
let upvar_tys : Vec<_> = substs.prefix_tys(def_id, cx.tcx).map(|t| {
@@ -728,7 +730,8 @@ pub fn type_metadata(
728730
t,
729731
&tys,
730732
unique_type_id,
731-
usage_site_span).finalize(cx)
733+
usage_site_span,
734+
NO_SCOPE_METADATA).finalize(cx)
732735
}
733736
_ => {
734737
bug!("debuginfo: unexpected type in type_metadata: {:?}", t)
@@ -1205,14 +1208,15 @@ fn prepare_tuple_metadata(
12051208
component_types: &[Ty<'tcx>],
12061209
unique_type_id: UniqueTypeId,
12071210
span: Span,
1211+
containing_scope: Option<&'ll DIScope>,
12081212
) -> RecursiveTypeDescription<'ll, 'tcx> {
12091213
let tuple_name = compute_debuginfo_type_name(cx.tcx, tuple_type, false);
12101214

12111215
let struct_stub = create_struct_stub(cx,
12121216
tuple_type,
12131217
&tuple_name[..],
12141218
unique_type_id,
1215-
NO_SCOPE_METADATA);
1219+
containing_scope);
12161220

12171221
create_and_register_recursive_type_forward_declaration(
12181222
cx,

src/librustc_codegen_ssa/debuginfo/type_names.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -190,11 +190,19 @@ pub fn push_debuginfo_type_name<'tcx>(
190190
// processing
191191
visited.remove(t);
192192
},
193-
ty::Closure(..) => {
193+
ty::Closure(def_id, ..) => {
194194
output.push_str("closure");
195+
let disambiguator = tcx.def_key(def_id).disambiguated_data.disambiguator;
196+
if disambiguator != 0 {
197+
output.push_str(&format!("-{}", disambiguator));
198+
}
195199
}
196-
ty::Generator(..) => {
200+
ty::Generator(def_id, ..) => {
197201
output.push_str("generator");
202+
let disambiguator = tcx.def_key(def_id).disambiguated_data.disambiguator;
203+
if disambiguator != 0 {
204+
output.push_str(&format!("-{}", disambiguator));
205+
}
198206
}
199207
ty::Error |
200208
ty::Infer(_) |

src/test/debuginfo/issue-57822.rs

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// This test makes sure that the LLDB pretty printer does not throw an exception
2+
// for nested closures and generators.
3+
4+
// Require LLVM with DW_TAG_variant_part and a gdb that can read it.
5+
// min-system-llvm-version: 8.0
6+
// min-gdb-version: 8.2
7+
// ignore-tidy-linelength
8+
9+
// compile-flags:-g
10+
11+
// === GDB TESTS ===================================================================================
12+
13+
// gdb-command:run
14+
15+
// gdb-command:print g
16+
// gdb-check:$1 = issue_57822::main::closure-1 (issue_57822::main::closure (1))
17+
18+
// gdb-command:print b
19+
// gdb-check:$2 = issue_57822::main::generator-3 {__0: issue_57822::main::generator-2 {__0: 2, <<variant>>: {[...]}}, <<variant>>: {[...]}}
20+
21+
// === LLDB TESTS ==================================================================================
22+
23+
// lldb-command:run
24+
25+
// lldb-command:print g
26+
// lldbg-check:(issue_57822::main::closure-1) $0 = closure-1(closure(1))
27+
28+
// lldb-command:print b
29+
// lldbg-check:(issue_57822::main::generator-3) $1 = generator-3(generator-2(2))
30+
31+
#![feature(omit_gdb_pretty_printer_section, generators, generator_trait)]
32+
#![omit_gdb_pretty_printer_section]
33+
34+
use std::ops::Generator;
35+
use std::pin::Pin;
36+
37+
fn main() {
38+
let mut x = 1;
39+
let f = move || x;
40+
let g = move || f();
41+
42+
let mut y = 2;
43+
let mut a = move || {
44+
y += 1;
45+
yield;
46+
};
47+
let mut b = move || {
48+
Pin::new(&mut a).resume();
49+
yield;
50+
};
51+
52+
zzz(); // #break
53+
}
54+
55+
fn zzz() { () }

0 commit comments

Comments
 (0)