From 8ebc1c9fd88640b1833e0743b649a957f3337720 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Fri, 5 Dec 2014 18:35:16 -0500 Subject: [PATCH] librustc: Fix debuginfo for captured variables in non-FnOnce unboxed closures. --- src/librustc_trans/trans/closure.rs | 4 +- src/librustc_trans/trans/debuginfo.rs | 6 ++- .../var-captured-in-stack-closure.rs | 47 +++++++++++++++++-- 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs index bb4df00bd94..106c272a779 100644 --- a/src/librustc_trans/trans/closure.rs +++ b/src/librustc_trans/trans/closure.rs @@ -286,7 +286,6 @@ fn load_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, debuginfo::create_captured_var_metadata( bcx, def_id.node, - cdata_ty, env_pointer_alloca, i, captured_by_ref, @@ -326,7 +325,7 @@ fn load_unboxed_closure_environment<'blk, 'tcx>( // Store the pointer to closure data in an alloca for debug info because that's what the // llvm.dbg.declare intrinsic expects let env_pointer_alloca = if bcx.sess().opts.debuginfo == FullDebugInfo { - let alloc = alloc_ty(bcx, ty::mk_mut_ptr(bcx.tcx(), self_type), "__debuginfo_env_ptr"); + let alloc = alloca(bcx, val_ty(llenv), "__debuginfo_env_ptr"); Store(bcx, llenv, alloc); Some(alloc) } else { @@ -355,7 +354,6 @@ fn load_unboxed_closure_environment<'blk, 'tcx>( debuginfo::create_captured_var_metadata( bcx, def_id.node, - self_type, env_pointer_alloca, i, captured_by_ref, diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index 555cb000489..09cfbde43e5 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -882,7 +882,6 @@ pub fn create_local_var_metadata(bcx: Block, local: &ast::Local) { /// Adds the created metadata nodes directly to the crate's IR. pub fn create_captured_var_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, node_id: ast::NodeId, - env_data_type: Ty<'tcx>, env_pointer: ValueRef, env_index: uint, captured_by_ref: bool, @@ -928,7 +927,10 @@ pub fn create_captured_var_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let variable_type = node_id_type(bcx, node_id); let scope_metadata = bcx.fcx.debug_context.get_ref(cx, span).fn_metadata; - let llvm_env_data_type = type_of::type_of(cx, env_data_type); + // env_pointer is the alloca containing the pointer to the environment, + // so it's type is **EnvironmentType. In order to find out the type of + // the environment we have to "dereference" two times. + let llvm_env_data_type = val_ty(env_pointer).element_type().element_type(); let byte_offset_of_var_in_env = machine::llelement_offset(cx, llvm_env_data_type, env_index); diff --git a/src/test/debuginfo/var-captured-in-stack-closure.rs b/src/test/debuginfo/var-captured-in-stack-closure.rs index 92a3d358f5c..761d0f0be8f 100644 --- a/src/test/debuginfo/var-captured-in-stack-closure.rs +++ b/src/test/debuginfo/var-captured-in-stack-closure.rs @@ -28,6 +28,19 @@ // gdb-command:print *owned // gdb-check:$5 = 6 +// gdb-command:continue + +// gdb-command:print variable +// gdb-check:$6 = 2 +// gdb-command:print constant +// gdb-check:$7 = 2 +// gdb-command:print a_struct +// gdb-check:$8 = {a = -3, b = 4.5, c = 5} +// gdb-command:print *struct_ref +// gdb-check:$9 = {a = -3, b = 4.5, c = 5} +// gdb-command:print *owned +// gdb-check:$10 = 6 + // === LLDB TESTS ================================================================================== @@ -44,6 +57,20 @@ // lldb-command:print *owned // lldb-check:[...]$4 = 6 +// lldb-command:continue + +// lldb-command:print variable +// lldb-check:[...]$5 = 2 +// lldb-command:print constant +// lldb-check:[...]$6 = 2 +// lldb-command:print a_struct +// lldb-check:[...]$7 = Struct { a: -3, b: 4.5, c: 5 } +// lldb-command:print *struct_ref +// lldb-check:[...]$8 = Struct { a: -3, b: 4.5, c: 5 } +// lldb-command:print *owned +// lldb-check:[...]$9 = 6 + +#![feature(unboxed_closures)] #![allow(unused_variables)] struct Struct { @@ -65,12 +92,22 @@ fn main() { let struct_ref = &a_struct; let owned = box 6; - let closure = || { - zzz(); // #break - variable = constant + a_struct.a + struct_ref.a + *owned; - }; + { + let closure = || { + zzz(); // #break + variable = constant + a_struct.a + struct_ref.a + *owned; + }; - closure(); + closure(); + } + + { + let mut unboxed_closure = |&mut:| { + zzz(); // #break + variable = constant + a_struct.a + struct_ref.a + *owned; + }; + unboxed_closure(); + } } fn zzz() {()}