Bug
In compiler/rustc_codegen_llvm/src/debuginfo/mod.rs:213, dbg_var_value emits DW_OP_stack_value after the direct offset but before processing indirect offsets. When both direct_offset > 0 and indirect_offsets is non-empty, the expression becomes:
DW_OP_plus_uconst N, DW_OP_stack_value, DW_OP_deref, ...
DW_OP_stack_value is a terminator op that must appear at the END of a DWARF expression. LLVM's DIExpression::isValid() rejects DW_OP_deref after DW_OP_stack_value, silently dropping the debug info for that variable.
This combination occurs when a MIR variable's debug projection includes both a field access (producing non-zero direct_offset) and a dereference (producing an entry in indirect_offsets), e.g., [Field(1), Deref] for a closure capture accessed through a reference.
Impact
Variables with compound debug projections (field + deref) through the dbg_var_value path are invisible in debuggers (shown as <optimized out>).
Fix
Move DW_OP_stack_value to after all deref/offset operations but before DW_OP_LLVM_fragment.
Bug
In
compiler/rustc_codegen_llvm/src/debuginfo/mod.rs:213,dbg_var_valueemitsDW_OP_stack_valueafter the direct offset but before processing indirect offsets. When bothdirect_offset > 0andindirect_offsetsis non-empty, the expression becomes:DW_OP_stack_valueis a terminator op that must appear at the END of a DWARF expression. LLVM'sDIExpression::isValid()rejectsDW_OP_derefafterDW_OP_stack_value, silently dropping the debug info for that variable.This combination occurs when a MIR variable's debug projection includes both a field access (producing non-zero
direct_offset) and a dereference (producing an entry inindirect_offsets), e.g.,[Field(1), Deref]for a closure capture accessed through a reference.Impact
Variables with compound debug projections (field + deref) through the
dbg_var_valuepath are invisible in debuggers (shown as<optimized out>).Fix
Move
DW_OP_stack_valueto after all deref/offset operations but beforeDW_OP_LLVM_fragment.