about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorWim Looman <wim@nemo157.com>2018-11-07 22:45:21 +0100
committerWim Looman <wim@nemo157.com>2019-02-23 12:13:39 +0100
commit61097bce0dd4d394129ba15d2bbd41ec2dc526ef (patch)
tree88e90499a88781cc033523f2265a088fbd88086b /src
parent3e58dabc16b1678da8702c71f70c72644764226c (diff)
downloadrust-61097bce0dd4d394129ba15d2bbd41ec2dc526ef.tar.gz
rust-61097bce0dd4d394129ba15d2bbd41ec2dc526ef.zip
Add debug-info to access variables from generator state
Diffstat (limited to 'src')
-rw-r--r--src/librustc_codegen_ssa/mir/mod.rs35
-rw-r--r--src/test/debuginfo/generators.rs10
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();