Diffstat (limited to 'src/hkt.rs')
-rw-r--r--src/hkt.rs430
1 files changed, 60 insertions, 370 deletions
diff --git a/src/hkt.rs b/src/hkt.rs
index 8cc3952..55e9856 100644
--- a/src/hkt.rs
+++ b/src/hkt.rs
@@ -19,12 +19,14 @@
//! Bounding a generic by a higher-ranked trait simultaniously allows any higher-ranked type with
//! a "true" type with the required traits and any lifetime to be given to that "true" type.
+use core::marker::PhantomData;
+
#[derive(Debug, Default, Copy, Clone)]
#[repr(transparent)]
pub struct Invariant<'a>(PhantomData<fn(&'a ()) -> &'a ()>);
#[repr(transparent)]
-pub struct Marker<T>(PhantomData<fn() -> T>);
+pub struct Marker<T: ?Sized>(PhantomData<fn() -> *const T>);
impl<T> Copy for Marker<T> {}
impl<T> Clone for Marker<T> {
@@ -47,412 +49,100 @@ impl<T> Default for Marker<T> {
#[doc(hidden)]
#[macro_export]
-macro_rules! bijective_higher_ranked_trait {
+macro_rules! higher_ranked_trait {
{
- $(#[$($meta:tt)*])*
- $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:vis type class $name:ident$([$($generic:tt)*])? for<$($lt:lifetime),+> {
+ type Bound = $bound:ty;
+
+ type T: {$($lower:tt)*} $(where {$($lower_where:tt)*})?;
+
+ type HigherRanked: {$($higher:tt)*} $(where {$($higher_where:tt)*})?;
+ }
} => {
- $(#[$($meta)*])*
$vis mod $name {
- #![allow(unused, non_snake_case)]
-
- use super::*;
+ #![allow(non_snake_case)]
- /// Trait for lowering a higher ranked type to a lower type.
- ///
- /// Do not use this trait directly instead use the [`MemberType`] trait and [`T`]
- /// type alias.
- ///
- /// This acts to inject a lifetime into the higher ranked type to make it concrete.
- pub trait LowerForLt<
- $lt,
- $($lifetimes: $lt,)*
- B: $lt,
- $($generic: $lt),*
- >
- $(: $($self_provides)*)?
+ pub trait LowerForLt<$($lt,)+ $($($generic)*,)? B>
where
- $($($bound)*)?
- $($($for_bound)*)?
+ $($($lower_where)*)?
+ $($($higher_where)*)?
{
- /// The lower type for this higher ranked type.
- ///
- /// The lower type must live for a minimum of the injected lifetime.
- ///
- /// Note this type must be raisable back to the same higher ranked type to make
- /// this a bijective mapping.
- type T: ?Sized + RaiseForLt<
- $lt,
- $($lifetimes,)*
- &$lt ($(&$lifetimes (),)* $(*const $generic,)*),
- $($generic,)*
- HigherRanked = Self
- > $(+ $($provides)+)? + $lt;
+ type T: RaiseForLt<$($lt,)+ $($($generic)*,)? B, HigherRanked = Self> + ?Sized + $($lower)*;
}
- /// Trait for raising a lower type to it's higher ranked form.
- ///
- /// Do not use this trait directly instead use the [`LowerType`] trait and [`HigherRanked`]
- /// type alias.
- ///
- /// this acts to remove a lifetime from the lower type.
- pub trait RaiseForLt<$lt, $($lifetimes: $lt,)* B: $lt, $($generic: $lt),*>
+ pub trait RaiseForLt<$($lt,)+ $($($generic)*,)? B>
where
- $($($bound)*)?
- $($($for_bound)*)?
+ $($($lower_where)*)?
+ $($($higher_where)*)?
{
- /// The higher ranked type for this lower type.
- ///
- /// Note this type must be lowerable back to the same lower type to make
- /// this a bijective mapping.
- type HigherRanked: ?Sized + LowerForLt<
- $lt,
- $($lifetimes,)*
- &$lt ($(&$lifetimes (),)* $(*const $generic,)*),
- $($generic,)*
- T = Self
- > $(+ $lifetimes)*;
+ type HigherRanked: LowerForLt<$($lt,)+ $($($generic)*,)? B, T = Self> + ?Sized + $($higher)*;
}
- /// Trait for higher ranked types of this form.
- ///
- /// A higher ranked type can have a lifetime injected to form a lower type.
- /// To perform this operation use the [`T`] type alias.
- ///
- /// This is basically a trait alias for the bound `for<'a> LowerForLt<'a, ...>`.
- pub trait MemberType<$($lifetimes,)* $($generic),*>:
- for<$lt> LowerForLt<
- $lt,
- $($lifetimes,)*
- // Use a implied bound to make sure the lifetime from the for syntax is
- // correctly bounded.
- &$lt ($(&$lifetimes (),)* $(*const $generic,)*),
- $($generic),*
- >
- where
- $($($bound)*)?
+ pub type Bound<$($lt,)+ $($($generic)*)?> = $bound;
+
+ pub trait MemberType$(<$($generic)*>)?:
+ for<$($lt,)+> LowerForLt<$($lt,)+ $($($generic)*,)? Bound<$($lt,)+ $($($generic)*)?>> + $($higher)*
+ $(where $($higher_where)*)?
{}
- // Impl the higher ranked trait for all higher ranked types with the ability to lower.
- impl<
- $($lifetimes,)*
- __: ?Sized,
- $($generic),*
- > MemberType<$($lifetimes,)* $($generic),*> for __
+ impl<$($($generic)*,)? __: ?Sized> MemberType$(<$($generic)*>)? for __
where
- __: for<$lt> LowerForLt<
- $lt,
- $($lifetimes,)*
- &$lt ($(&$lifetimes (),)* $(*const $generic,)*),
- $($generic),*
- >,
- $($($bound)*)?
+ __: for<$($lt,)+> LowerForLt<$($lt,)+ $($($generic)*,)? Bound<$($lt,)+ $($($generic)*)?>> + $($higher)?
+ $($($higher_where)*)?
{}
- /// Inject a lifetime into a higher ranked type to form its lower type.
- pub type T<$lt, $($lifetimes,)* __, $($generic),*> =
- <__ as LowerForLt<
- $lt,
- $($lifetimes,)*
- &$lt ($(&$lifetimes (),)* $(*const $generic,)*),
- $($generic),*
- >>::T;
-
- /// Trait for lower types with a higher ranked form.
- ///
- /// A lower type can have a lifetime removed to form a higher ranked type.
- /// To perform this operation use the [`HigherRanked`] type alias.
- ///
- /// This is basically a trait alias for the bound `RaiseForLt<'a, ...>`.
- pub trait LowerType<
- $lt,
- $($lifetimes: $lt,)*
- $($generic: $lt),*
- >: RaiseForLt<
- $lt,
- $($lifetimes,)*
- &$lt ($(&$lifetimes (),)* $(*const $generic,)*),
- $($generic),*
- > $(+ $($provides)+)?
+ pub trait LowerType<$($lt,)+ $($($generic)*)?>:
+ RaiseForLt<$($lt,)+ $($($generic)*,)? Bound<$($lt,)+ $($($generic)*)?>> + $($lower)*
where
- $($($bound)*)?
+ $($($lower_where)*)?
+ $($($higher_where)*)?
{}
- // Impl the lower type trait for all lower types with the ability to raise.
- impl<
- $lt,
- $($lifetimes: $lt,)*
- __: ?Sized,
- $($generic: $lt),*
- > LowerType<$lt, $($lifetimes,)* $($generic),*> for __
+ impl<$($lt,)+ $($($generic)*,)? __: ?Sized> LowerType<$($lt,)+ $($($generic)*)?> for __
where
- __: RaiseForLt<
- $lt,
- $($lifetimes,)*
- &$lt ($(&$lifetimes (),)* $(*const $generic,)*),
- $($generic),*
- > $(+ $($provides)+)?,
- $($($bound)*)?
+ __: RaiseForLt<$($lt,)+ $($($generic)*,)? Bound<$($lt,)+ $($($generic)*)?>> + $($lower)*,
+ $($($lower_where)*)?
+ $($($higher_where)*)?
{}
- /// Remove a lifetime into a lower type to form its higher ranked type.
- pub type HigherRanked<$lt, $($lifetimes,)* __, $($generic),*> =
- <__ as RaiseForLt<
- $lt,
- $($lifetimes,)*
- &$lt ($(&$lifetimes (),)* $(*const $generic,)*),
- $($generic),*
- >>::HigherRanked;
+ pub type T<$($lt,)+ $($($generic)*,)? __> =
+ <__ as LowerForLt<$($lt,)+ $($($generic)*,)? Bound<$($lt,)+ $($($generic)*)?>>>::T;
+
+ pub type HigherRanked<$($lt,)+ $($($generic)*,)? __> =
+ <__ as RaiseForLt<$($lt,)+ $($($generic)*,)? Bound<$($lt,)+ $($($generic)*)?>>>::HigherRanked;
}
- };
+ }
}
+pub use higher_ranked_trait;
-use core::marker::PhantomData;
-
-#[doc(inline)]
-pub use bijective_higher_ranked_trait;
-
-/// Generate a higher-ranked type.
#[doc(hidden)]
#[macro_export]
-macro_rules! bijective_higher_ranked_type {
+macro_rules! higher_ranked_type {
{
- $(for[$($extra_lt:lifetime)*])? use $name:ident[
- $($ctx:lifetime),*
- ][
- $($generic:ident),*
- ]$([
- $($forwarding_generic:ident[$($forward_lt:lifetime),*][$($forward_generic:ident),*]),*
- ])?: $type_class:ident[$($type_class_lifetime:lifetime)*][$($type_class_generic:ident)*]
- for<$lt:lifetime>
- ($for_lt_type:ty)
- ($higher_ranked_type:ty)
- $(where {$($bound:tt)*})?
+ impl $higher_trait:ident {
+ impl$([$($lower_generic:tt)*])? type T[$($lower_forward:tt)*] for $lower_higher:ty =
+ $lower:ty
+ $(where {$($lower_where:tt)*})?;
+
+ impl$([$($higher_generic:tt)*])? type HigherRanked[$($higher_forward:tt)*] for $higher_lower:ty =
+ $higher:ty
+ $(where {$($higher_where:tt)*})?;
+ }
} => {
- impl<
- $lt,
- $($($extra_lt,)*)?
- $($ctx,)*
- $($generic,)*
- $($($forwarding_generic),*)?
- > $type_class::LowerForLt<
- $lt,
- $($type_class_lifetime,)*
- &$lt (
- $(&$type_class_lifetime (),)*
- $(*const $type_class_generic,)*
- ),
- $($type_class_generic),*
- > for $name<
- $($ctx,)*
- $($generic,)*
- $($($forwarding_generic),*)?
- >
- where
- $($(
- $forwarding_generic: $type_class::LowerForLt<
- $lt,
- $($forward_lt,)*
- &$lt (
- $(&$forward_lt (),)*
- $(*const $forward_generic,)*
- ),
- $($forward_generic,)*
- >,
- )*)?
- $($($bound)*)?
+ impl$(<$($lower_generic)*>)* $higher_trait::LowerForLt<$($lower_forward)*, $higher_trait::Bound<$($lower_forward)*>> for $lower_higher
+ $(where $($lower_where)*)?
{
- type T = $for_lt_type;
+ type T = $lower;
}
- impl<
- $lt,
- $($($extra_lt,)*)?
- $($ctx,)*
- $($generic,)*
- $($($forwarding_generic),*)?
- > $type_class::RaiseForLt<
- $lt,
- $($type_class_lifetime,)*
- &$lt (
- $(&$type_class_lifetime (),)*
- $(*const $type_class_generic,)*
- ),
- $($type_class_generic),*
- > for $higher_ranked_type
- where
- $($(
- $forwarding_generic: $type_class::RaiseForLt<
- $lt,
- $($forward_lt,)*
- &$lt (
- $(&$forward_lt (),)*
- $(*const $forward_generic,)*
- ),
- $($forward_generic,)*
- >,
- )*)?
- $($($bound)*)?
+ impl$(<$($higher_generic)*>)* $higher_trait::RaiseForLt<$($higher_forward)*, $higher_trait::Bound<$($higher_forward)*>> for $higher_lower
+ $(where $($higher_where)*)?
{
- type HigherRanked = $name<
- $($ctx,)*
- $($generic,)*
- $($(
- <$forwarding_generic as $type_class::RaiseForLt<
- $lt,
- $($forward_lt,)*
- &$lt (
- $(&$forward_lt (),)*
- $(*const $forward_generic,)*
- ),
- $($forward_generic,)*
- >>::HigherRanked
- ),*)?
- >;
- }
- };
- {
- $(#[$($meta:tt)*])*
- $vis:vis $(for[$($extra_lt:lifetime)*])? type $name:ident[
- $($ctx:lifetime),*
- ][
- $($generic:ident),*
- ]$([
- $($forwarding_generic:ident[$($forward_lt:lifetime),*][$($forward_generic:ident),*]),*
- ])?: $type_class:ident[$($type_class_lifetime:lifetime)*][$($type_class_generic:ident)*]
- for<$lt:lifetime>
- ($for_lt_type:ty)
- ($higher_ranked_type:ty)
- $(where {$($bound:tt)*})?
- } => {
- $(#[$($meta)*])*
- $vis struct $name<
- $($ctx,)*
- $($generic: ?Sized,)*
- $($($forwarding_generic: ?Sized),*)?
- >(
- core::marker::PhantomData<fn() -> (
- $(&$ctx (),)*
- $(*const $generic,)*
- $($(*const $forwarding_generic,)*)?
- )>
- );
-
- $crate::hkt::bijective_higher_ranked_type! {
- $(for[$($extra_lt)*])? use $name[
- $($ctx),*
- ][
- $($generic),*
- ]$([
- $($forwarding_generic[$($forward_lt),*][$($forward_generic),*]),*
- ])?: $type_class[$($type_class_lifetime)*][$($type_class_generic)*]
- for<$lt>
- ($for_lt_type)
- ($higher_ranked_type)
- $(where {$($bound)*})?
- }
- };
- {
- $vis:vis $(for[$($extra_lt:lifetime)*])? type [
- $($ctx:lifetime),*
- ][
- $($generic:ident),*
- ]$([
- $($forwarding_generic:ident[$($forward_lt:lifetime),*][$($forward_generic:ident),*]),*
- ])?: $type_class:ident[$($type_class_lifetime:lifetime)*][$($type_class_generic:ident)*]
- for<$lt:lifetime>
- ($for_lt_type:ty)
- $(($higher_ranked_type:ty))?
- $(where {$($bound:tt)*})?
- } => {
- const _: () = {
- $crate::hkt::bijective_higher_ranked_type! {
- $vis $(for[$($extra_lt)*])? type __HigherRanked[
- $($ctx),*
- ][
- $($generic),*
- ]$([
- $($forwarding_generic[$($forward_lt),*][$($forward_generic),*]),*
- ])?: $type_class[$($type_class_lifetime)*][$($type_class_generic)*]
- for<$lt>
- ($for_lt_type)
- $(($higher_ranked_type))?
- $(where {$($bound)*})?
- }
- };
- };
- {
- $(#[$($meta:tt)*])*
- $vis:vis $(for[$($extra_lt:lifetime)*])? type $name:ident[
- $($ctx:lifetime),*
- ][
- $($generic:ident),*
- ]$([
- $($forwarding_generic:ident[$($forward_lt:lifetime),*][$($forward_generic:ident),*]),*
- ])?: $type_class:ident[$($type_class_lifetime:lifetime)*][$($type_class_generic:ident)*]
- for<$lt:lifetime>
- ($for_lt_type:ty)
- $(where {$($bound:tt)*})?
- } => {
- $crate::hkt::bijective_higher_ranked_type! {
- $(#[$($meta)*])*
- $vis $(for[$($extra_lt)*])? type $name[
- $($ctx),*
- ][
- $($generic),*
- ]$([
- $($forwarding_generic[$($forward_lt),*][$($forward_generic),*]),*
- ])?: $type_class[$($type_class_lifetime)*][$($type_class_generic)*]
- for<$lt>
- ($for_lt_type)
- ($for_lt_type)
- $(where {$($bound)*})?
- }
- };
- {
- $(for[$($extra_lt:lifetime)*])? use $name:ident[
- $($ctx:lifetime),*
- ][
- $($generic:ident),*
- ]$([
- $($forwarding_generic:ident[$($forward_lt:lifetime),*][$($forward_generic:ident),*]),*
- ])?: $type_class:ident[$($type_class_lifetime:lifetime)*][$($type_class_generic:ident)*]
- for<$lt:lifetime>
- ($for_lt_type:ty)
- $(where {$($bound:tt)*})?
- } => {
- $crate::hkt::bijective_higher_ranked_type! {
- $(for[$($extra_lt)*])? use $name[
- $($ctx),*
- ][
- $($generic),*
- ]$([
- $($forwarding_generic[$($forward_lt),*][$($forward_generic),*]),*
- ])?: $type_class[$($type_class_lifetime)*][$($type_class_generic)*]
- for<$lt>
- ($for_lt_type)
- ($for_lt_type)
- $(where {$($bound)*})?
+ type HigherRanked = $higher;
}
}
}
-
-#[doc(inline)]
-pub use bijective_higher_ranked_type;
-
-bijective_higher_ranked_trait! {
- pub type class AnySizedSend[][]: [for<'lt> Send + Sized]
-}
+pub use higher_ranked_type;
// #[cfg(test)]
// mod test {