use alloc::string::String;
use core::marker::PhantomData;
use core::mem::{transmute, transmute_copy};
use core::ops::{Deref, DerefMut};
use core::pin::Pin;
use core::ptr;
struct Specializer<T, S>(pub T, PhantomData<S>);
impl<T, S> Specializer<T, S> {
fn select(spec: &S) -> Specializer<PhantomData<T>, S> {
Specializer(PhantomData, PhantomData)
}
}
impl<S> Specializer<PhantomData<()>, S> {
unsafe fn init<T>(self, arg: T) -> Specializer<T, S> {
Specializer(arg, PhantomData)
}
}
fn test<T: HasSpecialization<S>, S>(x: Specializer<T, S>)
where
S: SimpleTrait,
{
x.0.specialized_ref().simple_call()
}
#[cfg(test)]
#[test]
fn call_test() {
let arg = Foo("");
let tmp = outermost_level(&arg).select();
test(unsafe { tmp.init(arg) });
let arg = Foo(1usize);
let tmp = outermost_level(&arg).select();
test(unsafe { tmp.init(arg) });
}
trait SimpleTrait {
fn simple_call(&self);
}
struct Foo<X>(X);
impl<X> SimpleTrait for Foo<X> {
fn simple_call(&self) {
panic!("1");
}
}
impl SimpleTrait for Level<Foo<usize>> {
fn simple_call(&self) {
panic!("2")
}
}
trait SimpleTraitSpecializer: Sized {
fn select(&self) -> Specializer<PhantomData<()>, Self> {
Specializer(PhantomData, PhantomData)
}
}
impl<T: SimpleTrait> SimpleTraitSpecializer for T {}
impl<X> SpecializationOf for Foo<X> {
type Original = Foo<X>;
}
trait SpecializationOf {
type Original;
}
impl<X: SpecializationOf> SpecializationOf for Level<X> {
type Original = X::Original;
}
fn outermost_level<T>(
arg: &T,
) -> &Level<Level<Level<Level<Level<Level<Level<Level<Level<Level<T>>>>>>>>>> {
unsafe { transmute(arg) }
}
#[repr(transparent)]
struct Level<T>(pub T);
impl<T> Deref for Level<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for Level<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
type Implements<T> = Level<T>;
trait Spec<Marker: Bool> {}
struct True;
impl Bool for True {}
struct False;
impl Bool for False {}
impl<T: Clone + MaybeCopy<IsCopy = True>> Spec<True> for T {}
impl<T: Clone + MaybeCopy> Spec<False> for T {}
trait MaybeCopy {
type IsCopy: Bool;
type SelfButKnownToBeCopy: Copy + TypeEq<Self>;
}
impl<T: Copy> MaybeCopy for T {
type IsCopy = True;
type SelfButKnownToBeCopy = T;
}
trait TypeEq<T> {
fn concrete(self) -> T;
fn concrete_ref(&self) -> &T;
fn concrete_mut(&mut self) -> &mut T;
}
impl<T> TypeEq<T> for T {
fn concrete(self) -> T {
unsafe { transmute_copy(&self) }
}
fn concrete_ref(&self) -> &T {
unsafe { transmute_copy(&self) }
}
fn concrete_mut(&mut self) -> &mut T {
unsafe { transmute_copy(&self) }
}
}