Skip to content

Identifiers introduced via if let binding can't be debugged #97799

Closed
@wesleywiser

Description

@wesleywiser

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-debuginfoArea: Debugging information in compiled programs (DWARF, PDB, etc.)C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions