Diffstat (limited to 'src/hkt.rs')
-rw-r--r--src/hkt.rs97
1 files changed, 78 insertions, 19 deletions
diff --git a/src/hkt.rs b/src/hkt.rs
index f51ebed..8cc3952 100644
--- a/src/hkt.rs
+++ b/src/hkt.rs
@@ -10,12 +10,12 @@
//! lifetime. Sadly, Rust only allows `for<'a>` in trait objects. However, trait object provide
//! enough for us to implement arbitrary hifher-ranked types with some extra effort.
//!
-//! In this module the [`higher_ranked_type!`] macro generates a type that needs a lifetime to
+//! In this module the [`bijective_higher_ranked_type!`] macro generates a type that needs a lifetime to
//! be complete. Before a higher-ranked type can be generated we need a higher-ranked trait to
//! describe what behavior the resulting "true" type will have.
//!
-//! The [`higher_ranked_trait!`] macro cgenerates a trait that can be used with
-//! [`higher_ranked_type!`] and as a bound by code wanting to accept a higher ranked type.
+//! The [`bijective_higher_ranked_trait!`] macro cgenerates a trait that can be used with
+//! [`bijective_higher_ranked_type!`] and as a bound by code wanting to accept a higher ranked type.
//! 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.
@@ -74,7 +74,13 @@ macro_rules! bijective_higher_ranked_trait {
/// 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,
+ $($lifetimes: $lt,)*
+ B: $lt,
+ $($generic: $lt),*
+ >
+ $(: $($self_provides)*)?
where
$($($bound)*)?
$($($for_bound)*)?
@@ -221,8 +227,7 @@ pub use bijective_higher_ranked_trait;
#[macro_export]
macro_rules! bijective_higher_ranked_type {
{
- $(#[$($meta:tt)*])*
- $vis:vis $(for[$($extra_lt:lifetime)*])? type $name:ident[
+ $(for[$($extra_lt:lifetime)*])? use $name:ident[
$($ctx:lifetime),*
][
$($generic:ident),*
@@ -234,19 +239,6 @@ macro_rules! bijective_higher_ranked_type {
($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,)*)?
- )>
- );
-
impl<
$lt,
$($($extra_lt,)*)?
@@ -330,6 +322,47 @@ macro_rules! bijective_higher_ranked_type {
}
};
{
+ $(#[$($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),*
][
@@ -385,6 +418,32 @@ macro_rules! bijective_higher_ranked_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)*})?
+ }
}
}