pub trait Same {
type Type;
fn same_cast(self) -> Self::Type;
}
impl<T> Same for T {
type Type = T;
fn same_cast(self) -> T {
self
}
}
pub trait Generic1 {
type Unit: ?Sized;
type Type: ?Sized;
}
pub trait Rebind1<Y: ?Sized>: Generic1<Unit=Self> {
type Type: Generic1<Unit=Self, Type=Y>;
}
pub trait Generic2: Generic1 {
type Unit: ?Sized;
type Type: ?Sized;
}
pub trait Rebind2<T: ?Sized>: Generic2<Unit=Self> {
type Type: Generic2<Unit=Self, Type=T>;
}
#[macro_export]
macro_rules! declare_generic1 {
($x:ident) => {
impl<T> Generic1 for $x<T> {
type Type = T;
type Unit = $x<()>;
}
impl<T> Rebind1<T> for $x<()> {
type Type = $x<T>;
}
};
}
#[macro_export]
macro_rules! generic1 {
($x:ty) => { <$x as Generic1>::Type }
}
#[macro_export]
macro_rules! can_rebind1 {
($x:ty, $y:ty) => { <$x as Generic1>::Unit: Rebind1<$y> }
}
#[macro_export]
macro_rules! rebind1 {
($x:ty, $y:ty) => { <<$x as Generic1>::Unit as Rebind1<$y>>::Type }
}
#[macro_export]
macro_rules! declare_generic2 {
($x:ident) => {
impl<T0, T1> Generic1 for $x<T0, T1> {
type Type = T0;
type Unit = $x<(), T1>;
}
impl<T1, Y> Rebind1<Y> for $x<(), T1> {
type Type = $x<Y, T1>;
}
impl<T0, T1> Generic2 for $x<T0, T1> {
type Type = T1;
type Unit = $x<T0, ()>;
}
impl<T0, Y> Rebind2<Y> for $x<T0, ()> {
type Type = $x<T0, Y>;
}
};
}
#[macro_export]
macro_rules! generic2 {
($x:ty) => { <$x as Generic2>::Type }
}
#[macro_export]
macro_rules! rebind2 {
($x:ty, $y:ty) => { <<$x as Generic2>::Unit as Rebind1<$y>>::Type }
}
declare_generic1!(Option);
declare_generic2!(Result);
declare_generic1!(Vec);