-
Notifications
You must be signed in to change notification settings - Fork 768
Description
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.