Skip to main content

Namespace

Trait Namespace 

Source
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§

Source

fn generic_static<T>() -> &'static T
where 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!.

Source

fn generic_static_const<T, const N: usize>() -> &'static T
where 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);
Source

unsafe fn generic_static_mut<T>() -> *mut T
where 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 needing Drop (use once for 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>()));
Source

unsafe fn generic_static_const_mut<T, const N: usize>() -> *mut T
where 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".

Implementors§