Change:
So, this code raises an assertion in llvm when compiling with -g. Without -g it works fine. Raised assertion is Edit: reduced code more
Duplicate of ? (there are some comments with unboxed closures and /)
It worked with the rustc versions from around last week. Especially the rustup versions. A friend just tested it with his "old" version from 11/26, and it still works there. So either it's new or it's a regression bug.
cc
I'll look into it.
I suspect the culprit is makereturnslotpointer in librustctrans::trans::builder

Discussion:
debuginfo::create_captured_var_metadata( bcx, def_id.node, <del> cdata_ty, </del> env_pointer_alloca, i, captured_by_ref,

// 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 { <del> let alloc = alloc_ty(bcx, ty::mk_mut_ptr(bcx.tcx(), self_type), "__debuginfo_env_ptr"); </del> <ins> let alloc = alloca(bcx, val_ty(llenv), "__debuginfo_env_ptr"); </ins> Store(bcx, llenv, alloc); Some(alloc) } else {

debuginfo::create_captured_var_metadata( bcx, def_id.node, <del> self_type, </del> env_pointer_alloca, i, captured_by_ref,

/// 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, <del> env_data_type: Ty<'tcx>, </del> env_pointer: ValueRef, env_index: uint, captured_by_ref: bool,

let variable_type = node_id_type(bcx, node_id); let scope_metadata = bcx.fcx.debug_context.get_ref(cx, span).fn_metadata; <del> let llvm_env_data_type = type_of::type_of(cx, env_data_type); </del> <ins> // 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(); </ins> let byte_offset_of_var_in_env = machine::llelement_offset(cx, llvm_env_data_type, env_index);

// gdb-command:print *owned // gdb-check:$5 = 6 <ins> // 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 </ins> // === LLDB TESTS ==================================================================================

// lldb-command:print *owned // lldb-check:[...]$4 = 6 <ins> // 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)] </ins> #![allow(unused_variables)] struct Struct {

let struct_ref = &a_struct; let owned = box 6; <del> let closure = || { zzz(); // #break variable = constant + a_struct.a + struct_ref.a + *owned; }; closure(); </del> <ins> { let closure = || { zzz(); // #break variable = constant + a_struct.a + struct_ref.a + *owned; }; closure(); } { let mut unboxed_closure = |&mut:| { zzz(); // #break variable = constant + a_struct.a + struct_ref.a + *owned; }; unboxed_closure(); } </ins> } fn zzz() {()}