1 个不稳定版本

0.1.0 2019年7月30日

#19 in #repr

MIT 许可证

14KB
244

typelayout

文档

这是一个实验,仍在进行中。对于 repr(C) 布局算法的实现还没有经过彻底测试。

将布局计算嵌入类型系统的实验。这个crate将 repr(C) 结构的布局算法编码为类型级别计算,使用 frunk 计算结构类型以及 typenum 执行计算。对于在类型检查时知道自身大小的类型实现了 Layout 特性。例如

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);

布局不变性

这个实验的目的是在类型系统中表达类型布局不变性,以使依赖于布局的不安全代码能够进行安全抽象。

例如,mem::zeroed() 只能对那些零位序列是类型有效实例的类型调用。此函数用于初始化具有填充位的结构是不安全的,因为Rust可以自由地假设填充位具有 特定 的值。

此库的 NoPadding 特性实现了对那些 #[repr(packed)] 布局算法和 #[repr(C)] 算法产生相同大小的布局的类型。利用这个特性,我们为满足可以安全使用 mem::zeroed 初始化的结构实现了 FromZeros 特性。

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

给定这个实现,这将编译

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());

...但 这将不会编译

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());

依赖关系

~2.5MB
~55K SLoC