Diffstat (limited to 'src/hkt.rs')
| -rw-r--r-- | src/hkt.rs | 430 |
1 files changed, 60 insertions, 370 deletions
@@ -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 { |