Skip to content

rustified_non_exhaustive_enum() can still cause UB at runtime? #1763

@strohel

Description

@strohel

I'm researching what bindgen::Builder options to use for my -sys crate.

The rustified_enum() is clearly marked as potentially causing undefined behavior as described in rust-lang/rust#36927 and #667:

Use this with caution, you probably want to use the non_exhaustive flavor of rust enums instead of this one. Take a look at rust-lang/rust#36927 for more information.

The newer rustified_non_exhaustive_enum(), introduced in #1554, that does the same but marks the enum as #[non_exhaustive] is not marked as potentially dangerous, and is even mentioned as a solution in rustified_enum() docs (above).

rustified_non_exhaustive_enum() indeed seems to be used in the wild with assumption the UB cannot occur, e.g. in cholcombe973/libparted-sys#6.

However, I've been reading the RFC 2008 that introduces #[non_exhaustive] by @clarfon, and it doesn't seem to imply any such guarantees. Quite the contrary, it even mentions that compiler may (continue to) remove the wildcard arm (emphasis mine):

Outside the crate that defines the enum, users should be required to add a wildcard arm to ensure forward-compatibility, like so:
And it should not be marked as dead code, even if the compiler does mark it as dead and remove it.

It seems that #[non_exhaustive] is a compile-time check that doesn't have any effect on generated code, i.e. that there is still a chance of UB even with rustified_non_exhaustive_enum()? Or maybe there is some piece I'm missing that makes it safe (compiler being more cautious than RFC)?

For clarity I'm talking about the case where a C library returns an int value that doesn't map to any variants of the enum as known at compile time. I'll be happy to submit a PR to make docstrings clear once we answer the question here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions