Diffstat (limited to 'src/hkt.rs')
-rw-r--r--src/hkt.rs133
1 files changed, 132 insertions, 1 deletions
diff --git a/src/hkt.rs b/src/hkt.rs
index 466d358..3f2c52d 100644
--- a/src/hkt.rs
+++ b/src/hkt.rs
@@ -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]
}