Quoting the [Rust Reference](https://doc.rust-lang.org/reference/items/static-items.html#statics--generics):
> A static item defined in a generic scope (for example in a blanket or default implementation)
> will result in exactly one static item being defined, as if the static definition was pulled
> out of the current scope into the module. There will not be one item per monomorphization.
One way to work around this is to use a `HashMap<TypeId,Data>`. This is a simple & usually the best solution.
If lookup performance is important, you can skip hashing the `TypeId` for minor gains as it
[already contains](https://github.com/rust-lang/rust/blob/eeff92ad32c2627876112ccfe812e19d38494087/library/core/src/any.rs#L645)
a good-quality hash.
This crate aims to further fully remove the lookup by allocating the storage using inline
assembly.
# ⚠ Caveats ⚠
THIS PLACE IS NOT A PLACE OF HONOR.
NO HIGHLY ESTEEMED DEED IS COMMEMORATED HERE.
NOTHING VALUED IS HERE.
WHAT IS HERE WAS DANGEROUS AND REPULSIVE TO US.
THE DANGER IS IN A PARTICULAR LOCATION.
THE DANGER IS STILL PRESENT, IN YOUR TIME, AS IT WAS IN OURS.
Different compilation units may access different instances of the data
(at least without `share-generics).
Supported targets are **x86-64**, **aarch64**, **arm** and **x86**;
on other targets, this crate falls back to a hashmap.
The linker may not use a smaller align for the `data` section than that of
the types used with `global`.
# Usage
The `generic_static` macro defines a static variable inside of a function,
with every instantiation of the function having it's own instance of the static:
```rust
fn get_and_inc<T>() -> i32 {
generic_static!{
static COUNTER: &AtomicI32 = &AtomicI32::new(1);
}
COUNTER.fetch_add(1, Ordering::Relaxed)
}
assert_eq!(get_and_inc::<bool>(), 1);
assert_eq!(get_and_inc::<bool>(), 2);
assert_eq!(get_and_inc::<String>(), 1);
assert_eq!(get_and_inc::<bool>(), 3);
```
Underlying this is the `global::<T>()` function,
which allocates a shared global static for each type it's used with.