rust: pin-init: allow Zeroable derive macro to also be applied to unions

Enabling the same behavior for unions as for structs is correct, but
could be relaxed: the valid bit patterns for unions are the union of all
valid bit patterns of their fields. So for a union to implement
`Zeroable`, only a single field needs to implement `Zeroable`. This can
be a future improvement, as it is currently only needed for unions where
all fields implement `Zeroable`.

There is no danger for mis-parsing with the two optional tokens (ie
neither one or both tokens are parsed), as the compiler will already
have rejected that before giving it as the input to the derive macro.

Link: 5927b497ce
Signed-off-by: Benno Lossin <benno.lossin@proton.me>
This commit is contained in:
Benno Lossin 2025-04-21 22:18:41 +00:00
parent 983d13fc2c
commit a313d41a2b

View file

@ -1412,4 +1412,34 @@ macro_rules! __derive_zeroable {
}
};
};
(parse_input:
@sig(
$(#[$($struct_attr:tt)*])*
$vis:vis union $name:ident
$(where $($whr:tt)*)?
),
@impl_generics($($impl_generics:tt)*),
@ty_generics($($ty_generics:tt)*),
@body({
$(
$(#[$($field_attr:tt)*])*
$field_vis:vis $field:ident : $field_ty:ty
),* $(,)?
}),
) => {
// SAFETY: Every field type implements `Zeroable` and padding bytes may be zero.
#[automatically_derived]
unsafe impl<$($impl_generics)*> $crate::Zeroable for $name<$($ty_generics)*>
where
$($($whr)*)?
{}
const _: () = {
fn assert_zeroable<T: ?::core::marker::Sized + $crate::Zeroable>() {}
fn ensure_zeroable<$($impl_generics)*>()
where $($($whr)*)?
{
$(assert_zeroable::<$field_ty>();)*
}
};
};
}