This commit is contained in:
AF 2024-05-10 17:25:52 +03:00
commit eb948e4889
Signed by: alisa
SSH Key Fingerprint: SHA256:vNY4pdIZvO1FYJKHROkdHLtvyopizvZVAEwg9AF6h04
6 changed files with 762 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/target
/Cargo.lock

8
Cargo.toml Normal file
View 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
View 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
View 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
View 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
View 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)
}