1macro_rules! impl_fn {
4 (@recurse () ($($nm:ident : $ty:ident),*)) => {
5 impl_fn!(@impl_all ($($nm : $ty),*));
6 };
7 (@recurse ($hd_nm:ident : $hd_ty:ident $(, $tl_nm:ident : $tl_ty:ident)*) ($($nm:ident : $ty:ident),*)) => {
8 impl_fn!(@impl_all ($($nm : $ty),*));
9 impl_fn!(@recurse ($($tl_nm : $tl_ty),*) ($($nm : $ty,)* $hd_nm : $hd_ty));
10 };
11
12 (@impl_all ($($nm:ident : $ty:ident),*)) => {
13 impl_fn!(@impl_u_and_s ($($nm : $ty),*), Rust, "Rust");
14 impl_fn!(@impl_u_and_s ($($nm : $ty),*), C, "C");
15 impl_fn!(@impl_u_and_s ($($nm : $ty),*), System, "system");
16 #[cfg(has_abi_cdecl)]
17 impl_fn!(@impl_u_and_s ($($nm : $ty),*), Cdecl, "cdecl");
18 #[cfg(has_abi_stdcall)]
19 impl_fn!(@impl_u_and_s ($($nm : $ty),*), Stdcall, "stdcall");
20 #[cfg(has_abi_fastcall)]
21 impl_fn!(@impl_u_and_s ($($nm : $ty),*), Fastcall, "fastcall");
22 #[cfg(has_abi_win64)]
23 impl_fn!(@impl_u_and_s ($($nm : $ty),*), Win64, "win64");
24 #[cfg(has_abi_sysv64)]
25 impl_fn!(@impl_u_and_s ($($nm : $ty),*), Sysv64, "sysv64");
26 #[cfg(has_abi_aapcs)]
27 impl_fn!(@impl_u_and_s ($($nm : $ty),*), Aapcs, "aapcs");
28 };
29
30 (@impl_u_and_s ($($nm:ident : $ty:ident),*), $abi_ident:ident, $abi_str:expr) => {
31 impl_fn!(@impl_core ($($nm : $ty),*), extern $abi_str fn($($ty),*) -> Ret, true, $abi_ident, $abi_str);
32 impl_fn!(@impl_core ($($nm : $ty),*), unsafe extern $abi_str fn($($ty),*) -> Ret, false, $abi_ident, $abi_str);
33 };
34
35 (@impl_core ($($nm:ident : $ty:ident),*), $fn_type:ty, $safety:tt, $abi_ident:ident, $call_conv:expr) => {
36 #[automatically_derived]
37 impl<Ret, $($ty),*> $crate::FnPtr for $fn_type {
38 type Args = ($($ty,)*);
39 type Output = Ret;
40
41 const ARITY: ::core::primitive::usize = impl_fn!(@count ($($ty)*));
42 const IS_SAFE: ::core::primitive::bool = $safety;
43 const IS_EXTERN: ::core::primitive::bool = !matches!($crate::Abi::$abi_ident, $crate::Abi::Rust);
44 const ABI: $crate::Abi = $crate::Abi::$abi_ident;
45
46 fn as_ptr(&self) -> $crate::UntypedFnPtr {
47 *self as $crate::UntypedFnPtr
48 }
49 unsafe fn from_ptr(ptr: $crate::UntypedFnPtr) -> Self {
50 ::core::assert!(!ptr.is_null());
51 unsafe { ::core::mem::transmute::<$crate::UntypedFnPtr, Self>(ptr) }
52 }
53 }
54 impl_fn!(@impl_safe_fn_type ($($nm : $ty),*), $fn_type, $safety);
55
56 #[automatically_derived]
57 impl<Ret: 'static, $($ty: 'static),*> $crate::StaticFnPtr for $fn_type {
58 }
59
60 #[automatically_derived]
62 impl<Ret, $($ty),*> $crate::WithSafety<{true}> for $fn_type {
63 type F = extern $call_conv fn($($ty),*) -> Ret;
64 }
65 #[automatically_derived]
66 impl<Ret, $($ty),*> $crate::WithSafety<{false}> for $fn_type {
67 type F = unsafe extern $call_conv fn($($ty),*) -> Ret;
68 }
69
70 #[automatically_derived]
72 impl<Ret, $($ty),*> $crate::HasAbi<{$crate::abi!($call_conv)}> for $fn_type {}
73
74 #[automatically_derived]
76 impl<Ret, $($ty),*> $crate::WithAbi<{$crate::abi!("Rust")}> for $fn_type {
77 type F = impl_fn!(@make_unsafe extern "Rust" fn($($ty),*) -> Ret, $safety);
78 }
79 #[automatically_derived]
80 impl<Ret, $($ty),*> $crate::WithAbi<{$crate::abi!("C")}> for $fn_type {
81 type F = impl_fn!(@make_unsafe extern "C" fn($($ty),*) -> Ret, $safety);
82 }
83 #[automatically_derived]
84 impl<Ret, $($ty),*> $crate::WithAbi<{$crate::abi!("system")}> for $fn_type {
85 type F = impl_fn!(@make_unsafe extern "system" fn($($ty),*) -> Ret, $safety);
86 }
87 #[cfg(has_abi_cdecl)]
88 #[automatically_derived]
89 impl<Ret, $($ty),*> $crate::WithAbi<{$crate::abi!("cdecl")}> for $fn_type {
90 type F = impl_fn!(@make_unsafe extern "cdecl" fn($($ty),*) -> Ret, $safety);
91 }
92 #[cfg(has_abi_stdcall)]
93 #[automatically_derived]
94 impl<Ret, $($ty),*> $crate::WithAbi<{$crate::abi!("stdcall")}> for $fn_type {
95 type F = impl_fn!(@make_unsafe extern "stdcall" fn($($ty),*) -> Ret, $safety);
96 }
97 #[cfg(has_abi_fastcall)]
98 #[automatically_derived]
99 impl<Ret, $($ty),*> $crate::WithAbi<{$crate::abi!("fastcall")}> for $fn_type {
100 type F = impl_fn!(@make_unsafe extern "fastcall" fn($($ty),*) -> Ret, $safety);
101 }
102 #[cfg(has_abi_win64)]
103 #[automatically_derived]
104 impl<Ret, $($ty),*> $crate::WithAbi<{$crate::abi!("win64")}> for $fn_type {
105 type F = impl_fn!(@make_unsafe extern "win64" fn($($ty),*) -> Ret, $safety);
106 }
107 #[cfg(has_abi_sysv64)]
108 #[automatically_derived]
109 impl<Ret, $($ty),*> $crate::WithAbi<{$crate::abi!("sysv64")}> for $fn_type {
110 type F = impl_fn!(@make_unsafe extern "sysv64" fn($($ty),*) -> Ret, $safety);
111 }
112 #[cfg(has_abi_aapcs)]
113 #[automatically_derived]
114 impl<Ret, $($ty),*> $crate::WithAbi<{$crate::abi!("aapcs")}> for $fn_type {
115 type F = impl_fn!(@make_unsafe extern "aapcs" fn($($ty),*) -> Ret, $safety);
116 }
117 };
118
119 (@count ()) => {
120 0
121 };
122 (@count ($hd:tt $($tl:tt)*)) => {
123 1 + impl_fn!(@count ($($tl)*))
124 };
125
126 (@make_unsafe $fn_type:ty, true) => {
127 $fn_type
128 };
129 (@make_unsafe extern $abi:literal fn($($args:ty),*) -> $ret:ty, false) => {
130 unsafe extern $abi fn($($args),*) -> $ret
131 };
132
133 (@impl_safe_fn_type ($($nm:ident : $ty:ident),*), $fn_type:ty, true) => {
134 #[automatically_derived]
135 impl<Ret, $($ty),*> $crate::SafeFnPtr for $fn_type {
136 fn invoke(&self, impl_fn!(@call_args ($($nm),*)): Self::Args) -> Self::Output {
137 (*self)($($nm),*)
138 }
139 }
140 };
141 (@impl_safe_fn_type ($($nm:ident : $ty:ident),*), $fn_type:ty, false) => {
142 #[automatically_derived]
143 impl<Ret, $($ty),*> $crate::UnsafeFnPtr for $fn_type {
144 unsafe fn invoke(&self, impl_fn!(@call_args ($($nm),*)): Self::Args) -> Self::Output {
145 unsafe { (*self)($($nm),*) }
146 }
147 }
148 };
149
150 (@call_args ($single:ident)) => {
151 ($single,)
152 };
153 (@call_args ($($args:ident),*)) => {
154 ($($args),*)
155 };
156
157 ($($nm:ident : $ty:ident),*) => {
158 impl_fn!(@recurse ($($nm : $ty),*) ());
159 };
160}
161
162#[cfg(not(feature = "max-arity-12"))]
164impl_fn! {
165 __arg_0: A, __arg_1: B, __arg_2: C, __arg_3: D, __arg_4: E, __arg_5: F
166}
167
168#[cfg(feature = "max-arity-12")]
170impl_fn! {
171 __arg_0: A, __arg_1: B, __arg_2: C, __arg_3: D, __arg_4: E, __arg_5: F, __arg_6: G,
172 __arg_7: H, __arg_8: I, __arg_9: J, __arg_10: K, __arg_11: L
173}