From 61097bce0dd4d394129ba15d2bbd41ec2dc526ef Mon Sep 17 00:00:00 2001 From: Wim Looman Date: Wed, 7 Nov 2018 22:45:21 +0100 Subject: [PATCH] Add debug-info to access variables from generator state --- src/librustc_codegen_ssa/mir/mod.rs | 35 +++++++++++++++++++++++++---- src/test/debuginfo/generators.rs | 10 +++++++-- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index c7e2131eed5..ce342320af9 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -607,15 +607,42 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( }; let upvar_tys = upvar_substs.upvar_tys(def_id, tcx); - for (i, (decl, ty)) in mir.upvar_decls.iter().zip(upvar_tys).enumerate() { - let byte_offset_of_var_in_env = closure_layout.fields.offset(i).bytes(); + let extra_locals = { + let upvars = mir.upvar_decls + .iter() + .zip(upvar_tys) + .enumerate() + .map(|(i, (decl, ty))| (i, decl.debug_name, decl.by_ref, ty)); + + let generator_fields = mir.generator_layout.as_ref().map(|generator_layout| { + let (def_id, gen_substs) = match closure_layout.ty.sty { + ty::Generator(def_id, substs, _) => (def_id, substs), + _ => bug!("generator layout without generator substs"), + }; + let state_tys = gen_substs.state_tys(def_id, tcx); + + let upvar_count = mir.upvar_decls.len(); + generator_layout.fields + .iter() + .zip(state_tys) + .enumerate() + .filter_map(move |(i, (decl, ty))| { + decl.name.map(|name| (i + upvar_count + 1, name, false, ty)) + }) + }).into_iter().flatten(); + + upvars.chain(generator_fields) + }; + + for (field, name, by_ref, ty) in extra_locals { + let byte_offset_of_var_in_env = closure_layout.fields.offset(field).bytes(); let ops = bx.debuginfo_upvar_decls_ops_sequence(byte_offset_of_var_in_env); // The environment and the capture can each be indirect. let mut ops = if env_ref { &ops[..] } else { &ops[1..] }; - let ty = if let (true, &ty::Ref(_, ty, _)) = (decl.by_ref, &ty.sty) { + let ty = if let (true, &ty::Ref(_, ty, _)) = (by_ref, &ty.sty) { ty } else { ops = &ops[..ops.len() - 1]; @@ -628,7 +655,7 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( }; bx.declare_local( &fx.debug_context, - decl.debug_name, + name, ty, scope, variable_access, diff --git a/src/test/debuginfo/generators.rs b/src/test/debuginfo/generators.rs index b56d222e0e0..35a67217f16 100644 --- a/src/test/debuginfo/generators.rs +++ b/src/test/debuginfo/generators.rs @@ -7,6 +7,8 @@ // gdb-command:run // gdb-command:print a // gdb-check:$1 = 5 +// gdb-command:print d +// gdb-check:$2 = 6 // === LLDB TESTS ================================================================================== @@ -14,8 +16,11 @@ // lldb-command:print a // lldbg-check:(int) $0 = 5 // lldbr-check:(int) a = 5 +// lldb-command:print d +// lldbg-check:(int) $1 = 6 +// lldbr-check:(int) d = 6 -#![feature(omit_gdb_pretty_printer_section, generators, generator_trait, pin)] +#![feature(omit_gdb_pretty_printer_section, generators, generator_trait)] #![omit_gdb_pretty_printer_section] use std::ops::Generator; @@ -24,9 +29,10 @@ use std::pin::Pin; fn main() { let mut a = 5; let mut b = || { + let d = 6; yield; _zzz(); // #break - a = 6; + a = d; }; Pin::new(&mut b).resume(); Pin::new(&mut b).resume();