Expand description
A “workaround” for missing generic statics in Rust.
This crate is experimental and might not be fully sound. Use at your own risk.
The core functionality is provided by Namespace::generic_static
.
use std::sync::atomic::{AtomicPtr, Ordering};
use generic_statics::{define_namespace, Namespace};
define_namespace!(Test);
let a = Test::generic_static::<AtomicPtr<usize>>().load(Ordering::Relaxed);
§Caveats and Limitations
This crate is nightly only and relies on #![feature(asm_const)]
.
The generic statics provided by this crate use static allocation (i.e. no dynamic allocation will occur at runtime) and is almost zero-cost (aside from some inline asm instructions for computing the static address).
However, this crate is only best-effort (i.e. best-effort stable addresses):
use generic_statics::{define_namespace, Namespace};
define_namespace!(Test);
// This is *not* guaranteed, but in usual cases this will work just fine.
assert_eq!(
Test::generic_static::<usize>() as *const _,
Test::generic_static::<usize>() as *const _
);
The used approach relies on inline assembly to instantiate/reserve static data for each
monomorphized variant of the function.
Unfortunately inlining will return a different version of the data and thus will not return
stable addresses.
However, Namespace::generic_static
is marked #[inline(never)]
which should provide stable
addresses in most situations
(Note that #[inline(never)]
is just a hint to the compiler and doesn’t guarantee anything).
Only “zeroable” types are allowed for now due to inline asm restrictions.
This crate only supports these targets for now:
- macOS
x86_64
,aarch64
- Linux
x86_64
,aarch64
- FreeBSD
x86_64
,aarch64
- Windows
x86_64