1use core::{convert::Infallible, marker::PhantomData};
2
3use crate::TypeFn;
4
5mod sealed {
6    pub trait LifetimeHkt {}
7    pub trait Lt {}
8}
9
10#[doc(hidden)]
11pub trait _LifetimeHktOf<'lt>: sealed::LifetimeHkt {
12    type T: ?Sized;
13}
14
15pub trait LifetimeHkt {
36    type Actual<'x>: ?Sized;
38}
39
40pub type Actual<'lt, H> = <H as LifetimeHkt>::Actual<'lt>;
41
42impl<H> LifetimeHkt for HktWrapper<H>
43where
44    H: ?Sized + for<'x> _LifetimeHktOf<'x>,
45{
46    type Actual<'x> = <H as _LifetimeHktOf<'x>>::T;
47}
48
49#[doc(hidden)]
50pub struct Invariant<T: ?Sized>(PhantomData<fn(PhantomData<T>) -> PhantomData<T>>);
51#[doc(hidden)]
52pub struct Lifetime<'lt>(Invariant<&'lt ()>);
53
54#[doc(hidden)]
55pub struct HktWrapper<L: ?Sized>(Infallible, Invariant<L>);
56
57pub type LtList<'x, L = ()> = (Lifetime<'x>, L);
58
59pub trait Lt: sealed::Lt {
61    type Next: Lt;
62    type NextExtending: Lt;
63    type Extend<'a>: Lt;
64    type Actual<H: LifetimeHkt>: ?Sized;
65    type NextTypeFn<F: for<'x> LifetimeHkt<Actual<'x>: TypeFn>>: TypeFn;
66}
67
68impl sealed::Lt for () {}
69impl<L> sealed::Lt for LtList<'_, L> where L: sealed::Lt {}
70
71impl Lt for () {
72    type Next = ();
73    type NextExtending = LtList<'static, Self>;
74    type Extend<'a> = LtList<'a, Self>;
75    type Actual<H: LifetimeHkt> = H::Actual<'static>;
76    type NextTypeFn<F: for<'x> LifetimeHkt<Actual<'x>: TypeFn>> = Self::Actual<F>;
77}
78
79impl<'lt, L> Lt for LtList<'lt, L>
80where
81    L: Lt,
82{
83    type Next = L;
84    type NextExtending = L::Extend<'lt>;
85    type Extend<'a> = Self;
86    type Actual<H: LifetimeHkt> = H::Actual<'lt>;
87    type NextTypeFn<F: for<'x> LifetimeHkt<Actual<'x>: TypeFn>> = Self::Actual<F>;
88}
89
90impl<T: ?Sized + sealed::LifetimeHkt> sealed::LifetimeHkt for HktWrapper<T> {}
91
92#[macro_export]
106macro_rules! Lt {
107    () => { () };
108    ($lt0:lifetime $(, $($rest:tt)*)?) => {
109        $crate::lt::LtList::<$lt0, $crate::Lt![$($($rest)*)?]>
110    };
111    (..$Ty:ty) => { $Ty };
112}
113
114#[macro_export]
122macro_rules! LifetimeHkt {
123    (for <$lt:lifetime> $T:ty) => {
124        $crate::lt::HktWrapper::<dyn for<$lt> $crate::lt::_LifetimeHktOf<$lt, T = $T>>
125    };
126}