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.

Macros

Create a Guard with a unique invariant lifetime (with respect to other trusted/invariant lifetime brands).

Structs

An invariant lifetime phantomdata that is guaranteed to be unique with respect to other invariant lifetimes.

A phantomdata-like type taking a single invariant lifetime.