Ty Tag
TypeId for lifetime containing types via type tags.
Not all types in Rust are 'static. Meaning they can't be used with [core::any::TypeId].
However, it is often useful to be able to name a lifetime containing type via a 'static
type. Most implementations go about this by using the same type with all the lifetimes
replaced by 'static. So for example &'a [u8] would be named by &'static [u8]. These
implementations suffer from some limitations. One being that they are usually limited to
a single lifetime 'a.
This crate takes a different approach to solve this issue. We introduce the idea of tags.
A tag is an arbitrary type with an associated lifetime containing type. So for the &'a [u8]
example we would have a struct SliceU8; with the &'a [u8] as an associated type.
You may notice that by itself this has an issue. We somehow need to get a 'a to actually
write the &'a [u8] associated type. The lifetime can't live on the SliceU8 because we
need that to be 'static.
We solve this by injecting the lifetime 'a in an operation called reification. This operation
combines a tag type and some number of lifetimes into the lifetime containing type. So
SliceU8 + 'a reifies to &'a [u8]. Combining this with a way to get a tag type from a
lifetime containing type, we gain the ability to go full circle from a lifetime containing type
to a 'static type back to the lifetime containing type.
In this crate a tag type is defined to be a type that implements both [Tag] and [WithLt].
These types automatically gain the [Reify] operation for constructing the lifetime containing
type they name. Any type can have a tag associated with it via the [Tagged]
trait. Note, [Tagged] does not require the associated tag to name the Self type. This
is a useful property but may be unintuitive.
use ;
// Check that the tag of &str is a 'static type.
;
// Introduce an arbitrary lifetime 'a.
with_lt;
, U>
Another concept this crate introduces is that of a tag group. Because of Rust's coherence rules
we are limited in our ability to implement [Tagged] for types outside a user's crate. To work
around this we use tag groups like [DefaultGroup] to allow a user to bypass the coherence
rules by naming a type they control. This functionality is not used within this crate, but
is designed to improve the ergonomics of other crates.
Crate features
-
macros(enabled by default) — Includes thetagmacro for creating tags from type aliases. -
core(enabled by default) — Adds tags for commonly used types incore. -
alloc— Adds tags for commonly used types inalloc. -
std— Adds tags for commonly used types instd. -
unsafe— Allowsunsafecode.Only some convenience methods of
Labelneed this.
no_std Support
This crate is #![no_std] by default, it can be used anywhere Rust can.
Minimum Supported Rust Version
Requires Rust 1.83.0.
This crate follows the "Latest stable Rust" policy. The listed MSRV won't be changed unless needed. However, updating the MSRV anywhere up to the latest stable at time of release is allowed.
Contributing
Contributions in any form (issues, pull requests, etc.) to this project must adhere to Rust's Code of Conduct.
Unless you explicitly state otherwise, any contribution intentionally submitted for
inclusion in ty-tag by you shall be licensed as below, without any
additional terms or conditions.
License
This project is licensed under either of
at your option.