Use #[non_exhaustive] to make the generated sys bindings more forward compatible#49
Use #[non_exhaustive] to make the generated sys bindings more forward compatible#49Phantomical wants to merge 2 commits intojimblandy:masterfrom
#[non_exhaustive] to make the generated sys bindings more forward compatible#49Conversation
This commit addresses the two major issues that cargo-semver-checks finds when running over the update changes. The changes I've made are: - Add #[non_exhaustive] annotations to all generated perf_* structs. While this doesn't address all changes the kernel might make (e.g. adding a transparent union works in C but not in Rust) it should go a little bit further in making things backwards compatible should the kernel introduce a new struct field. - Make the various new_bitfield_1 methods private. These get a new parameter every a new bitfield is added to a struct and that is obviously not going to be compatible.
|
My concern about this change stems from wanting It also seems to me that forward compatibility is not something that sys crates are generally expected to provide. That should usually be left to higher-level crates. Regarding (I was hoping to explain this skepticism about the change before you put in the time to make a PR. I apologize for that.) |
|
For what it's worth, crates like |
Granted, it's also not something a user can turn on if its absence is a problem for them. |
|
The alternative I want us to consider is:
|
|
I'm happy to spend some time discussing this PR. In the interest of unblocking changes let's focus on #48 first? That's the one that is blocking me from moving perf-event2 changes upstream, not this PR.
This is literally just a cherry-pick of the two commits. No need to worry here :). It's also easier to have the discussion all in one place with a PR.
I will freely admit, though, that this part confuses me. It's possible there's something I'm missing here. As far as I can tell the only thing that marking these structs as I will note that the only structs I think really need to be
It's worth noting that this doesn't actually solve the problem. If downstream crates want to keep up to date with the current kernel version and also publicly expose their version of
This, on the other hand, is an alternative. Not the crate features bit, since that only works when the integration is only via traits, otherwise you need exclusive features. Re-exporting |
The spec for
So it forbids both field struct expressions ( |
Sure thing - I've run out of time today, but I'll try to take a look tomorrow. |
I suppose I'm less worried about this because outside of something like |
|
Given the nature of The only kind of code that I can see wanting to deal with every last field would be something like that |
There are a bunch of changes that are not breaking in C but are breaking in rust. This is inconvenient both for us and for users, since we end up needing to make frequent breaking changes of
perf-event-open-sys. This carries on throughout the whole ecosystem and leads to breaking changes for any crate that publicly re-exports types fromperf-event-open-sys. This will notably includeperf-event, once I get around to upstreaming some of the various changes made inperf-event2.By making a few structs
#[non_exhaustive]we can make it so that most future updates that the kernel is likely to make are not breaking changes on the rust side. This needs to be combined with #48 in order to really avoid having breaking changes.The main trade-off, of course, is that you can no longer do
perf_event_attr { type_: blah, ...Default::default() }. This is a real cost, but I think the benefits of avoid breaking changes are worth it here.WRT
const, you already can't set any of the bitflags onperf_event_attrin a const context. However, you can still create a zeroedperf_event_attrin a const context by usingstd::mem::zeroed, like this:A quick search on sourcegraph hasn't found anyone actually doing this, so I'm not sure this is much of concern for existing users.