-
Notifications
You must be signed in to change notification settings - Fork 700
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add enum option constified_enum + rustified_enum
with conversions
#2646
Comments
cc @ojeda |
I think a good compromise would be a subset of what you mention: pub type foo_ctype = ::std::os::raw::c_uint;
#[repr(u32)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub enum foo {
one = 1,
two = 2,
three = 3,
}
impl TryFrom<foo_ctype> for foo {
type Error = foo_ctype;
fn try_from(value: foo_ctype) -> Result<foo, Self::Error> {
match value {
1 => Ok(foo::one),
2 => Ok(foo::two),
3 => Ok(foo::three),
_ => Err(value),
}
}
} Even though such thing could be generated by a procedural macro crate without issue. The rest of it I wouldn't implement because:
|
I forgot about the From/TryFrom conflict, thanks for pointing it out. Everything you said sounds reasonable to me, would you accept a PR to add that enum option? A proc macro could indeed do this but I think it would have to be an attribute macro rather than derive since it needs the size context and has to add a separate trait. Is there a way to add attribute macros? I know know of adding derives |
I think we need to figure out the API for this first, but it sounds like a reasonable feature:
The issue I have with the second option is that potentially someone could want to implement this for newtype enums or non-exhaustive, rustified enums. So I'd favor the first option in that case but I'm open to discussion.
I agree, i think an attribute macro would be more appropriate. Adding attribute macros is not that different from a derive macro iirc: https://doc.rust-lang.org/reference/procedural-macros.html#attribute-macros This could be an option if you want to add this quickly to rust-for-linux instead of waiting for this feature to be implemented and released in bindgen and then update the bindgen version on your build scripts (as I know that y'all don't bump your bindgen version that often) |
Even if a procedural macro is able to do it, On On implementing some of the methods or not: I agree Having said that, if the better way is to use Moreover, |
Yeah I think this is a good alternative if you need more fine tuning in the future.
Hmm... I would consider a
I suspect that this optimization is less prone to break for fieldless enums in comparison to the
I think adding this
See my previous comment. |
Yeah, it would be bad to do so unconditionally for everything (when I suggested the overall idea in Zulip, I was thinking of having a constructor, rather than implementing
Agreed, having the option to choose here would be very nice. In fact, doing so per enum (like how the "kind" of the enum can already be chosen per enum) would be nice too. |
I think the main "blocker" here is the CLI API for these two options. The library API is more or less clear:
One option would be to copy the |
@ojeda Taking a look at this, and I just want to make sure I'm understanding the final request after the discussion. As I'm understanding it, we just want a |
A safe, fallible way may be enough, but it depends on the codegen when used with e.g.
It depends on what the maintainers want to do here, but since other things can be customized per-enum, it may make sense to allow that per-enum too, I am not sure. My (possibly naïve) idea for the kernel is that, when we have this, we will just enable it for all enums there (with both the safe, fallible and the unsafe versions) and that's it. In other words, we would just have a single "kind" of enum (this one -- which I would argue should be the default in |
Okay! I'll start with an implementation of independent safe and unsafe wrappers and have the policy be applied to all enums and see what the maintainers think. |
All ways of interop with C enums unfortunately have some downsides.
constified-enum
,constified-enum-module
,newtype-enum
, andbitfield-enum
can't be matched exhaustively: using the below demo, for example:If a new variant is added to the enum, it gets swallowed with the
_
. Or a variant may have accidentally be emitted in the first place.rustified_enum
andrustified-non-exhaustive-enum
provide more ergonomic solutions and are easier to match, but they don't have good handling for if C provides value not covered by a variant - which is allowed in C. This leads to bugs that can be impossible to track down.Proposal: allow creating both a constified enum and a Rust enum, and autogenerate three conversion methods between them:
Into
TryInto
Input C/C++ Header
Bindgen Invocation
bindgen test.h bindgen test.h --rustified-enum '.*'
Actual Results
Expected Results
Something like this:
All bindings would use
foo_ctype
as the value type, but this would give an easy way to turn it into something exhaustiveThe text was updated successfully, but these errors were encountered: