}
macro_rules! fnptr_impls_args {
- ($($Arg: ident),*) => {
+ ($($Arg: ident),+) => {
fnptr_impls_safety_abi! { extern "Rust" fn($($Arg),*) -> Ret, $($Arg),* }
fnptr_impls_safety_abi! { extern "C" fn($($Arg),*) -> Ret, $($Arg),* }
+ fnptr_impls_safety_abi! { extern "C" fn($($Arg),* , ...) -> Ret, $($Arg),* }
fnptr_impls_safety_abi! { unsafe extern "Rust" fn($($Arg),*) -> Ret, $($Arg),* }
fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),*) -> Ret, $($Arg),* }
- }
+ fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),* , ...) -> Ret, $($Arg),* }
+ };
+ () => {
+ // No variadic functions with 0 parameters
+ fnptr_impls_safety_abi! { extern "Rust" fn() -> Ret, }
+ fnptr_impls_safety_abi! { extern "C" fn() -> Ret, }
+ fnptr_impls_safety_abi! { unsafe extern "Rust" fn() -> Ret, }
+ fnptr_impls_safety_abi! { unsafe extern "C" fn() -> Ret, }
+ };
}
fnptr_impls_args! { }
let zs: &mut [i32] = &mut [1, 2, 3];
assert!(ys == zs);
}
+
+#[test]
+fn test_variadic_fnptr() {
+ use core::hash::{Hash, SipHasher};
+ extern "C" {
+ fn printf(_: *const u8, ...);
+ }
+ let p: unsafe extern "C" fn(*const u8, ...) = printf;
+ let q = p.clone();
+ assert_eq!(p, q);
+ assert!(!(p < q));
+ let mut s = SipHasher::new();
+ assert_eq!(p.hash(&mut s), q.hash(&mut s));
+}