Expand description
Create a trusted carrier with a new lifetime that is guaranteed to be
unique among other trusted carriers. When you call make_guard! to make a
unique lifetime, the macro creates a Guard to hold it. This guard can be
converted into an Id, which can be stored in structures to uniquely
“brand” them. A different invocation of the macro will produce a new
lifetime that cannot be unified. The only way to construct these types is
with make_guard! or unsafe code.
use generativity::{Id, make_guard};
struct Struct<'id>(Id<'id>);
make_guard!(a);
Struct(a.into());This is the concept of “generative” lifetime brands. Guard and Id are
invariant over
their lifetime parameter, meaning that it is never valid to substitute or
otherwise coerce Id<'a> into Id<'b>, for any concrete 'a or 'b,
including the 'static lifetime.
Any invariant lifetime can be “trusted” to carry a brand, so long as they
are known to be restricted to carrying a brand, and haven’t been derived
from some untrusted lifetime (or are completely unbound). When using this
library, it is recommended to always use Id<'id> to carry the brand, as
this reduces the risk of accidentally trusting an untrusted lifetime.
Importantly, non-invariant lifetimes cannot be trusted, as the variance
allows lifetimes to be contracted to match and copy the brand lifetime.
To achieve lifetime invariance without Id, there are two standard ways:
PhantomData<&'a mut &'a ()> and PhantomData<fn(&'a ()) -> &'a ()>. The
former works because &mut T is invariant over T, and the latter works
because fn(T) is contravariant over T and fn() -> T is covariant
over T, which combines to invariance. Both are equivalent in this case
with T = (), but fn(T) -> T is generally preferred if the only purpose
is to indicate invariance, as function pointers are a perfect cover for all
auto traits (e.g. Send, Sync, Unpin, UnwindSafe, etc.) and thus
only indicates invariance, whereas &mut T can carry further implication
of “by example” use of PhantomData.
Macros§
- make_
guard - Create a
Guardwith a unique invariant lifetime (with respect to other trusted/invariant lifetime brands).