Skip to content

Commit f187065

Browse files
committed
implement ZeroableOption for function pointers with up to 20 arguments
`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 [1] Signed-off-by: Benno Lossin <[email protected]>
1 parent c3ffdd5 commit f187065

File tree

2 files changed

+18
-0
lines changed

2 files changed

+18
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717
- add `Zeroable::init_zeroed()` delegating to `init_zeroed()`
1818
- add new `zeroed()`, a safe version of `mem::zeroed()` and also provide it via `Zeroable::zeroed()`
1919
- implement `Zeroable` for `Option<&T>` and `Option<&mut T>`
20+
- implement `Zeroable` for `Option<[unsafe] [extern "abi"] fn(...args...) -> ret>` for `"Rust"` and
21+
`"C"` ABIs and up to 20 arguments
2022

2123
### Changed
2224

src/lib.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1662,6 +1662,22 @@ macro_rules! impl_tuple_zeroable {
16621662

16631663
impl_tuple_zeroable!(A, B, C, D, E, F, G, H, I, J);
16641664

1665+
macro_rules! impl_fn_zeroable_option {
1666+
([$($abi:literal),* $(,)?] $args:tt) => {
1667+
$(impl_fn_zeroable_option!({extern $abi} $args);)*
1668+
$(impl_fn_zeroable_option!({unsafe extern $abi} $args);)*
1669+
};
1670+
({$($prefix:tt)*} {$(,)?}) => {};
1671+
({$($prefix:tt)*} {$ret:ident, $($rest:ident),* $(,)?}) => {
1672+
// SAFETY: function pointers are part of the option layout optimization:
1673+
// <https://doc.rust-lang.org/stable/std/option/index.html#representation>.
1674+
unsafe impl<$ret, $($rest),*> ZeroableOption for $($prefix)* fn($($rest),*) -> $ret {}
1675+
impl_fn_zeroable_option!({$($prefix)*} {$($rest),*,});
1676+
};
1677+
}
1678+
1679+
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 });
1680+
16651681
/// This trait allows creating an instance of `Self` which contains exactly one
16661682
/// [structurally pinned value](https://doc.rust-lang.org/std/pin/index.html#projections-and-structural-pinning).
16671683
///

0 commit comments

Comments
 (0)