On windows, with this repro case, compiled with cargo rustc (--emit=asm,llvm-ir)
fn main() {
foobar(5);
}
fn foobar(n: usize) -> () {
let foo = if n == 5 {
0
} else {
1
};
let bar = if n == 6 {
1
} else {
2
};
}
I expected to see this happen: When stepping through code source line-by-line (in either WinDbg, or the LLDB-based RustRover debugger), I'd expect the value of foo to be available and shown in the locals window once we reach line 12 (let bar = ...).
Instead, this happened: Instead, the value is only available when stepping past that location, either to the next line, or even to the next assembly instruction.
The ultimate reason for this is that the emitted debuginfo is inaccurate: (from the asm output)
.def _ZN20rust_debuginfo_repro6foobar17h5720b41e41166300E;
.scl 3;
.type 32;
.endef
.section .text,"xr",one_only,_ZN20rust_debuginfo_repro6foobar17h5720b41e41166300E,unique,1
.p2align 4
_ZN20rust_debuginfo_repro6foobar17h5720b41e41166300E:
.Lfunc_begin1:
.cv_func_id 1
.cv_loc 1 1 5 0
.seh_proc _ZN20rust_debuginfo_repro6foobar17h5720b41e41166300E
subq $24, %rsp
.seh_stackalloc 24
.seh_endprologue
movq %rcx, (%rsp)
movq %rcx, 16(%rsp)
.Ltmp2:
.cv_loc 1 1 6 0
cmpq $5, %rcx
jne .LBB1_2
.cv_loc 1 1 7 0
movl $0, 8(%rsp)
.cv_loc 1 1 6 0
jmp .LBB1_3
.LBB1_2:
.cv_loc 1 1 9 0
movl $1, 8(%rsp)
.LBB1_3:
.cv_loc 1 1 12 0
movq (%rsp), %rax # <- Line 12 breakpoint/stepping stops here
.Ltmp3: # <- "foo" valid starting from here (see debug record at the end)
cmpq $6, %rax
jne .LBB1_5
.cv_loc 1 1 13 0
movl $1, 12(%rsp)
.cv_loc 1 1 12 0
jmp .LBB1_6
.LBB1_5:
.cv_loc 1 1 15 0
movl $2, 12(%rsp)
.Ltmp4:
.LBB1_6:
.cv_loc 1 1 17 0
.seh_startepilogue
addq $24, %rsp
.seh_endepilogue
retq
.Ltmp5:
.Lfunc_end1:
.seh_endproc
# later...
# Debug record for "foo" variable
.asciz "foo"
.p2align 2, 0x0
.Ltmp49:
.cv_def_range .Ltmp3 .Ltmp4, frame_ptr_rel, 8 # Valid from .Ltmp3 to .Ltmp4
Interestingly, I compared the debug output generated for DWARF (https://godbolt.org/z/4b9T8fvvs) and while it appears to have the same validity range as the CodeView version, it rather assigns the source locations differently:
.LBB0_2:
.loc 1 9 9
mov dword ptr [rsp - 16], 1
.LBB0_3:
.loc 1 0 9 is_stmt 0 # <- Marked as line 12 in PDB, but "no line" here
mov rax, qword ptr [rsp - 24]
.Ltmp1: # <- "foo" validity starts here
.loc 1 12 18 is_stmt 1
cmp rax, 6
jne .LBB0_5
This means that a breakpoint on that line ends up stopping at the cmp instead, and "foo" is visible as expected. (Even though, in reality, the value on the stack was already available on the previous instruction, but this is much less of an issue.)
Meta
rustc --version --verbose:
rustc 1.93.0-beta.6 (7bea8c6cf 2026-01-09)
binary: rustc
commit-hash: 7bea8c6cf1ccce6b06c26d9a435e85cd0b9113bb
commit-date: 2026-01-09
host: x86_64-pc-windows-msvc
release: 1.93.0-beta.6
LLVM version: 21.1.8
I found similar reports in the RustRover bug tracker going back several years, so this is unlikely to be a recent regression: RUST-15126 RUST-6821
On windows, with this repro case, compiled with
cargo rustc(--emit=asm,llvm-ir)I expected to see this happen: When stepping through code source line-by-line (in either WinDbg, or the LLDB-based RustRover debugger), I'd expect the value of
footo be available and shown in the locals window once we reach line 12 (let bar = ...).Instead, this happened: Instead, the value is only available when stepping past that location, either to the next line, or even to the next assembly instruction.
The ultimate reason for this is that the emitted debuginfo is inaccurate: (from the asm output)
Interestingly, I compared the debug output generated for DWARF (https://godbolt.org/z/4b9T8fvvs) and while it appears to have the same validity range as the CodeView version, it rather assigns the source locations differently:
This means that a breakpoint on that line ends up stopping at the
cmpinstead, and "foo" is visible as expected. (Even though, in reality, the value on the stack was already available on the previous instruction, but this is much less of an issue.)Meta
rustc --version --verbose:I found similar reports in the RustRover bug tracker going back several years, so this is unlikely to be a recent regression: RUST-15126 RUST-6821