Derive Macro bytemuck_derive::Zeroable
source · #[derive(Zeroable)]
{
// Attributes available to this derive:
#[bytemuck]
#[zeroable]
}
Expand description
Derive the Zeroable
trait for a type.
The macro ensures that the type follows all the the safety requirements
for the Zeroable
trait.
The following constraints need to be satisfied for the macro to succeed on a struct:
- All fields in the struct must implement
Zeroable
The following constraints need to be satisfied for the macro to succeed on an enum:
- The enum has an explicit
#[repr(Int)]
,#[repr(C)]
, or#[repr(C, Int)]
. - The enum has a variant with discriminant 0 (explicitly or implicitly).
- All fields in the variant with discriminant 0 (if any) must implement
Zeroable
The macro always succeeds on unions.
§Example
#[derive(Copy, Clone, Zeroable)]
#[repr(C)]
struct Test {
a: u16,
b: u16,
}
#[derive(Copy, Clone, Zeroable)]
#[repr(i32)]
enum Values {
A = 0,
B = 1,
C = 2,
}
#[derive(Clone, Zeroable)]
#[repr(C)]
enum Implicit {
A(bool, u8, char),
B(String),
C(std::num::NonZeroU8),
}
§Custom bounds
Custom bounds for the derived Zeroable
impl can be given using the
#[zeroable(bound = "")]
helper attribute.
Using this attribute additionally opts-in to “perfect derive” semantics, where instead of adding bounds for each generic type parameter, bounds are added for each field’s type.
§Examples
#[derive(Clone, Zeroable)]
#[zeroable(bound = "")]
struct AlwaysZeroable<T> {
a: PhantomData<T>,
}
AlwaysZeroable::<std::num::NonZeroU8>::zeroed();
#[derive(Copy, Clone, Zeroable)]
#[repr(u8)]
#[zeroable(bound = "")]
enum MyOption<T> {
None,
Some(T),
}
assert!(matches!(MyOption::<std::num::NonZeroU8>::zeroed(), MyOption::None));
#[derive(Clone, Zeroable)]
#[zeroable(bound = "T: Copy")]
struct ZeroableWhenTIsCopy<T> {
a: PhantomData<T>,
}
ZeroableWhenTIsCopy::<String>::zeroed();
The restriction that all fields must be Zeroable is still applied, and this is enforced using the mentioned “perfect derive” semantics.
#[derive(Clone, Zeroable)]
#[zeroable(bound = "")]
struct ZeroableWhenTIsZeroable<T> {
a: T,
}
ZeroableWhenTIsZeroable::<u32>::zeroed();
ZeroableWhenTIsZeroable::<String>::zeroed();