Closed jozanza closed 3 months ago
Pod
/AnyBitPattern
can only be implemented for an enum if every possible value of the discriminant has a valid variant associated with it. For example, the following code compiles under this PR, but has undefined behavior, since x[2]
is not a valid instance of Thing
.
use bytemuck::{Zeroable, Pod};
#[derive(Clone, Copy, Debug, Zeroable, Pod)]
#[repr(u8)]
enum Thing {
A = 0,
B = 1,
}
fn main() {
let x: &[Thing] = bytemuck::cast_slice(&[0_u8, 1, 2]);
dbg!(x);
}
This PR could be updated to check if there are exactly 2**int_repr_bitsize
defined variants, or IMO it'd probably be "good enough" to only support u8
and i8
with exactly 256 variants; having a #[repr(u16)]
65536-variant enum probably already takes too long to compile for anyone to want to do it (takes ~4 seconds on my machine to compile a hello world with such an enum), and a #[repr(u32)]
4294967296
-variant enum won't compile at all due to source file length restrictions IIRC.
Zeroable we could maybe support in more cases though, if we can determine that zero-bits is a valid value
Hmm, if this passed miri then maybe we need more miri tests? dunno if miri supports "should fail miri" the same as normal tests do
Okay I see we want to avoid that case of undefined behavior. I can definitely add a check for all 256 u8 variants, however, that kills the ergonomics and definitely causes Pod to be infeasible for other integer types.
Is it possible we could just make the enum Pod derive not do the exhaustiveness check and make another trait (let's call it Exhaustive
) that enforces the exhaustiveness for Pod enums -- basically requiring repr u8 and all 256 variants to be defined as was mentioned?
I'm personally fine with the undefined behavior for out of range Pod enum variants by default as I just want to use enums in Pod structs and to serialize to/from a u8.
But either way, I'm happy to move forward with whatever works for your project.
I'm personally fine with the undefined behavior for out of range Pod enum variants by default
You're the first rust programmer I've ever seen say this.
But no, we don't accept code that leads to UB.
You could look at implementing TryFrom on your enum so that it can convert from an int to the enum type.
LOL fair enough! Someone needs to take away my Rust card 😂
You may want to look into derive(CheckedBitPattern)
which does not require that all bit patterns are valid for an enum.
Since we fundamentally can't accept this change, I'm gonna close it out.
Hey folks! I was looking at this PR https://github.com/Lokathor/bytemuck/pull/233 and decided to take things a step further so we could finally derive the Pod trait for fieldless enums. Hopefully, this is something this project is interested in supporting. If so, I'm happy to make further updates to clean up this PR. Cheers!
Also related to this issue: https://github.com/Lokathor/bytemuck/issues/230