zerocopy

Derive Macro FromZeroes

source
#[derive(FromZeroes)]
Expand description

Analyzes whether a type is FromZeroes.

This derive analyzes, at compile time, whether the annotated type satisfies the safety conditions of FromZeroes and implements FromZeroes if it is sound to do so. This derive can be applied to structs, enums, and unions; e.g.:

#[derive(FromZeroes)]
struct MyStruct {
    ...
}

#[derive(FromZeroes)]
#[repr(u8)]
enum MyEnum {
    ...
}

#[derive(FromZeroes)]
union MyUnion {
    ...
}

§Analysis

This section describes, roughly, the analysis performed by this derive to determine whether it is sound to implement FromZeroes for a given type. Unless you are modifying the implementation of this derive, or attempting to manually implement FromZeroes for a type yourself, you don’t need to read this section.

If a type has the following properties, then this derive can implement FromZeroes for that type:

  • If the type is a struct, all of its fields must be FromZeroes.
  • If the type is an enum, it must be C-like (meaning that all variants have no fields) and it must have a variant with a discriminant of 0. See the reference for a description of how discriminant values are chosen.
  • The type must not contain any UnsafeCells (this is required in order for it to be sound to construct a &[u8] and a &T to the same region of memory). The type may contain references or pointers to UnsafeCells so long as those values can themselves be initialized from zeroes (FromZeroes is not currently implemented for, e.g., Option<&UnsafeCell<_>>, but it could be one day).

This analysis is subject to change. Unsafe code may only rely on the documented safety conditions of FromZeroes, and must not rely on the implementation details of this derive.

§Why isn’t an explicit representation required for structs?

Neither this derive, nor the safety conditions of FromZeroes, requires that structs are marked with #[repr(C)].

Per the Rust reference,

The representation of a type can change the padding between fields, but does not change the layout of the fields themselves.

Since the layout of structs only consists of padding bytes and field bytes, a struct is soundly FromZeroes if:

  1. its padding is soundly FromZeroes, and
  2. its fields are soundly FromZeroes.

The answer to the first question is always yes: padding bytes do not have any validity constraints. A discussion of this question in the Unsafe Code Guidelines Working Group concluded that it would be virtually unimaginable for future versions of rustc to add validity constraints to padding bytes.

Whether a struct is soundly FromZeroes therefore solely depends on whether its fields are FromZeroes.