Lift enum variants to the type-level by simply adding the attribute tylift
.
This comes in handy for type-level programming. The crate you are looking at is
brand new and far from polished!
The attribute promotes variants to their own types which will not be namespaced
by current design. The enum type becomes a kind emulated by a trait. In the
process, the original type gets replaced. In Rust, the syntax of trait bounds (:
) beautifully
mirror the syntax of type annotations. Thus, the snippet B: Bool
can also be
read as "type parameter B
of kind Bool
".
As of right now, there is no automated way to reify the lifted variants. Variants can hold unnamed fields of types of given kind. Lifted enum types cannot be generic over kinds. The promoted variants inherit the visibility of the lifted enum. Traits representing kinds are sealed, which means nobody is able to add new types to the kind.
Attributes applied to the item itself (placed below tylift
), its variants and fields of its
variants will not be translated and have no effect. Explicit discriminants are ignored, too.
```rust use tylift::tylift; use std::marker::PhantomData;
pub enum Mode { Safe, Fast, }
pub struct Text
impl
impl Text
impl Text
fn main() {
let safe = Text::
Works with rustc
version 1.32 (stable) or above, Rust 2018 edition. Add these lines to your Cargo.toml
:
toml
[dependencies]
tylift = "0.3.0"
Code before the macro expansion:
```rust use tylift::tylift;
pub enum Bool { False, True, }
pub(crate) enum Nat { Zero, Succ(Nat), }
enum BinaryTree { Leaf, Branch(BinaryTree, Nat, BinaryTree), } ```
And after:
```rust use tylift::tylift;
pub use tyliftenumBool::; mod __tylift_enum_Bool { use super::; pub trait Bool: _sealed::Sealed {} pub struct False(::std::marker::PhantomData<()>); impl Bool for False {} pub struct True(::std::marker::PhantomData<()>); impl Bool for True {} mod _sealed { use super::*; pub trait _Sealed {} impl _Sealed for False {} impl __Sealed for True {} } }
pub(crate) use tyliftenumNat::; mod __tylift_enum_Nat { use super::; pub trait Nat: _sealed::Sealed {} pub struct Zero(::std::marker::PhantomData<()>); impl Nat for Zero {} pub struct Succ<__T0: Nat>(::std::marker::PhantomData<(T0)>); impl<__T0: Nat> Nat for Succ<__T0> {} mod _sealed { use super::*; pub trait _Sealed {} impl _Sealed for Zero {} impl<__T0: Nat> __Sealed for Succ<__T0> {} } }
use tyliftenumBinaryTree::; mod __tylift_enum_BinaryTree { use super::; pub trait BinaryTree: _sealed::Sealed {} pub struct Leaf(::std::marker::PhantomData<()>); impl BinaryTree for Leaf {} pub struct Branch<__T0: BinaryTree, __T1: Nat, __T2: BinaryTree>( ::std::marker::PhantomData<(T0, _T1, _T2)>, ); impl<__T0: BinaryTree, __T1: Nat, __T2: BinaryTree> BinaryTree for Branch<__T0, __T1, __T2> {} mod _sealed { use super::*; pub trait _Sealed {} impl _Sealed for Leaf {} impl<__T0: BinaryTree, __T1: Nat, __T2: BinaryTree> __Sealed for Branch<__T0, __T1, __T2> {} } } ```