#![feature(unboxed_closures)] #![feature(fn_traits)] macro_rules! itt { () => { () }; ($name:ident) => { ($name,) }; ($($name:ident),+$(,)?) => { ($($name),+) }; } macro_rules! ttt { () => { () }; ($type:ty) => { ($type,) }; ($($type:ty),+$(,)?) => { ($($type),+) }; } macro_rules! tou { () => { () }; ($type:ty) => { $type }; } macro_rules! overloaddddddd { ($type:tt { $( ($($name:ident: $arg:ty),*) $(-> $ret:ty)? { $body:expr } )* }) => { #[allow(non_camel_case_types)] struct $type; $( impl FnOnce for $type where $type: std::ops::Fn, { type Output = tou!($($ret)?); extern "rust-call" fn call_once(self, args: ttt!($($arg),*)) -> Self::Output { self.call(args) } } impl FnMut for $type where $type: std::ops::Fn, { extern "rust-call" fn call_mut(&mut self, args: ttt!($($arg),*)) -> Self::Output { self.call(args) } } impl Fn for $type { extern "rust-call" fn call(&self, itt!($($name),*): ttt!($($arg),*)) -> Self::Output { $body } } )* }; } overloaddddddd!(cursed { (name: String) {{ println!("{name}") }} (num: usize) -> usize {{ println!("{num}"); num + 1 }} () {{ println!("No arguments?"); }} }); fn main() { cursed("test".to_string()); println!("{}", cursed(1337usize)); cursed(); }