use core::marker::PhantomData;
use super::{Mut, Ref, Static, Tagged};
use crate::tag::{Tag, WithLt};
use crate::LtList;
macro_rules! impl_static_tagged {
($($type:ty),* $(,)?) => {
$(
impl Tagged for $type {
type Tag = Static<$type>;
}
)*
}
}
const _: () = {
#[allow(clippy::type_complexity)]
pub struct ArrayTag<T: ?Sized, const N: usize>(PhantomData<(fn() -> *const T, [(); N])>);
impl<L: LtList, T: ?Sized + WithLt<L>, const N: usize> WithLt<L> for ArrayTag<T, N>
where
T::Reified: Sized,
{
type Reified = [T::Reified; N];
}
impl<T: Tagged, const N: usize> Tagged for [T; N] {
type Tag = ArrayTag<T::Tag, N>;
}
impl<T: ?Sized + Tagged + 'static, const N: usize> Tagged for ArrayTag<T, N> {
type Tag = ArrayTag<T::Tag, N>;
}
impl<T: ?Sized + Tag + 'static, const N: usize> Tag for ArrayTag<T, N> {
type LifetimesTag = T::LifetimesTag;
}
};
impl_static_tagged![bool];
impl_static_tagged![char];
impl_static_tagged![f32, f64];
impl_static_tagged![i8, i16, i32, i64, i128, isize];
const _: () = {
impl<T: ?Sized + WithLt<L>, L: LtList> WithLt<L> for *const T {
type Reified = *const T::Reified;
}
impl<T: ?Sized + Tagged> Tagged for *const T {
type Tag = *const T::Tag;
}
impl<T: ?Sized + Tag> Tag for *const T {
type LifetimesTag = T::LifetimesTag;
}
};
const _: () = {
impl<L: LtList, T: ?Sized + WithLt<L>> WithLt<L> for *mut T {
type Reified = *mut T::Reified;
}
impl<T: ?Sized + Tagged> Tagged for *mut T {
type Tag = *mut T::Tag;
}
impl<T: ?Sized + Tag> Tag for *mut T {
type LifetimesTag = T::LifetimesTag;
}
};
impl<'r, T: ?Sized + Tagged> Tagged for &'r T {
type Tag = Ref<T::Tag>;
}
impl<'r, T: ?Sized + Tagged> Tagged for &'r mut T {
type Tag = Mut<T::Tag>;
}
const _: () = {
pub struct Slice<T: ?Sized>(PhantomData<fn() -> *const T>);
impl<L: LtList, T: ?Sized + WithLt<L>> WithLt<L> for Slice<T>
where
T::Reified: Sized,
{
type Reified = [T::Reified];
}
impl<T: ?Sized + Tagged + 'static> Tagged for Slice<T> {
type Tag = Slice<T::Tag>;
}
impl<T: Tagged> Tagged for [T] {
type Tag = Slice<T::Tag>;
}
impl<T: ?Sized + Tag> Tag for Slice<T> {
type LifetimesTag = T::LifetimesTag;
}
};
impl_static_tagged![str];
const _: () = {
macro_rules! impl_tuple {
($($t:ident),*) => {
const _: () = {
pub struct Tuple<$($t: ?Sized),*>(PhantomData<($(fn() -> *const $t,)*)>);
impl<L: LtList $(, $t: ?Sized + WithLt<L>)*> WithLt<L> for Tuple<$($t,)*>
where
$($t::Reified: Sized,)*
($($t::LifetimesTag,)*): $crate::lt_list::MergeTuple
{
type Reified = ($($t::Reified,)*);
}
impl<$($t: Tagged),*> Tagged for ($($t,)*)
where
($(<$t::Tag as Tag>::LifetimesTag,)*): $crate::lt_list::MergeTuple
{
type Tag = Tuple<$($t::Tag,)*>;
}
impl<$($t: ?Sized + Tagged),*> Tagged for Tuple<$($t,)*>
where
($(<$t::Tag as Tag>::LifetimesTag,)*): $crate::lt_list::MergeTuple
{
type Tag = Tuple<$($t::Tag,)*>;
}
impl<$($t: ?Sized + Tag),*> Tag for Tuple<$($t,)*>
where
($($t::LifetimesTag,)*): $crate::lt_list::MergeTuple
{
type LifetimesTag = <($($t::LifetimesTag,)*) as $crate::lt_list::MergeTuple>::LtStructure;
}
};
};
}
impl_tuple!(); impl_tuple!(T);
impl_tuple!(T0, T1);
impl_tuple!(T0, T1, T2);
impl_tuple!(T0, T1, T2, T3);
impl_tuple!(T0, T1, T2, T3, T4);
impl_tuple!(T0, T1, T2, T3, T4, T5);
};
impl_static_tagged![u8, u16, u32, u64, u128, usize];