pub unsafe trait Namespace:
'static
+ Send
+ Sync
+ Copy
+ Clone {
// Provided methods
fn generic_static<T>() -> &'static T
where T: 'static + Zeroable { ... }
fn generic_static_const<T, const N: usize>() -> &'static T
where T: 'static + Zeroable { ... }
unsafe fn generic_static_mut<T>() -> *mut T
where T: 'static + Zeroable { ... }
unsafe fn generic_static_const_mut<T, const N: usize>() -> *mut T
where T: 'static + Zeroable { ... }
}Expand description
A namespace for generic statics.
§Safety
Implementing this trait is not unsafe per-se but you should use the crate::define_namespace
instead.
Provided Methods§
Sourcefn generic_static<T>() -> &'static Twhere
T: 'static + Zeroable,
fn generic_static<T>() -> &'static Twhere
T: 'static + Zeroable,
The returned reference points to the static namespaced global variable for each
generic T. The static’s value is zero-initialized.
On targets with a fast weak-COMDAT + asm! path this compiles to 1-2
instructions with no runtime overhead. Anywhere else (unsupported
architectures, Miri, and the Cranelift backend) the std feature enables a
slow Mutex<HashMap>-based fallback; without it compilation fails with compile_error!.
Sourcefn generic_static_const<T, const N: usize>() -> &'static Twhere
T: 'static + Zeroable,
fn generic_static_const<T, const N: usize>() -> &'static Twhere
T: 'static + Zeroable,
The returned reference points to the static namespaced global variable for each
(T, const N: usize) pair (with lifetimes erased). The static’s value is
zero-initialized.
This is the const-keyed alternative to Namespace::generic_static: the same
T with a different N is a different address.
use static_generics::{define_namespace, namespace::Namespace};
use core::sync::atomic::{AtomicU64, Ordering};
define_namespace!(Counters);
Counters::generic_static_const::<AtomicU64, 0>().store(1, Ordering::Relaxed);
Counters::generic_static_const::<AtomicU64, 1>().store(2, Ordering::Relaxed);
assert_eq!(Counters::generic_static_const::<AtomicU64, 0>().load(Ordering::Relaxed), 1);
assert_eq!(Counters::generic_static_const::<AtomicU64, 1>().load(Ordering::Relaxed), 2);Sourceunsafe fn generic_static_mut<T>() -> *mut Twhere
T: 'static + Zeroable,
unsafe fn generic_static_mut<T>() -> *mut Twhere
T: 'static + Zeroable,
Raw (*mut T) view of the same slot as Namespace::generic_static.
Equivalent of static mut for static generics.
§Safety
The pointer itself is always valid (non-null, aligned, valid for T,
stable per (Self, T), never dropped). The caller must follow static mut
safety rules while the pointer (or anything derived
from it) is used:
- no other live reference — shared or mutable — to the same slot aliases the access.
- no data races.
- the zero-initialized contents are a valid
T(bytemuck::Zeroable), and the slot is never dropped — do not store types needingDrop(useoncefor those).
use static_generics::{define_namespace, namespace::Namespace};
define_namespace!(Counters);
let ptr = unsafe { Counters::generic_static_mut::<u64>() };
assert!(!ptr.is_null());
unsafe { ptr.write(7) };
assert_eq!(unsafe { ptr.read() }, 7);
// Same slot as the shared view.
assert!(core::ptr::eq(ptr as *const u64, Counters::generic_static::<u64>()));Sourceunsafe fn generic_static_const_mut<T, const N: usize>() -> *mut Twhere
T: 'static + Zeroable,
unsafe fn generic_static_const_mut<T, const N: usize>() -> *mut Twhere
T: 'static + Zeroable,
Raw (*mut T) view of the same slot as
Namespace::generic_static_const: the same T with a different N
is a different address.
§Safety
Same contract as Namespace::generic_static_mut.
use static_generics::{define_namespace, namespace::Namespace};
define_namespace!(Counters);
let a = unsafe { Counters::generic_static_const_mut::<u64, 0>() };
let b = unsafe { Counters::generic_static_const_mut::<u64, 1>() };
assert!(!core::ptr::eq(a, b));
unsafe { a.write(1) };
unsafe { b.write(2) };
assert_eq!(unsafe { a.read() }, 1);Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".