]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
rust: pin-init: implement `ZeroableOption` for function pointers with up to 20 arguments
authorBenno Lossin <lossin@kernel.org>
Fri, 23 May 2025 14:51:02 +0000 (16:51 +0200)
committerBenno Lossin <lossin@kernel.org>
Wed, 11 Jun 2025 19:13:57 +0000 (21:13 +0200)
`Option<[unsafe] [extern "abi"] fn(...args...) -> ret>` is documented
[1] to also have the `None` variant equal all zeroes.

Link: https://doc.rust-lang.org/stable/std/option/index.html#representation
Link: https://github.com/Rust-for-Linux/pin-init/pull/56/commits/b6c1ab4fb3699765f81ae512ecac5a2f032d8d51
Link: https://lore.kernel.org/all/20250523145125.523275-7-lossin@kernel.org
Signed-off-by: Benno Lossin <lossin@kernel.org>
rust/pin-init/src/lib.rs

index a4656e7976c7e25c20784c6a3281bf027941b01a..3e5fe84ae5478470edb208f0d78d40127a5b6460 100644 (file)
@@ -1662,6 +1662,22 @@ macro_rules! impl_tuple_zeroable {
 
 impl_tuple_zeroable!(A, B, C, D, E, F, G, H, I, J);
 
+macro_rules! impl_fn_zeroable_option {
+    ([$($abi:literal),* $(,)?] $args:tt) => {
+        $(impl_fn_zeroable_option!({extern $abi} $args);)*
+        $(impl_fn_zeroable_option!({unsafe extern $abi} $args);)*
+    };
+    ({$($prefix:tt)*} {$(,)?}) => {};
+    ({$($prefix:tt)*} {$ret:ident, $($rest:ident),* $(,)?}) => {
+        // SAFETY: function pointers are part of the option layout optimization:
+        // <https://doc.rust-lang.org/stable/std/option/index.html#representation>.
+        unsafe impl<$ret, $($rest),*> ZeroableOption for $($prefix)* fn($($rest),*) -> $ret {}
+        impl_fn_zeroable_option!({$($prefix)*} {$($rest),*,});
+    };
+}
+
+impl_fn_zeroable_option!(["Rust", "C"] { A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U });
+
 /// This trait allows creating an instance of `Self` which contains exactly one
 /// [structurally pinned value](https://doc.rust-lang.org/std/pin/index.html#projections-and-structural-pinning).
 ///