Derive Macro IntoBytes
#[derive(IntoBytes)]
Expand description
Analyzes whether a type is IntoBytes
.
This derive analyzes, at compile time, whether the annotated type satisfies
the safety conditions of IntoBytes
and implements IntoBytes
if it is
sound to do so. This derive can be applied to structs and enums (see below
for union support); e.g.:
#[derive(IntoBytes)]
#[repr(C)]
struct MyStruct {
...
}
#[derive(IntoBytes)]
#[repr(u8)]
enum MyEnum {
...
}
§Error Messages
On Rust toolchains prior to 1.78.0, due to the way that the custom derive
for IntoBytes
is implemented, you may get an error like this:
error[E0277]: the trait bound `(): PaddingFree<Foo, true>` is not satisfied
--> lib.rs:23:10
|
1 | #[derive(IntoBytes)]
| ^^^^^^^^^ the trait `PaddingFree<Foo, true>` is not implemented for `()`
|
= help: the following implementations were found:
<() as PaddingFree<T, false>>
This error indicates that the type being annotated has padding bytes, which
is illegal for IntoBytes
types. Consider reducing the alignment of some
fields by using types in the byteorder
module, wrapping field types in
Unalign
, adding explicit struct fields where those padding bytes would
be, or using #[repr(packed)]
. See the Rust Reference’s page on type
layout for more information about type layout and padding.
§Unions
Currently, union bit validity is up in the air, and so
zerocopy does not support #[derive(IntoBytes)]
on unions by default.
However, implementing IntoBytes
on a union type is likely sound on all
existing Rust toolchains - it’s just that it may become unsound in the
future. You can opt-in to #[derive(IntoBytes)]
support on unions by
passing the unstable zerocopy_derive_union_into_bytes
cfg:
$ RUSTFLAGS='--cfg zerocopy_derive_union_into_bytes' cargo build
However, it is your responsibility to ensure that this derive is sound on the specific versions of the Rust toolchain you are using! We make no stability or soundness guarantees regarding this cfg, and may remove it at any point.
We are actively working with Rust to stabilize the necessary language
guarantees to support this in a forwards-compatible way, which will enable
us to remove the cfg gate. As part of this effort, we need to know how much
demand there is for this feature. If you would like to use IntoBytes
on
unions, please let us know.
§Analysis
This section describes, roughly, the analysis performed by this derive to
determine whether it is sound to implement IntoBytes
for a given type.
Unless you are modifying the implementation of this derive, or attempting to
manually implement IntoBytes
for a type yourself, you don’t need to read
this section.
If a type has the following properties, then this derive can implement
IntoBytes
for that type:
- If the type is a struct, its fields must be
IntoBytes
. Additionally:- if the type is
repr(transparent)
orrepr(packed)
, it isIntoBytes
if its fields areIntoBytes
; else, - if the type is
repr(C)
with at most one field, it isIntoBytes
if its field isIntoBytes
; else, - if the type has no generic parameters, it is
IntoBytes
if the type is sized and has no padding bytes; else, - if the type is
repr(C)
, its fields must beUnaligned
.
- if the type is
- If the type is an enum:
- It must have a defined representation (
repr
sC
,u8
,u16
,u32
,u64
,usize
,i8
,i16
,i32
,i64
, orisize
). - It must have no padding bytes.
- Its fields must be
IntoBytes
.
- It must have a defined representation (
This analysis is subject to change. Unsafe code may only rely on the
documented safety conditions of FromBytes
, and must not rely on the
implementation details of this derive.