Diffstat (limited to 'src/hkt.rs')
| -rw-r--r-- | src/hkt.rs | 133 |
1 files changed, 132 insertions, 1 deletions
@@ -49,7 +49,7 @@ macro_rules! higher_ranked_trait { where $($($bound)*)? $($($for_bound)*)? { - type T$(: $($provides)+)?; + type T: $lt $(+ $($provides)+)?; } pub trait Trait<$ctx $(, $($generic)*)?>: for<$lt> ForLt<$lt, $ctx, $crate::hkt::Bound<$lt, $ctx $(, $($generic)*)?> $(, $($generic)*)?> @@ -68,6 +68,8 @@ macro_rules! higher_ranked_trait { }; } +use core::marker::PhantomData; + #[doc(inline)] pub use higher_ranked_trait; @@ -94,6 +96,135 @@ macro_rules! higher_ranked_type { #[doc(inline)] pub use higher_ranked_type; +#[doc(hidden)] +#[macro_export] +macro_rules! bijective_higher_ranked_trait { + { + $vis:vis type class $name:ident[ + $($lifetimes:lifetime),* + ][ + $($generic:ident),* + ]: $({$($self_provides:tt)*})? [for<$lt:lifetime> $($($provides:tt)+)?] + $(where { + $($bound:tt)* + })? + $(for where { + $($for_bound:tt)* + })? + } => { + $vis mod $name { + #![allow(unused, non_snake_case)] + + use super::*; + + pub trait LowerForLt<$lt, $($lifetimes,)* B, $($generic),*> $(: $($self_provides)*)? + where $($($bound)*)? $($($for_bound)*)? + + { + type T: ?Sized + RaiseForLt<$lt, $($lifetimes,)* B, $($generic),*> $(+ $($provides)+)? + $lt; + } + + pub trait RaiseForLt<$lt, $($lifetimes,)* B, $($generic),*> + where $($($bound)*)? $($($for_bound)*)? + + { + type HigherRanked: ?Sized + LowerForLt<$lt, $($lifetimes,)* B, $($generic),*>; + } + + pub trait Trait<$($lifetimes,)* $($generic),*>: + for<$lt> LowerForLt<$lt, $($lifetimes,)* &$lt ($(&$lifetimes (),)* $($generic),*), $($generic),*> + where + $($($bound)*)? + {} + + impl<$($lifetimes,)* __: ?Sized, $($generic),*> Trait<$($lifetimes,)* $($generic),*> for __ + where + __: for<$lt> LowerForLt<$lt, $($lifetimes,)* &$lt ($(&$lifetimes (),)* $($generic),*), $($generic),*>, + $($($bound)*)? + {} + + pub type T<$lt, $($lifetimes,)* __, $($generic),*> = <__ as LowerForLt<$lt, $($lifetimes,)* &$lt ($(&$lifetimes (),)* $($generic),*), $($generic),*>>::T; + + pub trait Member<$lt, $($lifetimes,)* $($generic),*>: RaiseForLt<$lt, $($lifetimes,)* &$lt ($(&$lifetimes (),)* $($generic),*), $($generic),*> $(+ $($provides)+)? + where + ($(&$lifetimes (),)*): $lt, + $($($bound)*)? + {} + + impl<$lt, $($lifetimes,)* __: ?Sized, $($generic),*> Member<$lt, $($lifetimes,)* $($generic),*> for __ + where + __: RaiseForLt<$lt, $($lifetimes,)* &$lt ($(&$lifetimes (),)* $($generic),*), $($generic),*> $(+ $($provides)+)?, + ($(&$lifetimes (),)*): $lt, + $($($bound)*)? + {} + + pub type HigherRanked<$lt, $($lifetimes,)* __, $($generic),*> = <__ as RaiseForLt<$lt, $($lifetimes,)* &$lt ($(&$lifetimes (),)* $($generic),*), $($generic),*>>::HigherRanked; + } + }; +} + +#[doc(inline)] +pub use bijective_higher_ranked_trait; + +/// Generate a higher-ranked type. +#[doc(hidden)] +#[macro_export] +macro_rules! bijective_higher_ranked_type { + { + $vis:vis type $name:ident[ + $($ctx:lifetime),* + ][ + $($generic:ident),* + ]: ($($type_class:tt)*)[$($type_class_lifetime:lifetime)*][$($type_class_generic:ident)*] + $(where {$($bound:tt)*})? + = for<$lt:lifetime> $for_lt_type:ty + $(where {$($higher_bound:tt)*})? + } => { + $vis struct $name<$($type_class_lifetime,)* $($generic),*>(core::marker::PhantomData<fn() -> ($(&$type_class_lifetime (),)* $($generic,)*)>); + + impl<$lt, $($ctx,)* $($generic),*> $($type_class)*::LowerForLt<$lt, $($type_class_lifetime,)* &$lt ($(&$type_class_lifetime (),)* $($generic,)*), $($type_class_generic),*> for $name<$($type_class_lifetime,)* $($generic),*> + where $($($bound)*)? $($($higher_bound)*)? + { + type T = $for_lt_type; + } + + impl<$lt, $($ctx,)* $($generic),*> $($type_class)*::RaiseForLt<$lt, $($type_class_lifetime,)* &$lt ($(&$type_class_lifetime (),)* $($generic,)*), $($type_class_generic),*> for $for_lt_type + where $($($bound)*)? $($($higher_bound)*)? + { + type HigherRanked = $name<$($type_class_lifetime,)* $($generic),*>; + } + }; + { + $vis:vis type [ + $($ctx:lifetime),* + ][ + $($generic:ident),* + ]: ($($type_class:tt)*)[$($type_class_lifetime:lifetime)*][$($type_class_generic:ident)*] + $(where {$($bound:tt)*})? + = for<$lt:lifetime> $for_lt_type:ty + $(where {$($higher_bound:tt)*})? + } => { + const _: () = { + $vis struct __Name<$($type_class_lifetime,)* $($generic: ?Sized),*>(core::marker::PhantomData<fn() -> ($(&$type_class_lifetime (),)* $(*const $generic),*)>); + + impl<$lt, $($ctx,)* $($generic),*> $($type_class)*::LowerForLt<$lt, $($type_class_lifetime,)* &$lt ($(&$type_class_lifetime (),)* $(*const $generic),*), $($type_class_generic),*> for __Name<$($type_class_lifetime,)* $($generic),*> + where $($($bound)*)? $($($higher_bound)*)? + { + type T = $for_lt_type; + } + + impl<$lt, $($ctx,)* $($generic),*> $($type_class)*::RaiseForLt<$lt, $($type_class_lifetime,)* &$lt ($(&$type_class_lifetime (),)* $(*const $generic),*), $($type_class_generic),*> for $for_lt_type + where $($($bound)*)? $($($higher_bound)*)? + { + type HigherRanked = __Name<$($type_class_lifetime,)* $($generic),*>; + } + }; + } +} + +#[doc(inline)] +pub use bijective_higher_ranked_type; + higher_ranked_trait! { pub type class AnySend['ctx]: [for<'lt> Send] } |