Skip to content

Commit e65c460

Browse files
committed
Name the upvars for closures and generators in debuginfo
Previously, debuggers print closures as something like ``` y::main::closure-0 (0x7fffffffdd34, 0x7fffffffdd30) ``` The two pointers are actually references to two upvars. It is not very obvious, especially for beginners. It's because upvars don't have names before, as they are packed into a tuple. This commit names the upvars, so we can expect to see something like ``` y::main::closure-0 {_upvar_ref_mut__b: 0x[...], _upvar_ref__a: 0x[...]} ```
1 parent 1995cd9 commit e65c460

File tree

3 files changed

+65
-8
lines changed

3 files changed

+65
-8
lines changed

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use rustc_fs_util::path_to_c_string;
2727
use rustc_hir::def::CtorKind;
2828
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
2929
use rustc_index::vec::{Idx, IndexVec};
30+
use rustc_middle::hir;
3031
use rustc_middle::ich::NodeIdHashingMode;
3132
use rustc_middle::mir::{self, Field, GeneratorLayout};
3233
use rustc_middle::ty::layout::{self, IntegerExt, PrimitiveExt, TyAndLayout};
@@ -1285,14 +1286,70 @@ struct TupleMemberDescriptionFactory<'tcx> {
12851286

12861287
impl<'tcx> TupleMemberDescriptionFactory<'tcx> {
12871288
fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) -> Vec<MemberDescription<'ll>> {
1289+
// For closures and generators, we mangle the upvars' names to something like:
1290+
// - `_upvar__name`
1291+
// - `_upvar_ref__name`
1292+
// - `_upvar_ref_mut__name`
1293+
// The purpose is to make those names human-understandable. Otherwise, the end users may
1294+
// get confused when the debuggers just print some pointers for closures or generators.
1295+
let closure_def_id = match *self.ty.kind() {
1296+
ty::Generator(def_id, ..) => def_id.as_local(),
1297+
ty::Closure(def_id, ..) => def_id.as_local(),
1298+
_ => None,
1299+
};
1300+
let captures = match closure_def_id {
1301+
Some(local_def_id) => {
1302+
let typeck_results = cx.tcx.typeck(local_def_id);
1303+
let captures = typeck_results
1304+
.closure_min_captures_flattened(local_def_id.to_def_id())
1305+
.collect::<Vec<_>>();
1306+
Some(captures)
1307+
}
1308+
_ => None,
1309+
};
1310+
let format_name = |i| {
1311+
match &captures {
1312+
Some(ref captures) => {
1313+
let capture: &ty::CapturedPlace<'tcx> = captures[i];
1314+
1315+
let prefix = if cx.tcx.features().capture_disjoint_fields {
1316+
// FIXME:
1317+
// Here we may need more name mangling to reflect disjoint fields.
1318+
format!("_upvar{}_", i)
1319+
} else {
1320+
"_upvar_".to_string()
1321+
};
1322+
1323+
let adjust = match capture.info.capture_kind {
1324+
ty::UpvarCapture::ByValue(_) => "_",
1325+
ty::UpvarCapture::ByRef(borrow)
1326+
if borrow.kind == ty::BorrowKind::MutBorrow =>
1327+
{
1328+
"ref_mut__"
1329+
}
1330+
ty::UpvarCapture::ByRef(_) => "ref__",
1331+
};
1332+
1333+
let hir_id = match capture.place.base {
1334+
hir::place::PlaceBase::Upvar(upvar_id) => upvar_id.var_path.hir_id,
1335+
base => bug!("Expected an upvar, found {:?}", base),
1336+
};
1337+
let name = cx.tcx.hir().name(hir_id).as_str();
1338+
1339+
prefix + adjust + &name
1340+
}
1341+
None => format!("__{}", i),
1342+
}
1343+
};
1344+
12881345
let layout = cx.layout_of(self.ty);
12891346
self.component_types
12901347
.iter()
12911348
.enumerate()
12921349
.map(|(i, &component_type)| {
12931350
let (size, align) = cx.size_and_align_of(component_type);
12941351
MemberDescription {
1295-
name: format!("__{}", i),
1352+
name: format_name(i),
12961353
type_metadata: type_metadata(cx, component_type, self.span),
12971354
offset: layout.fields.offset(i),
12981355
size,

src/test/debuginfo/generator-objects.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@
1111

1212
// gdb-command:run
1313
// gdb-command:print b
14-
// gdb-check:$1 = generator_objects::main::generator-0::Unresumed(0x[...])
14+
// gdb-check:$1 = generator_objects::main::generator-0::Unresumed{_upvar_ref_mut__a: 0x[...]}
1515
// gdb-command:continue
1616
// gdb-command:print b
17-
// gdb-check:$2 = generator_objects::main::generator-0::Suspend0{c: 6, d: 7, __0: 0x[...]}
17+
// gdb-check:$2 = generator_objects::main::generator-0::Suspend0{c: 6, d: 7, _upvar_ref_mut__a: 0x[...]}
1818
// gdb-command:continue
1919
// gdb-command:print b
20-
// gdb-check:$3 = generator_objects::main::generator-0::Suspend1{c: 7, d: 8, __0: 0x[...]}
20+
// gdb-check:$3 = generator_objects::main::generator-0::Suspend1{c: 7, d: 8, _upvar_ref_mut__a: 0x[...]}
2121
// gdb-command:continue
2222
// gdb-command:print b
23-
// gdb-check:$4 = generator_objects::main::generator-0::Returned([...])
23+
// gdb-check:$4 = generator_objects::main::generator-0::Returned{_upvar_ref_mut__a: [...]}
2424

2525
// === LLDB TESTS ==================================================================================
2626

src/test/debuginfo/issue-57822.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,17 @@
1111
// gdb-command:run
1212

1313
// gdb-command:print g
14-
// gdb-check:$1 = issue_57822::main::closure-1 (issue_57822::main::closure-0 (1))
14+
// gdb-check:$1 = issue_57822::main::closure-1 {_upvar__f: issue_57822::main::closure-0 {_upvar__x: 1}}
1515

1616
// gdb-command:print b
17-
// gdb-check:$2 = issue_57822::main::generator-3::Unresumed(issue_57822::main::generator-2::Unresumed(2))
17+
// gdb-check:$2 = issue_57822::main::generator-3::Unresumed{_upvar__a: issue_57822::main::generator-2::Unresumed{_upvar__y: 2}}
1818

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

2121
// lldb-command:run
2222

2323
// lldb-command:print g
24-
// lldbg-check:(issue_57822::main::closure-1) $0 = { 0 = { 0 = 1 } }
24+
// lldbg-check:(issue_57822::main::closure-1) $0 = { _upvar__f = { _upvar__x = 1 } }
2525

2626
// lldb-command:print b
2727
// lldbg-check:(issue_57822::main::generator-3) $1 =

0 commit comments

Comments
 (0)