3 ms·
Rust has an annotation to mark that an enum is non-exhaustive[1], and a mechanism for declaring an enum as being laid out in a manner compatible with C[2]. I'v
by andrewaylett 6y ago
Rust has an annotation to mark that an enum is non-exhaustive[1], and a mechanism for declaring an enum as being laid out in a manner compatible with C[2]. I've not tried using them together :).
In general, it _is_ possible for any C data layout to be represented in Rust -- but it's not necessarily the case that the representation has the same name. And it's also not the case that we can safely pass memory from C to Rust without validating the content, even if the representation is equivalent for all valid values.
[1] https://blog.rust-lang.org/2019/12/19/Rust-1.40.0.html#non_exhaustive-structs-enums-and-variants https://blog.rust-lang.org/2019/12/19/Rust-1.40.0.html#non_e...
[2] https://rust-lang.github.io/unsafe-code-guidelines/layout/enums.html#repr-annotations-accepted-on-enums https://rust-lang.github.io/unsafe-code-guidelines/layout/en...
- drran 6y agoTo my surprise, it works partially on latest stable Rust: #[non_exhaustive] #[repr(C)] #[derive(Debug)] #[allow(dead_code)] enum Foo { A = 0, B = 1, C = 2, } pub fn main() { let bar = unsafe { std::mem::transmute::<i32, Foo>(33) }; println!("{:?}", bar); let s = match bar { Foo::A => ("A", bar as i32), Foo::B => ("B", bar as i32), Foo::C => ("C", bar as i32), _ => ("Unknown", bar as i32), }; println!("{:?}", s); } Standard Output C ("Unknown", 33)