Skip to content

Instantly share code, notes, and snippets.

@rust-play
Created January 1, 2023 08:50
Show Gist options
  • Select an option

  • Save rust-play/eca8908d9bbc474f5a2682fa05db3f31 to your computer and use it in GitHub Desktop.

Select an option

Save rust-play/eca8908d9bbc474f5a2682fa05db3f31 to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
#![feature(tuple_trait)]
#![feature(fn_traits)]
#![feature(type_alias_impl_trait)]
#![feature(unboxed_closures)]
#![feature(associated_type_defaults)]
trait Spec {
type SpecOwn;
type SpecOut<'a>
where
Self::SpecOwn: 'a;
type SpecArgs<'a>: std::marker::Tuple = (Self::SpecOut<'a>,) where Self::SpecOwn: 'a;
}
struct Own<A>(std::marker::PhantomData<A>);
impl<A> Spec for Own<A> {
type SpecOwn = A;
type SpecOut<'a> = A where A: 'a;
}
struct Ref<A>(std::marker::PhantomData<A>);
impl<A> Spec for Ref<A> {
type SpecOwn = A;
type SpecOut<'a> = &'a A where A: 'a;
}
/// Spec FnOnce.
trait Sfno<Args: Spec> {
type SfnoOut;
extern "rust-call" fn sfno(self, args: Args::SpecArgs<'_>) -> Self::SfnoOut;
}
struct SfnoWrap<F>(F);
impl<A, B, Imp: FnOnce<(A,), Output = B>> Sfno<Own<A>> for SfnoWrap<Imp> {
type SfnoOut = B;
extern "rust-call" fn sfno(self, args: (A,)) -> B {
self.0.call_once(args)
}
}
impl<A, B, Imp: for<'a> FnOnce<(&'a A,), Output = B>> Sfno<Ref<A>> for SfnoWrap<Imp> {
type SfnoOut = B;
extern "rust-call" fn sfno(self, args: (&A,)) -> B {
self.0.call_once(args)
}
}
struct DummySfno<A, B>(std::marker::PhantomData<(A, B)>);
impl<A: Spec, B> Sfno<A> for DummySfno<A, B> {
type SfnoOut = B;
extern "rust-call" fn sfno(self, _args: A::SpecArgs<'_>) -> B {
unreachable!()
}
}
/// Spec Cont FnOnce Morphism.
trait Scfnom<ScfnomDom: Spec>: Sized {
type ScfnomCod: Spec;
type ScfnomOut<R, F: Sfno<Self::ScfnomCod, SfnoOut = R>>: Sfno<ScfnomDom, SfnoOut = R>;
fn scfnom<R, F: Sfno<Self::ScfnomCod, SfnoOut = R>>(self, f: F) -> Self::ScfnomOut<R, F>;
}
struct DummyScfnom<A, B>(std::marker::PhantomData<(A, B)>);
impl<A: Spec, B: Spec> Scfnom<A> for DummyScfnom<A, B> {
type ScfnomCod = B;
type ScfnomOut<R, F: Sfno<Self::ScfnomCod, SfnoOut = R>> = DummySfno<A, R>;
fn scfnom<R, F: Sfno<Self::ScfnomCod, SfnoOut = R>>(self, _f: F) -> Self::ScfnomOut<R, F> {
unreachable!()
}
}
struct DummyAttic<Dom, Cod>(std::marker::PhantomData<(Dom, Cod)>);
impl<Dom: Spec, Cod: Spec> Attic for DummyAttic<Dom, Cod> {
type Domain = Dom;
type Codomain = Cod;
}
trait Attic: Sized {
type Domain: Spec = Own<()>;
type Codomain: Spec = Own<()>;
type SfnoSol: Sfno<Self::Domain, SfnoOut = <Self::Codomain as Spec>::SpecOwn> =
DummySfno<Self::Domain, <Self::Codomain as Spec>::SpecOwn>;
type ScfnomSol: Scfnom<Self::Domain, ScfnomCod = Self::Codomain> =
DummyScfnom<Self::Domain, Self::Codomain>;
type Clause: Clause = ();
type Scrap: Attic<
Domain = <Self::Clause as Clause>::Dom<Self>,
Codomain = <Self::Clause as Clause>::Cod<Self>,
> = DummyAttic<<Self::Clause as Clause>::Dom<Self>, <Self::Clause as Clause>::Cod<Self>>;
}
trait Clause: Sized {
type Dom<Att: Attic>: Spec = Att::Domain;
type Cod<Att: Attic>: Spec = Att::Codomain;
}
impl Clause for () {}
trait Cursor: Sized {
type BlockSol<Att: Attic<Clause = Self::Clause>>;
type ReturnSol<Att: Attic<Clause = Self::Clause>>;
type Clause: Clause = ();
}
type BlockSolOf<Cur, Att> = <Cur as Cursor>::BlockSol<Att>;
type ReturnSolOf<Cur, Att> = <Cur as Cursor>::ReturnSol<Att>;
trait IdOp: Cursor {
type IdOpAtt<A: Spec>: Attic<Clause = Self::Clause, Domain = A, Codomain = A>;
fn id_op<A: Spec>(self) -> (Self, BlockSolOf<Self, Self::IdOpAtt<A>>);
}
trait CatOp: Cursor {
type CatOpAtt<_1, _2>: Attic<
Clause = Self::Clause,
Domain = _1::Domain,
Codomain = _2::Codomain,
>
where
_1: Attic<Clause = Self::Clause>,
_2: Attic<Clause = Self::Clause, Domain = _1::Codomain>;
fn cat_op<_1, _2>(
self,
lhs: BlockSolOf<Self, _1>,
rhs: BlockSolOf<Self, _2>,
) -> (Self, BlockSolOf<Self, Self::CatOpAtt<_1, _2>>)
where
_1: Attic<Clause = Self::Clause>,
_2: Attic<Clause = Self::Clause, Domain = _1::Codomain>;
}
trait ArrOp: Cursor {
type ArrOpAtt<A: Spec, B: Spec, F: Scfnom<A, ScfnomCod = B>>: Attic<
Clause = Self::Clause,
Domain = A,
Codomain = B,
>;
#[allow(clippy::type_complexity)]
fn arr_op<A: Spec, B: Spec, F: Scfnom<A, ScfnomCod = B>>(
self,
f: F,
) -> (Self, BlockSolOf<Self, Self::ArrOpAtt<A, B, F>>);
}
trait AsRefOp: Cursor {
type AsRefOpAtt<A, _1>: Attic<Clause = Self::Clause, Domain = Own<A>, Codomain = _1::Codomain>
where
_1: Attic<Clause = Self::Clause, Domain = Ref<A>>;
#[allow(clippy::wrong_self_convention)]
fn as_ref_op<A, _1>(
self,
arg: BlockSolOf<Self, _1>,
) -> (Self, BlockSolOf<Self, Self::AsRefOpAtt<A, _1>>)
where
_1: Attic<Clause = Self::Clause, Domain = Ref<A>>;
}
trait ReturnOp: Cursor {
type ReturnOpAtt<A, _1: Attic<Clause = Self::Clause, Codomain = Own<A>>>: Attic<
Clause = Self::Clause,
Domain = _1::Domain,
Codomain = Own<A>,
>;
fn return_op<A, _1: Attic<Clause = Self::Clause, Codomain = Own<A>>>(
self,
blk: BlockSolOf<Self, _1>,
) -> (Self, ReturnSolOf<Self, Self::ReturnOpAtt<A, _1>>);
}
macro_rules! decl_cfnom {
($Name:ident $self:ident $f:ident [$($q:tt)*] [$($A:tt)*] [$($B:tt)*] [$($code:tt)*]) => {
struct $Name;
const _: () = {
impl $($q)* Scfnom<$($A)*> for $Name {
type ScfnomCod = $($B)*;
type ScfnomOut<R, F: Sfno<Self::ScfnomCod, SfnoOut = R>> = impl Sfno<$($A)*, SfnoOut = R>;
fn scfnom<R, F: Sfno<Self::ScfnomCod, SfnoOut = R>>(self, $f: F) -> Self::ScfnomOut<R, F> {
$($code)*
}
}
};
}
}
fn main() {
use rand::Rng;
let mut rng = rand::thread_rng();
let x: u32 = rng.gen();
println!("{}", program_asm(x >> 2));
}
#[inline(never)]
pub extern "C" fn program_asm(a: u32) -> u64 {
let (_, b) = program(MyCursor);
b.sfno((a,))
}
fn program<Cur>(
cur: Cur,
) -> (
Cur,
ReturnSolOf<Cur, impl Attic<Clause = Cur::Clause, Domain = Own<u32>, Codomain = Own<u64>>>,
)
where
Cur: IdOp + CatOp + ArrOp + AsRefOp + ReturnOp,
{
decl_cfnom! { Cfn01 self f [] [Own<u32>] [Own<(u32,u64,u128)>] [
SfnoWrap(|dom: u32| f.sfno((((dom + 11) * 22, ((dom + 33) as u64) * 44, ((dom + 55) as u128) * 66),)))
]}
let (cur, cratic_a) = cur.arr_op(Cfn01);
decl_cfnom! { Cfn02 self f [] [Ref<(u32,u64,u128)>] [Own<u64>] [
SfnoWrap(|dom: &(u32,u64,u128)| f.sfno((dom.0 as u64 + dom.1 + dom.2 as u64 + 77_u64,)))
]}
let (cur, cratic_b) = cur.arr_op(Cfn02);
let (cur, cratic_c) = cur.as_ref_op(cratic_b);
let (cur, cratic_d) = cur.id_op();
let (cur, cratic_e) = cur.cat_op(cratic_a, cratic_c);
let (cur, cratic_f) = cur.cat_op(cratic_e, cratic_d);
let (cur, cratic) = cur.return_op(cratic_f);
(cur, cratic)
}
struct MyCursor;
impl Cursor for MyCursor {
type BlockSol<Att: Attic<Clause = Self::Clause>> = Att::ScfnomSol;
type ReturnSol<Att: Attic<Clause = Self::Clause>> = Att::SfnoSol;
}
const _: () = {
struct Scfn;
impl<A: Spec> Scfnom<A> for Scfn {
type ScfnomCod = A;
type ScfnomOut<R, F: Sfno<Self::ScfnomCod, SfnoOut = R>> = impl Sfno<A, SfnoOut = R>;
fn scfnom<R, F: Sfno<Self::ScfnomCod, SfnoOut = R>>(self, f: F) -> Self::ScfnomOut<R, F> {
f
}
}
struct Att<A>(std::marker::PhantomData<A>);
impl<A: Spec> Attic for Att<A> {
type Domain = A;
type Codomain = A;
type ScfnomSol = Scfn;
}
impl IdOp for MyCursor {
type IdOpAtt<A: Spec> = Att<A>;
fn id_op<A: Spec>(self) -> (Self, Scfn) {
(self, Scfn)
}
}
};
const _: () = {
struct Scfn<_1, _2>(BlockSolOf<MyCursor, _1>, BlockSolOf<MyCursor, _2>)
where
_1: Attic<Clause = ()>,
_2: Attic<Clause = (), Domain = _1::Codomain>;
impl<_1, _2> Scfnom<_1::Domain> for Scfn<_1, _2>
where
_1: Attic<Clause = ()>,
_2: Attic<Clause = (), Domain = _1::Codomain>,
{
type ScfnomCod = _2::Codomain;
type ScfnomOut<R, F: Sfno<Self::ScfnomCod, SfnoOut = R>> =
impl Sfno<_1::Domain, SfnoOut = R>;
fn scfnom<R, F: Sfno<Self::ScfnomCod, SfnoOut = R>>(self, f: F) -> Self::ScfnomOut<R, F> {
self.0.scfnom(self.1.scfnom(f))
}
}
struct Att<_1, _2>(std::marker::PhantomData<(_1, _2)>);
impl<_1, _2> Attic for Att<_1, _2>
where
_1: Attic<Clause = ()>,
_2: Attic<Clause = (), Domain = _1::Codomain>,
{
type Domain = _1::Domain;
type Codomain = _2::Codomain;
type ScfnomSol = Scfn<_1, _2>;
}
impl CatOp for MyCursor {
type CatOpAtt<_1, _2> = Att<_1, _2>
where
_1: Attic<Clause = Self::Clause>,
_2: Attic<Clause = Self::Clause, Domain = _1::Codomain>;
fn cat_op<_1, _2>(
self,
lhs: BlockSolOf<Self, _1>,
rhs: BlockSolOf<Self, _2>,
) -> (Self, BlockSolOf<Self, Self::CatOpAtt<_1, _2>>)
where
_1: Attic<Clause = Self::Clause>,
_2: Attic<Clause = Self::Clause, Domain = _1::Codomain>,
{
(Self, Scfn::<_1, _2>(lhs, rhs))
}
}
};
const _: () = {
struct Att<A, B, F>(std::marker::PhantomData<(A, B, F)>);
impl<A: Spec, B: Spec, F: Scfnom<A, ScfnomCod = B>> Attic for Att<A, B, F> {
type Domain = A;
type Codomain = B;
type ScfnomSol = F;
}
impl ArrOp for MyCursor {
type ArrOpAtt<A: Spec, B: Spec, F: Scfnom<A, ScfnomCod = B>> = Att<A, B, F>;
fn arr_op<A: Spec, B: Spec, F: Scfnom<A, ScfnomCod = B>>(self, f: F) -> (Self, F) {
(self, f)
}
}
};
const _: () = {
struct Scfn<_1: Attic<Clause = ()>>(BlockSolOf<MyCursor, _1>);
impl<A, _1> Scfnom<Own<A>> for Scfn<_1>
where
_1: Attic<Clause = (), Domain = Ref<A>>,
{
type ScfnomCod = _1::Codomain;
type ScfnomOut<R, F: Sfno<Self::ScfnomCod, SfnoOut = R>> = impl Sfno<Own<A>, SfnoOut = R>;
fn scfnom<R, F: Sfno<Self::ScfnomCod, SfnoOut = R>>(self, f: F) -> Self::ScfnomOut<R, F> {
SfnoWrap(|dom| self.0.scfnom(f).sfno((&dom,)))
}
}
struct Att<A, _1>(std::marker::PhantomData<(A, _1)>);
impl<A, _1> Attic for Att<A, _1>
where
_1: Attic<Clause = (), Domain = Ref<A>>,
{
type Domain = Own<A>;
type Codomain = _1::Codomain;
type ScfnomSol = Scfn<_1>;
}
impl AsRefOp for MyCursor {
type AsRefOpAtt<A, _1> = Att<A, _1>
where
_1: Attic<Clause = Self::Clause, Domain = Ref<A>>;
fn as_ref_op<A, _1>(
self,
arg: BlockSolOf<Self, _1>,
) -> (Self, BlockSolOf<Self, Self::AsRefOpAtt<A, _1>>)
where
_1: Attic<Clause = Self::Clause, Domain = Ref<A>>,
{
(self, Scfn::<_1>(arg))
}
}
};
const _: () = {
struct Att<A, _1, F>(std::marker::PhantomData<(A, _1, F)>);
impl<A, _1, F> Attic for Att<A, _1, F>
where
_1: Attic<Clause = (), Codomain = Own<A>>,
F: Sfno<_1::Domain, SfnoOut = A>,
{
type Domain = _1::Domain;
type Codomain = Own<A>;
type SfnoSol = F;
}
impl ReturnOp for MyCursor {
type ReturnOpAtt<A, _1: Attic<Clause = Self::Clause, Codomain = Own<A>>> =
Att<A, _1, impl Sfno<_1::Domain, SfnoOut = A>>;
fn return_op<A, _1: Attic<Clause = Self::Clause, Codomain = Own<A>>>(
self,
blk: BlockSolOf<Self, _1>,
) -> (Self, ReturnSolOf<Self, Self::ReturnOpAtt<A, _1>>) {
(self, blk.scfnom(SfnoWrap(|a: A| a)))
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment