diff options
author | Benno Lossin <benno.lossin@proton.me> | 2023-08-14 11:46:41 +0300 |
---|---|---|
committer | Miguel Ojeda <ojeda@kernel.org> | 2023-08-21 15:31:48 +0300 |
commit | 071cedc84e907f6984b3de3285ec2b077d3c3cdb (patch) | |
tree | ee2ef5892e8c925df4f1b16df99527c5c564aab3 /rust/kernel/init/macros.rs | |
parent | f8badd150763ae0f9c8482fabe0fdbac81735d34 (diff) | |
download | linux-071cedc84e907f6984b3de3285ec2b077d3c3cdb.tar.xz |
rust: add derive macro for `Zeroable`
Add a derive proc-macro for the `Zeroable` trait. The macro supports
structs where every field implements the `Zeroable` trait. This way
`unsafe` implementations can be avoided.
The macro is split into two parts:
- a proc-macro to parse generics into impl and ty generics,
- a declarative macro that expands to the impl block.
Suggested-by: Asahi Lina <lina@asahilina.net>
Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Link: https://lore.kernel.org/r/20230814084602.25699-4-benno.lossin@proton.me
[ Added `ignore` to the `lib.rs` example and cleaned trivial nit. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Diffstat (limited to 'rust/kernel/init/macros.rs')
-rw-r--r-- | rust/kernel/init/macros.rs | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/rust/kernel/init/macros.rs b/rust/kernel/init/macros.rs index 474ed36f84a5..0b0ffbc901a7 100644 --- a/rust/kernel/init/macros.rs +++ b/rust/kernel/init/macros.rs @@ -1215,3 +1215,38 @@ macro_rules! __init_internal { ); }; } + +#[doc(hidden)] +#[macro_export] +macro_rules! __derive_zeroable { + (parse_input: + @sig( + $(#[$($struct_attr:tt)*])* + $vis:vis struct $name:ident + $(where $($whr:tt)*)? + ), + @impl_generics($($impl_generics:tt)*), + @ty_generics($($ty_generics:tt)*), + @body({ + $( + $(#[$($field_attr:tt)*])* + $field:ident : $field_ty:ty + ),* $(,)? + }), + ) => { + // SAFETY: Every field type implements `Zeroable` and padding bytes may be zero. + #[automatically_derived] + unsafe impl<$($impl_generics)*> $crate::init::Zeroable for $name<$($ty_generics)*> + where + $($($whr)*)? + {} + const _: () = { + fn assert_zeroable<T: ?::core::marker::Sized + $crate::init::Zeroable>() {} + fn ensure_zeroable<$($impl_generics)*>() + where $($($whr)*)? + { + $(assert_zeroable::<$field_ty>();)* + } + }; + }; +} |