meow
This commit is contained in:
commit
eb948e4889
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/target
|
||||
/Cargo.lock
|
8
Cargo.toml
Normal file
8
Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "metatrait"
|
||||
version = "0.0.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
futures = "0.3"
|
||||
pin-project = "1"
|
4
src/lib.rs
Normal file
4
src/lib.rs
Normal file
@ -0,0 +1,4 @@
|
||||
pub mod model_00;
|
||||
pub mod model_01;
|
||||
#[cfg(any())]
|
||||
pub mod model_02; // ICE
|
29
src/model_00.rs
Normal file
29
src/model_00.rs
Normal file
@ -0,0 +1,29 @@
|
||||
trait Trait {
|
||||
type More: ?Sized + Trait;
|
||||
}
|
||||
|
||||
trait ImplBase<T: ?Sized + Trait> {
|
||||
type More: ?Sized + ImplSelf<T::More>;
|
||||
}
|
||||
|
||||
trait ImplSelf<T: ?Sized + Trait>: ImplBase<T, More = Self> {}
|
||||
|
||||
impl<T: ?Sized + Trait, I: ?Sized + ImplBase<T, More = I>> ImplSelf<T> for I {}
|
||||
|
||||
struct Empty;
|
||||
|
||||
impl Trait for Empty {
|
||||
type More = Self;
|
||||
}
|
||||
|
||||
impl<T: ?Sized> ImplBase<Empty> for T {
|
||||
type More = Self;
|
||||
}
|
||||
|
||||
fn test() -> impl ImplSelf<Empty> {
|
||||
123
|
||||
}
|
||||
|
||||
pub fn _test() {
|
||||
let _ = test();
|
||||
}
|
520
src/model_01.rs
Normal file
520
src/model_01.rs
Normal file
@ -0,0 +1,520 @@
|
||||
use std::{
|
||||
future::Future,
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
|
||||
use pin_project::pin_project;
|
||||
|
||||
trait More {
|
||||
type Trait: ?Sized + Trait;
|
||||
type More: ?Sized + More;
|
||||
type Overlay: ?Sized + OverlayMore<Self>;
|
||||
}
|
||||
|
||||
trait OverlayTrait<T: ?Sized + Trait> {
|
||||
type More: ?Sized + OverlayMore<T::More>;
|
||||
type Associated: ?Sized + Trait;
|
||||
}
|
||||
|
||||
trait OverlayMore<T: ?Sized + More> {
|
||||
type Trait: ?Sized + OverlayTrait<T::Trait>;
|
||||
type More: ?Sized + OverlayMore<T::More>;
|
||||
}
|
||||
|
||||
trait Method {
|
||||
type Trait: ?Sized + Trait;
|
||||
type In<'tmp, 'out: 'tmp, I: 'tmp + ?Sized + Impl<Self::Trait>>
|
||||
where
|
||||
Self: 'tmp;
|
||||
type Out<'out, I: ?Sized + Impl<Self::Trait>>;
|
||||
}
|
||||
|
||||
trait Member {
|
||||
type Trait: ?Sized + Trait;
|
||||
type Associated<I: ?Sized + Impl<Self::Trait>>: ?Sized + Trait;
|
||||
type Method: ?Sized + Method<Trait = Self::Trait>;
|
||||
}
|
||||
|
||||
trait SizedMethod {
|
||||
type Trait: ?Sized + Trait;
|
||||
type InS<'tmp, 'out: 'tmp, I: 'tmp + Impl<Self::Trait>>
|
||||
where
|
||||
Self: 'tmp;
|
||||
type OutS<'out, I: Impl<Self::Trait>>;
|
||||
}
|
||||
|
||||
trait SizedMember {
|
||||
type Trait: ?Sized + Trait;
|
||||
type AssociatedS<I: Impl<Self::Trait>>: ?Sized + Trait;
|
||||
type MethodS: ?Sized + SizedMethod<Trait = Self::Trait>;
|
||||
}
|
||||
|
||||
impl<T: ?Sized + Method> SizedMethod for T {
|
||||
type Trait = T::Trait;
|
||||
type InS<'tmp, 'out: 'tmp, I: 'tmp + Impl<Self::Trait>> = T::In<'tmp, 'out, I> where Self: 'tmp;
|
||||
type OutS<'out, I: Impl<Self::Trait>> = T::Out<'out, I>;
|
||||
}
|
||||
|
||||
impl<T: ?Sized + Member> SizedMember for T {
|
||||
type Trait = T::Trait;
|
||||
type AssociatedS<I: Impl<Self::Trait>> = T::Associated<I>;
|
||||
type MethodS = T::Method;
|
||||
}
|
||||
|
||||
trait Trait {
|
||||
type More: ?Sized + More;
|
||||
type Member: ?Sized + Member<Trait = Self>;
|
||||
type Sized: ?Sized + SizedMember<Trait = Self>;
|
||||
}
|
||||
|
||||
trait ImplMethod<T: ?Sized + Method> {
|
||||
fn method<'tmp, 'out>(_: T::In<'tmp, 'out, Self>) -> T::Out<'out, Self>
|
||||
where
|
||||
Self: 'tmp + Impl<T::Trait>;
|
||||
}
|
||||
|
||||
trait ImplSizedMethod<T: ?Sized + SizedMethod> {
|
||||
fn method_s<'tmp, 'out>(_: T::InS<'tmp, 'out, Self>) -> T::OutS<'out, Self>
|
||||
where
|
||||
Self: 'tmp + Sized + Impl<T::Trait>;
|
||||
}
|
||||
|
||||
impl<T: ?Sized + Method, I: ?Sized + ImplMethod<T>> ImplSizedMethod<T> for I {
|
||||
fn method_s<'tmp, 'out>(
|
||||
arg: <T as SizedMethod>::InS<'tmp, 'out, Self>,
|
||||
) -> <T as SizedMethod>::OutS<'out, Self>
|
||||
where
|
||||
Self: 'tmp + Sized + Impl<<T as SizedMethod>::Trait>,
|
||||
{
|
||||
<Self as ImplMethod<T>>::method(arg)
|
||||
}
|
||||
}
|
||||
|
||||
trait ImplMember<T: ?Sized + Member>: ImplMethod<T::Method> {
|
||||
type Associated: Impl<T::Associated<Self>>
|
||||
where
|
||||
Self: Impl<T::Trait>;
|
||||
}
|
||||
|
||||
trait ImplSizedMember<T: ?Sized + SizedMember>: ImplSizedMethod<T::MethodS> {
|
||||
type AssociatedS: Impl<T::AssociatedS<Self>>
|
||||
where
|
||||
Self: Sized + Impl<T::Trait>;
|
||||
}
|
||||
|
||||
impl<T: ?Sized + Member, I: ?Sized + ImplMember<T>> ImplSizedMember<T> for I {
|
||||
type AssociatedS = <Self as ImplMember<T>>::Associated
|
||||
where
|
||||
Self: Sized + Impl<<T as SizedMember>::Trait>;
|
||||
}
|
||||
|
||||
trait ImplBase<T: ?Sized + Trait>: ImplMember<T::Member> + ImplSizedMember<T::Sized> {
|
||||
type More: ?Sized + ImplMore<T::More>;
|
||||
}
|
||||
|
||||
trait Impl<T: ?Sized + Trait>: ImplBase<T, More = Self> {}
|
||||
|
||||
impl<T: ?Sized + Trait, I: ?Sized + ImplBase<T, More = Self>> Impl<T> for I {}
|
||||
|
||||
trait ImplOverlayBase<T: ?Sized + More> {
|
||||
type _Trait: ?Sized + Impl<T::Trait>;
|
||||
type _Associated: Impl<
|
||||
<<T::Overlay as OverlayMore<T>>::Trait as OverlayTrait<T::Trait>>::Associated,
|
||||
>;
|
||||
}
|
||||
|
||||
trait ImplOverlay<T: ?Sized + More>:
|
||||
Impl<T::Trait>
|
||||
+ ImplOverlayBase<
|
||||
T,
|
||||
_Trait = Self,
|
||||
_Associated = <Self as ImplMember<<T::Trait as Trait>::Member>>::Associated,
|
||||
>
|
||||
{
|
||||
}
|
||||
|
||||
impl<T: ?Sized + More, I: ?Sized + Impl<T::Trait>> ImplOverlayBase<T> for I
|
||||
where
|
||||
<Self as ImplMember<<T::Trait as Trait>::Member>>::Associated:
|
||||
Impl<<<T::Overlay as OverlayMore<T>>::Trait as OverlayTrait<T::Trait>>::Associated>,
|
||||
{
|
||||
type _Trait = Self;
|
||||
type _Associated = <Self as ImplMember<<T::Trait as Trait>::Member>>::Associated;
|
||||
}
|
||||
|
||||
impl<T: ?Sized + More, I: ?Sized + Impl<T::Trait>> ImplOverlay<T> for I where
|
||||
<Self as ImplMember<<T::Trait as Trait>::Member>>::Associated:
|
||||
Impl<<<T::Overlay as OverlayMore<T>>::Trait as OverlayTrait<T::Trait>>::Associated>
|
||||
{
|
||||
}
|
||||
|
||||
trait ImplMoreBase<T: ?Sized + More> {
|
||||
type MoreTrait: ?Sized + ImplOverlay<T>;
|
||||
type MoreMore: ?Sized + ImplMore<T::More>;
|
||||
}
|
||||
|
||||
impl<T: ?Sized + More, I: ?Sized + ImplMoreBase<T, MoreMore = Self, MoreTrait = Self>> ImplMore<T>
|
||||
for I
|
||||
{
|
||||
}
|
||||
|
||||
trait ImplMore<T: ?Sized + More>: ImplMoreBase<T, MoreMore = Self, MoreTrait = Self> {}
|
||||
|
||||
enum Empty {}
|
||||
|
||||
impl More for Empty {
|
||||
type Trait = Self;
|
||||
type More = Self;
|
||||
type Overlay = Self;
|
||||
}
|
||||
|
||||
impl<T: ?Sized + Trait> OverlayTrait<T> for Empty {
|
||||
type More = Self;
|
||||
type Associated = Self;
|
||||
}
|
||||
|
||||
impl<T: ?Sized + More> OverlayMore<T> for Empty {
|
||||
type Trait = Self;
|
||||
type More = Self;
|
||||
}
|
||||
|
||||
impl Method for Empty {
|
||||
type Trait = Self;
|
||||
type In<'tmp, 'out: 'tmp, I: 'tmp + ?Sized> = Self;
|
||||
type Out<'out, I: ?Sized> = Self;
|
||||
}
|
||||
|
||||
impl Member for Empty {
|
||||
type Trait = Self;
|
||||
type Associated<I: ?Sized> = Self;
|
||||
type Method = Self;
|
||||
}
|
||||
|
||||
impl Trait for Empty {
|
||||
type More = Self;
|
||||
type Member = Self;
|
||||
type Sized = Self;
|
||||
}
|
||||
|
||||
impl<T: ?Sized> ImplMoreBase<Empty> for T {
|
||||
type MoreTrait = Self;
|
||||
type MoreMore = Self;
|
||||
}
|
||||
|
||||
impl<T: ?Sized> ImplMethod<Empty> for T {
|
||||
fn method<'tmp, 'out>(empty: Empty) -> <Empty as Method>::Out<'out, Self>
|
||||
where
|
||||
Self: 'tmp,
|
||||
{
|
||||
empty
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> ImplMember<Empty> for T {
|
||||
type Associated = Empty
|
||||
where
|
||||
Self: Impl<Empty>;
|
||||
}
|
||||
|
||||
impl<T: ?Sized> ImplBase<Empty> for T {
|
||||
type More = Self;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn int_is_empty() {
|
||||
fn takes_empty(_: impl Impl<Empty>) {}
|
||||
takes_empty(123);
|
||||
}
|
||||
|
||||
struct Futures;
|
||||
|
||||
impl Method for Futures {
|
||||
type Trait = Self;
|
||||
type In<'tmp, 'out: 'tmp, I: 'tmp + ?Sized + Impl<Self::Trait>> =
|
||||
(Pin<&'tmp mut I>, &'tmp mut Context<'out>);
|
||||
type Out<'out, I: ?Sized + Impl<Self::Trait>> = Poll<I::Associated>;
|
||||
}
|
||||
|
||||
impl Member for Futures {
|
||||
type Trait = Self;
|
||||
type Associated<I: ?Sized + Impl<Self::Trait>> = Empty;
|
||||
type Method = Self;
|
||||
}
|
||||
|
||||
impl Trait for Futures {
|
||||
type More = Empty;
|
||||
type Member = Self;
|
||||
type Sized = Self;
|
||||
}
|
||||
|
||||
impl<T: ?Sized + Future> ImplMethod<Futures> for T {
|
||||
fn method<'tmp, 'out>(
|
||||
(fut, cx): <Futures as Method>::In<'tmp, 'out, Self>,
|
||||
) -> <Futures as Method>::Out<'out, Self>
|
||||
where
|
||||
Self: 'tmp,
|
||||
{
|
||||
fut.poll(cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized + Future> ImplMember<Futures> for T {
|
||||
type Associated = T::Output
|
||||
where
|
||||
Self: Impl<<Futures as Member>::Trait>;
|
||||
}
|
||||
|
||||
impl<T: ?Sized + Future> ImplBase<Futures> for T {
|
||||
type More = Self;
|
||||
}
|
||||
|
||||
struct No<T: ?Sized>(T);
|
||||
|
||||
impl<T: ?Sized + Trait> Method for No<T> {
|
||||
type Trait = T;
|
||||
type In<'tmp, 'out: 'tmp, I: 'tmp + ?Sized + Impl<Self::Trait>> = Empty
|
||||
where
|
||||
Self: 'tmp;
|
||||
type Out<'out, I: ?Sized + Impl<Self::Trait>> = Empty;
|
||||
}
|
||||
|
||||
impl<T: ?Sized + Trait> Member for No<T> {
|
||||
type Trait = T;
|
||||
type Associated<I: ?Sized + Impl<Self::Trait>> = Empty;
|
||||
type Method = Self;
|
||||
}
|
||||
|
||||
impl<T: ?Sized + Trait, I: ?Sized> ImplMethod<No<T>> for I {
|
||||
fn method<'tmp, 'out>(empty: Empty) -> <No<T> as Method>::Out<'out, Self>
|
||||
where
|
||||
Self: 'tmp + Impl<<No<T> as Method>::Trait>,
|
||||
{
|
||||
empty
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized + Trait, I: ?Sized> ImplMember<No<T>> for I {
|
||||
type Associated = Empty
|
||||
where
|
||||
Self: Impl<<No<T> as Member>::Trait>;
|
||||
}
|
||||
|
||||
struct Is<A>(A);
|
||||
|
||||
impl<A> SizedMethod for Is<A> {
|
||||
type Trait = Self;
|
||||
type InS<'tmp, 'out: 'tmp, I: 'tmp + Impl<Self::Trait>> = I
|
||||
where
|
||||
Self: 'tmp;
|
||||
type OutS<'out, I: Impl<Self::Trait>> = A;
|
||||
}
|
||||
|
||||
impl<A> SizedMember for Is<A> {
|
||||
type Trait = Self;
|
||||
type AssociatedS<I: Impl<Self::Trait>> = Empty;
|
||||
type MethodS = Self;
|
||||
}
|
||||
|
||||
impl<A> Trait for Is<A> {
|
||||
type More = Empty;
|
||||
type Member = No<Self>;
|
||||
type Sized = Self;
|
||||
}
|
||||
|
||||
impl<I> ImplSizedMethod<Is<I>> for I {
|
||||
fn method_s<'tmp, 'out>(this: Self) -> <Is<I> as SizedMethod>::OutS<'out, Self>
|
||||
where
|
||||
Self: 'tmp + Sized + Impl<<Is<I> as SizedMethod>::Trait>,
|
||||
{
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
impl<I> ImplSizedMember<Is<I>> for I {
|
||||
type AssociatedS = Empty
|
||||
where
|
||||
Self: Sized + Impl<<Is<I> as SizedMember>::Trait>;
|
||||
}
|
||||
|
||||
impl<I> ImplBase<Is<I>> for I {
|
||||
type More = Self;
|
||||
}
|
||||
|
||||
struct FutureIs<A>(A);
|
||||
|
||||
impl<A> More for FutureIs<A> {
|
||||
type Trait = Futures;
|
||||
type More = Empty;
|
||||
type Overlay = Self;
|
||||
}
|
||||
|
||||
impl<A> OverlayMore<Self> for FutureIs<A> {
|
||||
type Trait = Self;
|
||||
type More = Empty;
|
||||
}
|
||||
|
||||
impl<A> OverlayTrait<Futures> for FutureIs<A> {
|
||||
type More = Empty;
|
||||
type Associated = Is<A>;
|
||||
}
|
||||
|
||||
impl<A> Trait for FutureIs<A> {
|
||||
type More = Self;
|
||||
type Member = No<Self>;
|
||||
type Sized = No<Self>;
|
||||
}
|
||||
|
||||
impl<F: ?Sized + Future> ImplBase<FutureIs<F::Output>> for F {
|
||||
type More = Self;
|
||||
}
|
||||
|
||||
impl<F: ?Sized + Future> ImplMoreBase<FutureIs<F::Output>> for F {
|
||||
type MoreTrait = Self;
|
||||
type MoreMore = Self;
|
||||
}
|
||||
|
||||
trait TraitInto<A> {
|
||||
fn trait_into(self) -> A;
|
||||
}
|
||||
|
||||
impl<A, I: Impl<Is<A>>> TraitInto<A> for I {
|
||||
fn trait_into(self) -> A {
|
||||
I::method_s(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
struct TraitFuture<F: ?Sized + Impl<Futures>>(#[pin] F);
|
||||
|
||||
impl<F: ?Sized + Impl<Futures>> Future for TraitFuture<F> {
|
||||
type Output = F::Associated;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
F::method((self.project().0, cx))
|
||||
}
|
||||
}
|
||||
|
||||
fn aaaaaaa<A>(a: impl Impl<Is<A>>) -> A {
|
||||
a.trait_into()
|
||||
}
|
||||
|
||||
fn aaaaaa<
|
||||
A,
|
||||
Ot: ?Sized + OverlayTrait<M::Trait, Associated = Is<A>>,
|
||||
Om: ?Sized + OverlayMore<M, Trait = Ot>,
|
||||
M: More<Overlay = Om>,
|
||||
I: ImplOverlayBase<M>,
|
||||
>(
|
||||
a: <I as ImplOverlayBase<M>>::_Associated,
|
||||
) -> A {
|
||||
aaaaaaa::<A>(a)
|
||||
}
|
||||
|
||||
async fn aaaaa<
|
||||
A,
|
||||
Ot: ?Sized + OverlayTrait<Futures, Associated = Is<A>>,
|
||||
Om: ?Sized + OverlayMore<M, Trait = Ot>,
|
||||
M: More<Trait = Futures, Overlay = Om>,
|
||||
I: ImplOverlay<M> + Impl<Futures> + ImplMember<Futures>,
|
||||
>(
|
||||
a: I,
|
||||
) -> A {
|
||||
let a = TraitFuture(a).await;
|
||||
let a: <I as ImplOverlayBase<M>>::_Associated = a;
|
||||
aaaaaa::<A, Ot, Om, M, I>(a)
|
||||
}
|
||||
|
||||
fn aaaa<
|
||||
A,
|
||||
Ot: ?Sized + OverlayTrait<Futures, Associated = Is<A>>,
|
||||
Om: ?Sized + OverlayMore<M, Trait = Ot>,
|
||||
M: More<Trait = Futures, Overlay = Om>,
|
||||
I: ImplMore<M>,
|
||||
>(
|
||||
a: I,
|
||||
) -> impl Future<Output = A> {
|
||||
aaaaa(upcast_ioi_ioia(upcast_im_ioi::<M, _>(a)))
|
||||
}
|
||||
|
||||
fn aaa<A>(a: impl Impl<FutureIs<A>>) -> impl Future<Output = A> {
|
||||
aaaa(upcast_i_im(a))
|
||||
}
|
||||
|
||||
trait TraitIntoFuture<A> {
|
||||
fn trait_into_future(self) -> impl Future<Output = A>;
|
||||
}
|
||||
|
||||
impl<A, F: Impl<FutureIs<A>>> TraitIntoFuture<A> for F {
|
||||
fn trait_into_future(self) -> impl Future<Output = A> {
|
||||
aaa(self)
|
||||
}
|
||||
}
|
||||
|
||||
trait Functor {
|
||||
type Trait<A>: ?Sized + Trait;
|
||||
fn pure<A>(a: A) -> impl Impl<Self::Trait<A>>;
|
||||
fn map<A, B>(a: impl Impl<Self::Trait<A>>, f: impl FnOnce(A) -> B)
|
||||
-> impl Impl<Self::Trait<B>>;
|
||||
}
|
||||
|
||||
impl Functor for Futures {
|
||||
type Trait<A> = FutureIs<A>;
|
||||
|
||||
fn pure<A>(a: A) -> impl Impl<Self::Trait<A>> {
|
||||
async { a }
|
||||
}
|
||||
|
||||
fn map<A, B>(
|
||||
a: impl Impl<Self::Trait<A>>,
|
||||
f: impl FnOnce(A) -> B,
|
||||
) -> impl Impl<Self::Trait<B>> {
|
||||
async { f(a.trait_into_future().await) }
|
||||
}
|
||||
}
|
||||
|
||||
fn upcast_ioi_ioia<T: ?Sized + More, I: ImplOverlay<T> + Impl<T::Trait>>(
|
||||
value: I,
|
||||
) -> impl ImplOverlay<T> + ImplMember<<T::Trait as Trait>::Member> {
|
||||
value
|
||||
}
|
||||
|
||||
fn upcast_imb_ioi<T: ?Sized + More, I: ImplMoreBase<T>>(
|
||||
value: I::MoreTrait,
|
||||
) -> impl ImplOverlay<T> + Impl<T::Trait>
|
||||
where
|
||||
<I as ImplMoreBase<T>>::MoreTrait: Sized,
|
||||
{
|
||||
value
|
||||
}
|
||||
|
||||
fn upcast_im_ioi<T: ?Sized + More, I: ImplMore<T>>(value: I) -> impl ImplOverlay<T> {
|
||||
upcast_imb_ioi::<T, I>(value)
|
||||
}
|
||||
|
||||
fn upcast_ib_im<T: ?Sized + Trait, I: ImplBase<T>>(value: I::More) -> impl ImplMore<T::More>
|
||||
where
|
||||
<I as ImplBase<T>>::More: Sized,
|
||||
{
|
||||
value
|
||||
}
|
||||
|
||||
fn upcast_i_im<T: ?Sized + Trait, I: Impl<T>>(value: I) -> impl ImplMore<T::More> {
|
||||
upcast_ib_im::<T, I>(value)
|
||||
}
|
||||
|
||||
pub async fn add5(x: i32) -> i32 {
|
||||
let x = Futures::pure(x);
|
||||
let x = Futures::map(x, |x| x + 1);
|
||||
let x = Futures::map(x, |x| x + 1);
|
||||
let x = Futures::map(x, |x| x + 1);
|
||||
let x = Futures::map(x, |x| x + 1);
|
||||
let x = Futures::map(x, |x| x + 1);
|
||||
x.trait_into_future().await
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn wah() {
|
||||
let x = futures::executor::block_on(add5(5));
|
||||
assert_eq!(x, 10);
|
||||
}
|
199
src/model_02.rs
Normal file
199
src/model_02.rs
Normal file
@ -0,0 +1,199 @@
|
||||
use std::{
|
||||
future::Future,
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
|
||||
use pin_project::pin_project;
|
||||
|
||||
trait More {
|
||||
type Trait: ?Sized + Trait;
|
||||
}
|
||||
|
||||
trait Member {
|
||||
type Trait: ?Sized + Trait;
|
||||
type Associated<I: ?Sized + Impl<Self::Trait>>: ?Sized + Trait;
|
||||
}
|
||||
|
||||
trait SizedMember {
|
||||
type Trait: ?Sized + Trait;
|
||||
}
|
||||
|
||||
impl<T: ?Sized + Member> SizedMember for T {
|
||||
type Trait = T::Trait;
|
||||
}
|
||||
|
||||
trait Trait {
|
||||
type More: ?Sized + More;
|
||||
type Member: ?Sized + Member<Trait = Self>;
|
||||
type Sized: ?Sized + SizedMember<Trait = Self>;
|
||||
}
|
||||
|
||||
trait ImplMember<T: ?Sized + Member> {
|
||||
type Associated: Impl<T::Associated<Self>>
|
||||
where
|
||||
Self: Impl<T::Trait>;
|
||||
}
|
||||
|
||||
trait ImplSizedMember<T: ?Sized + SizedMember> {}
|
||||
|
||||
impl<T: ?Sized + Member, I: ?Sized + ImplMember<T>> ImplSizedMember<T> for I {}
|
||||
|
||||
trait ImplBase<T: ?Sized + Trait>: ImplMember<T::Member> + ImplSizedMember<T::Sized> {
|
||||
type More: ?Sized + ImplMore<T::More>;
|
||||
}
|
||||
|
||||
trait Impl<T: ?Sized + Trait>: ImplBase<T, More = Self> {}
|
||||
|
||||
impl<T: ?Sized + Trait, I: ?Sized + ImplBase<T, More = Self>> Impl<T> for I {}
|
||||
|
||||
trait ImplMore<T: ?Sized + More>: Impl<T::Trait> {}
|
||||
|
||||
enum Empty {}
|
||||
|
||||
impl More for Empty {
|
||||
type Trait = Self;
|
||||
}
|
||||
|
||||
impl Member for Empty {
|
||||
type Trait = Self;
|
||||
type Associated<I: ?Sized> = Self;
|
||||
}
|
||||
|
||||
impl Trait for Empty {
|
||||
type More = Self;
|
||||
type Member = Self;
|
||||
type Sized = Self;
|
||||
}
|
||||
|
||||
impl<T: ?Sized> ImplMore<Empty> for T {}
|
||||
|
||||
impl<T: ?Sized> ImplMember<Empty> for T {
|
||||
type Associated = Empty
|
||||
where
|
||||
Self: Impl<Empty>;
|
||||
}
|
||||
|
||||
impl<T: ?Sized> ImplBase<Empty> for T {
|
||||
type More = Self;
|
||||
}
|
||||
|
||||
struct Futures;
|
||||
|
||||
impl Member for Futures {
|
||||
type Trait = Self;
|
||||
type Associated<I: ?Sized + Impl<Self::Trait>> = Empty;
|
||||
}
|
||||
|
||||
impl Trait for Futures {
|
||||
type More = Empty;
|
||||
type Member = Self;
|
||||
type Sized = Self;
|
||||
}
|
||||
|
||||
impl<T: ?Sized + Future> ImplMember<Futures> for T {
|
||||
type Associated = T::Output
|
||||
where
|
||||
Self: Impl<<Futures as Member>::Trait>;
|
||||
}
|
||||
|
||||
impl<T: ?Sized + Future> ImplBase<Futures> for T {
|
||||
type More = Self;
|
||||
}
|
||||
|
||||
struct No<T: ?Sized>(T);
|
||||
|
||||
impl<T: ?Sized + Trait> Member for No<T> {
|
||||
type Trait = T;
|
||||
type Associated<I: ?Sized + Impl<Self::Trait>> = Empty;
|
||||
}
|
||||
|
||||
impl<T: ?Sized + Trait, I: ?Sized> ImplMember<No<T>> for I {
|
||||
type Associated = Empty
|
||||
where
|
||||
Self: Impl<<No<T> as Member>::Trait>;
|
||||
}
|
||||
|
||||
struct Is<A>(A);
|
||||
|
||||
impl<A> SizedMember for Is<A> {
|
||||
type Trait = Self;
|
||||
}
|
||||
|
||||
impl<A> Trait for Is<A> {
|
||||
type More = Empty;
|
||||
type Member = No<Self>;
|
||||
type Sized = Self;
|
||||
}
|
||||
|
||||
impl<I> ImplSizedMember<Is<I>> for I {}
|
||||
|
||||
impl<I> ImplBase<Is<I>> for I {
|
||||
type More = Self;
|
||||
}
|
||||
|
||||
struct FutureIs<A>(A);
|
||||
|
||||
impl<A> More for FutureIs<A> {
|
||||
type Trait = Futures;
|
||||
}
|
||||
|
||||
impl<A> Trait for FutureIs<A> {
|
||||
type More = Self;
|
||||
type Member = No<Self>;
|
||||
type Sized = No<Self>;
|
||||
}
|
||||
|
||||
impl<F: ?Sized + Future> ImplBase<FutureIs<F::Output>> for F {
|
||||
type More = Self;
|
||||
}
|
||||
|
||||
impl<F: ?Sized + Future> ImplMore<FutureIs<F::Output>> for F {}
|
||||
|
||||
#[pin_project]
|
||||
struct TraitFuture<F: ?Sized + Impl<Futures>>(#[pin] F);
|
||||
|
||||
impl<F: ?Sized + Impl<Futures>> Future for TraitFuture<F> {
|
||||
type Output = F::Associated;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
trait Functor {
|
||||
type Trait<A>: ?Sized + Trait;
|
||||
fn pure<A>(a: A) -> impl Impl<Self::Trait<A>>;
|
||||
fn map<A, B>(a: impl Impl<Self::Trait<A>>, f: impl FnOnce(A) -> B)
|
||||
-> impl Impl<Self::Trait<B>>;
|
||||
}
|
||||
|
||||
impl Functor for Futures {
|
||||
type Trait<A> = FutureIs<A>;
|
||||
|
||||
fn pure<A>(a: A) -> impl Impl<Self::Trait<A>> {
|
||||
async { a }
|
||||
}
|
||||
|
||||
fn map<A, B>(
|
||||
a: impl Impl<Self::Trait<A>>,
|
||||
f: impl FnOnce(A) -> B,
|
||||
) -> impl Impl<Self::Trait<B>> {
|
||||
let fut = TraitFuture(upcast(a));
|
||||
async {
|
||||
let a = fut.await;
|
||||
f(todo!())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn upcast_more<T: ?Sized + Trait, I: ImplBase<T>>(value: I::More) -> impl ImplMore<T::More>
|
||||
where
|
||||
<I as ImplBase<T>>::More: std::marker::Sized,
|
||||
{
|
||||
value
|
||||
}
|
||||
|
||||
fn upcast<T: ?Sized + Trait, I: Impl<T>>(value: I) -> impl ImplMore<T::More> {
|
||||
upcast_more::<T, I>(value)
|
||||
}
|
Loading…
Reference in New Issue
Block a user