#![feature(unsized_locals)] #![feature(unboxed_closures)] #![feature(tuple_trait)] pub trait FnOnce { type Output; extern "rust-call" fn call_once(self, args: Args) -> Self::Output; } struct A; impl FnOnce<(String, Box)> for A { type Output = String; extern "rust-call" fn call_once(self, (s1, s2): (String, Box)) -> Self::Output { assert_eq!(&s1 as &str, "s1"); assert_eq!(&s2 as &str, "s2"); format!("hello") } } struct B(i32); impl FnOnce<(String, Box)> for B { type Output = String; extern "rust-call" fn call_once(self, (s1, s2): (String, Box)) -> Self::Output { assert_eq!(&s1 as &str, "s1"); assert_eq!(&s2 as &str, "s2"); format!("{}", self.0) } } struct C(String); impl FnOnce<(String, Box)> for C { type Output = String; extern "rust-call" fn call_once(self, (s1, s2): (String, Box)) -> Self::Output { assert_eq!(&s1 as &str, "s1"); assert_eq!(&s2 as &str, "s2"); self.0 } } struct D(Box); impl FnOnce<(String, Box)> for D { type Output = String; extern "rust-call" fn call_once(self, (s1, s2): (String, Box)) -> Self::Output { assert_eq!(&s1 as &str, "s1"); assert_eq!(&s2 as &str, "s2"); *self.0 } } fn main() { let (s1, s2) = (format!("s1"), format!("s2").into_boxed_str()); let x = *(Box::new(A) as Box), Output = String>>); assert_eq!(x.call_once((s1, s2)), format!("hello")); let (s1, s2) = (format!("s1"), format!("s2").into_boxed_str()); let x = *(Box::new(B(42)) as Box), Output = String>>); assert_eq!(x.call_once((s1, s2)), format!("42")); let (s1, s2) = (format!("s1"), format!("s2").into_boxed_str()); let x = *(Box::new(C(format!("jumping fox"))) as Box), Output = String>>); assert_eq!(x.call_once((s1, s2)), format!("jumping fox")); let (s1, s2) = (format!("s1"), format!("s2").into_boxed_str()); let x = *(Box::new(D(Box::new(format!("lazy dog")))) as Box), Output = String>>); assert_eq!(x.call_once((s1, s2)), format!("lazy dog")); }