typelayout 0.1.0

type-level layout reflection
Documentation
  • Coverage
  • 100%
    10 out of 10 items documented2 out of 3 items with examples
  • Size
  • Source code size: 15.69 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 2.43 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 18s Average build duration of successful builds.
  • all releases: 18s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • jswrenn

typelayout

Documentation

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:

use typelayout::{ReprC, Generic, Layout};

#[derive(Generic)]
#[repr(C)]
pub struct Struct {
  first: u8,
  second: u32,
}

unsafe impl ReprC for Struct {}

assert_eq!(4, <Struct as Layout>::ALIGN);
assert_eq!(8, <Struct as Layout>::SIZE);

Layout Invariants

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:

unsafe impl<T: Generic + ReprC> FromZeros for T
where
  T: NoPadding,
  Struct<<Self as Generic>::Repr>: FromZeros,
{}

Given this implementation, this will compile:

use typelayout::{ReprC, Generic, Layout, FromZeros};

#[derive(Generic, Default, Debug, PartialEq)]
#[repr(C)]
pub struct Struct {
  first: u8,
  second: u8,
}

unsafe impl ReprC for Struct {}

assert_eq!(<Struct as Default>::default(), <Struct as FromZeros>::zeroed());

...but this will not:

use typelayout::{ReprC, Generic, Layout, FromZeros};

#[derive(Generic, Default, Debug, PartialEq)]
#[repr(C)]
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!(<Struct as Default>::default(), <Struct as FromZeros>::zeroed());