gtk-rs-core
gtk-rs-core copied to clipboard
Allowing safe construction of unknown enums via the `__Unknown()` variant is potentially unsound
C code that gets such unknown enum values might do anything.
Not sure how we should handle this. Maybe:
#[non_exhaustive]
pub enum Foo {
A,
B,
C,
Unknown(i32), // no `pub`!
}
impl Foo {
pub fn is_unknown(self) -> bool { ... } // I think this is actually unnecessary as you can as well match on it... just not on the contained value
pub fn value(self) -> i32 { ... } // also returns unknown values
pub unsafe fn unknown(value: i32) -> Self { ... }
}
@bilelmoussaoui @GuillaumeGomez What do you think?
No pub wouldn't change anything on an enum variant (unless you meant #[doc(hidden)]
? But otherwise I think it's a good idea.
If the field in the enum variant is not public then you can't construct it, and you can't match on its content either.
Unless I missed something, this code works:
mod whatever {
pub enum Foo {
What,
Bar(i32),
}
}
fn main() {
// you can build it
let x = whatever::Foo::Bar(0);
match x {
whatever::Foo::What => {}
// you can match on it
whatever::Foo::Bar(i) => {}
}
}
Only fields of unions and structs can be private.
Oh indeed. Well, we can make it a Unknown(UnknownEnumValue)
and that type contains the value.
That sounds good, and then UnknownEnumValue
can have an unsafe constructor