> +pub unsafe trait FnCall<Args, R = ()>: 'static + Sync + Sized { > + /// Referring to this internal constant asserts that the `Self` type is > + /// zero-sized. Can be replaced by an inline const expression in > + /// Rust 1.79.0+. > + const ASSERT_ZERO_SIZED: () = { assert!(mem::size_of::<Self>() == 0) }; > + > + /// Call the function with the arguments in args. > + fn call(a: Args) -> R; > +} > + > +macro_rules! impl_call { > + ($($args:ident,)* ) => ( > + // SAFETY: because each function is treated as a separate type, > + // accessing `FnCall` is only possible in code that would be > + // allowed to call the function. > + unsafe impl<F, $($args,)* R> FnCall<($($args,)*), R> for F > + where > + F: 'static + Sync + Sized + Fn($($args, )*) -> R, > + { > + #[inline(always)] > + fn call(a: ($($args,)*)) -> R { > + let _: () = Self::ASSERT_ZERO_SIZED; > + > + // SAFETY: the safety of this method is the condition for > implementing > + // `FnCall`. As to the `NonNull` idiom to create a > zero-sized type, > + // see https://github.com/rust-lang/libs-team/issues/292. > + let f: &'static F = unsafe { > &*NonNull::<Self>::dangling().as_ptr() };
Awesome! The definition of FnCall and this trick are both very elegant! I've learned a lot. > + let ($($args,)*) = a; > + f($($args,)*) > + } > + } > + ) > +} > + The examples and test both show the power of this callback pattern, Reviewed-by: Zhao Liu <zhao1....@intel.com>