1 个不稳定版本
0.1.0 | 2019年7月30日 |
---|
#19 in #repr
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