This is an experiment and a work-in-progress. The implementation of the repr(C)
layout algorithm has not been thoroughly tested.
An experiment in embedding layout computations in the type system. This crate encodes the layout algorithm for repr(C)
structs as a type-level computation, using frunk to compute over the type structure of structs and typenum to perform the calculations. The Layout
trait is implemented for types that know their own size at type-checking time. For instance:
```rust use typelayout::{ReprC, Generic, Layout};
pub struct Struct { first: u8, second: u32, }
unsafe impl ReprC for Struct {}
asserteq!(4,
The purpose of this experiment is to express type layout invariants in the typesystem to enable safe abstractions for unsafe code that relies on layout.
For instance, mem::zeroed()
is only valid to call on types for which a sequence of zeroed bits is a valid instance of the type. This function is unsafe to use to initialize structures that have padding bits, since rust is free to assume that padding bits have a particular value.
This library's NoPadding
trait is implemented for types in which the #[repr(packed)]
layout algorithm and #[repr(C)]
algorithm produce layouts of exactly the same size. Using this, we implement a FromZeros
trait for structs meeting the criteria of being safe to initialize with mem::zeroed
:
rust
unsafe impl<T: Generic + ReprC> FromZeros for T
where
T: NoPadding,
Struct<<Self as Generic>::Repr>: FromZeros,
{}
Given this implementation, this will compile:
```rust use typelayout::{ReprC, Generic, Layout, FromZeros};
pub struct Struct { first: u8, second: u8, }
unsafe impl ReprC for Struct {}
assert_eq!(
...but this will not:
```rust use typelayout::{ReprC, Generic, Layout, FromZeros};
pub struct Struct {
first: u8,
second: u16, // padding will be inserted between first
and second
}
unsafe impl ReprC for Struct {}
// Struct
does not implement FromZeros
, because it has a padding byte!
assert_eq!(