Skip to content

DWARF variant metadata for compressed enums with niche is ambiguous #62839

Closed
@Kobzol

Description

@Kobzol

After the change of DWARF metadata generation for enums (#54004), compressed enums with niches are not distinguishable from tagged or empty enums in GDB pretty printing (not in the actual Rust pretty printers, as they do not support the new format yet).

In the new enum debug metadata format, enums have a variant field that should serve as a discriminant to pretty print the correct variant of the enum. However, when the Rust enum has a niche discriminant, the variant contains some integer value that has to be interpreted in a special way. Before #54004, compressed enums were marked (https://github.com/rust-lang/rust/blob/master/src/etc/debugger_pretty_printers_common.py#L230 ) and could be distinguished from normal enums. But currently, the variant field has the same name for all kinds of enums and therefore it is not possible to distinguish (and correctly pretty print) compressed enums.

Example:

enum MyEnum1<T> { A(T), B }

fn main()
{
    let a1 = MyEnum1::A(String::from("111"));
    let a2: MyEnum1<String> = MyEnum1::B;
}

This is a niche enum that gets its debug niche value here (https://github.com/rust-lang/rust/blob/master/src/librustc_codegen_llvm/debuginfo/metadata.rs#L1516).

Printing this in GDB:

# valobj is the debugged variable
content = valobj[valobj.type.fields()[0]]
print(valobj.type.fields()[0].name, content[content.type.fields()[0]])

outputs:

<<variant>> 94022087334720 // a1
<<variant>> 0 // a2

As opposed to a tagged enum:

let a1 = MyEnum1::A(5);
let a2: MyEnum1<u32> = MyEnum1::B;

which outputs:

<<variant>> 0 // a1
<<variant>> 1 // a2

I don't see any way how can I distinguish that this is not a normal enum and that the discriminant has to be handled in a special way. And even if there was such a way, how am I supposed to interpret the discriminant? In the old version the name of the discriminant encoded some metadata that helped to interpret the value (https://github.com/rust-lang/rust/blob/master/src/etc/debugger_pretty_printers_common.py#L289), but there's nothing like that in the new version. Am I missing something?

I noticed this while modifying enum pretty printers in the IntelliJ Rust plugin (intellij-rust/intellij-rust#4155).

Related issues:
#54004
#55701
#59509

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-debuginfoArea: Debugging information in compiled programs (DWARF, PDB, etc.)A-layoutArea: Memory layout of typesC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions