Closed
Description
Identifiers introduced via an if let
binding can't be inspected in the debugger. For instance:
pub fn do_it(o: Option<i32>) {
if let Some(x) = o {
zzz(x); // #break
}
}
fn zzz(_: i32) { }
Stopping the debugger on line 3 shows no variables in scope other than the function argument o
. I tested this in both gdb and WinDbg.
This appears to be because rustc generates incorrect scoping information for the call to zzz
. Looking at the LLVM IR, I see
...
%x = load i32, i32* %7, align 4, !dbg !36
store i32 %x, i32* %x.dbg.spill, align 4, !dbg !36
call void @llvm.dbg.declare(metadata i32* %x.dbg.spill, metadata !31, metadata !DIExpression()), !dbg !37
call void @_ZN7example3zzz17h59648a546f323dcaE(i32 %x), !dbg !38
...
!5 = distinct !DISubprogram(name: "do_it", linkageName: "_ZN7example5do_it17h549531f5caefefa2E", scope: !7, file: !6, line: 1, type: !8, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !3, templateParams: !19, retainedNodes: !29)
!32 = distinct !DILexicalBlock(scope: !5, file: !6, line: 2, column: 12)
!37 = !DILocation(line: 2, column: 17, scope: !32)
!38 = !DILocation(line: 3, column: 9, scope: !5)
Which puts the call to the zzz
in a different scope than the one x
is in and thus it isn't visible.
This reproduces on all current versions of Rust:
$ rustc +stable --version
rustc 1.61.0 (fe5b13d68 2022-05-18)
$ rustc +beta --version
rustc 1.62.0-beta.3 (a5cf77ca6 2022-06-02)
$ rustc +nightly --version
rustc 1.63.0-nightly (fee3a459d 2022-06-05)