#generics #static #caveats

nightly static-generics

Rust 的静态泛型

1 个不稳定版本

0.1.0 2023 年 5 月 30 日

#generics 中排名第 71

MIT/Apache 许可

12KB
190 行(不包括注释)

static-generics

此 crate 是实验性的,可能不是完全可靠的。使用风险自担。

Rust 中缺失静态泛型的一个解决方案。

use std::{ptr, sync::atomic::{AtomicPtr, Ordering}};

// This code doesn't work.
static A<T>: AtomicPtr<T> = AtomicPtr::new(ptr::null_mut());
let a = A::<usize>.load(Ordering::Relaxed);

使用 static-generics

use std::sync::atomic::{AtomicPtr, Ordering};
use static_generics::static_generic;

// This works.
let a = static_generic::<AtomicPtr<usize>>().load(Ordering::Relaxed);

注意事项

此 crate 仅适用于 nightly 版本,并依赖于 #![feature(asm_const)].

此 crate 提供的静态泛型使用静态分配(运行时不进行动态分配)且几乎无成本(除了用于计算静态地址的一些内联汇编指令)。

然而,此 crate 只提供尽力而为的稳定地址

use static_generics::static_generic;
assert_eq!(static_generic::<usize>() as *const _, static_generic::<usize>() as *const _);

所使用的方法依赖于内联汇编为函数的每个单形化变体实例化/预留静态数据。不幸的是,内联将返回不同的数据版本,因此不会返回稳定的地址。但是,static_generic 被标记为 #[inline(never)],这应该在大多数情况下提供稳定的地址(注意,#[inline(never)] 仅是编译器的提示,并不保证任何内容)。

由于内联汇编的限制,目前只允许“可零化”类型。

此 crate 目前仅支持以下目标

  • macOS x86_64, aarch64
  • Linux x86_64, aarch64
  • FreeBSD x86_64, aarch64

由于缺少某些内联汇编指令(.pushsection.popsection)的支持,目前不支持 Windows。

无运行时依赖