[legacy] Allow other attributes in #[pin_data] structs#93
[legacy] Allow other attributes in #[pin_data] structs#93nertpinx wants to merge 1 commit intoRust-for-Linux:legacyfrom
Conversation
|
Thanks for your PR! I'm currently very busy and won't be taking a look for the next few weeks, sorry about that. This limitation is annoying and I wanted to get rid of it in the future. I will be merging #89 in the next kernel cycle (in around 5-6 weeks). Would you mind re-doing the work based on The test looks good by the way! |
|
I'll see what I can do. I finally understood how to fix it in the legacy branch and I have to figure out how it works after #89 but I'll do my best. |
BennoLossin
left a comment
There was a problem hiding this comment.
Sorry for the long delay. I'm planning to merge #89 in this kernel cycle, so we should have a new version in around 5 weeks. Following that, I will publish the crate under pin-init. I also plan to make a new legacy release at that time that explains that the move to/merge with pin-init is complete.
Now if you really need this earlier, I can also make a new legacy release in the meantime.
When using a macro with custom attributes in a `#[pin_data]` struct it can mess up the generated `__Unpin` struct. This commit catches all other (not just `#[pin]`) attributes, moves the `#[cfg]` one in `$accum` (so that it is used for both the original struct and the generated `__Unpin` one), and keeps all other (custom, documentation, etc.) only in the original struct. With this commit a struct can use both #[pin] and other custom attributes, allowing combining multiple attribute macros without clashing. To keep this functionality this commit also adds a test with a custom attribute that fails without this fix. Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
|
For what it's worth I rebased this PR with updated changes, even though I'm not sure I'll use it in the end. I also tested that Anyway, if this does not make sense to you or anyone, feel free to just close it. |
When the
__pin_data!(find_pinned_fields:part of the macro encounters an unknown attribute (anything apart from$[pin]) before a field, it is put into the accumulator and the macro proceeds further. Whatever is in the accumulator is later saved into$fieldsand then also into$pinnedor$not_pinneddepending on whether that field is pinned. Pinned fields, with all their unknown attributes are also used in the internal__Unpinstruct.A field can have multiple different attributes, mostly belonging into two different categories. Built-in (defined by the language itself) and arbitrary (any other attribute that is used by another proc-macro crate).
Out of the built-in ones [1] the only things that make sense to be usable for struct fields are most probably just "cfg", "doc", lint levels ("allow", "expect", "warn", "deny", "forbid"), and "deprecated". Out of these the only one that makes sense to keep around for the pin_data macro is "cfg" since that one does a conditional compilation and we only want the members to be included if they are included in the original struct.
From the arbitrary (basically unknown) ones there is no reason for them to be used, mainly because they will likely be part of a derive which will not be included for the
__Unpinstruct, therefore making the code fail to compile if included. Since those need to be kept for the original struct, move them to the$fieldsinstead of$accumin order not to pollute thestruct __Unpinwith unknown attributes.To put this all together, add a test with a custom attribute that fails without this fix. Unfortunately, another crate needs to be added for the test.
[1] https://doc.rust-lang.org/reference/attributes.html#built-in-attributes-index