diff --git a/Cargo.toml b/Cargo.toml index 8634980a67..78e6d5f29b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,6 +61,7 @@ alloc = [] derive = ["zerocopy-derive"] simd = [] simd-nightly = ["simd"] +float-nightly = [] std = ["alloc"] # This feature depends on all other features that work on the stable compiler. # We make no stability guarantees about this feature; it may be modified or diff --git a/README.md b/README.md index 6fa9a240f5..b419c05eda 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,10 @@ for network parsing. available on nightly. Since these types are unstable, support for any type may be removed at any point in the future. +- **`float-nightly`** + Adds support for the unstable `f16` and `f128` types. These types are + not yet fully implemented and may not be supported on all platforms. + [duplicate-import-errors]: https://github.com/google/zerocopy/issues/1587 [simd-layout]: https://rust-lang.github.io/unsafe-code-guidelines/layout/packed-simd-vectors.html diff --git a/src/impls.rs b/src/impls.rs index 0a552d5231..321bad7fe3 100644 --- a/src/impls.rs +++ b/src/impls.rs @@ -72,6 +72,10 @@ safety_comment! { unsafe_impl!(isize: Immutable, TryFromBytes, FromZeros, FromBytes, IntoBytes); unsafe_impl!(f32: Immutable, TryFromBytes, FromZeros, FromBytes, IntoBytes); unsafe_impl!(f64: Immutable, TryFromBytes, FromZeros, FromBytes, IntoBytes); + #[cfg(feature = "float-nightly")] + unsafe_impl!(#[cfg_attr(doc_cfg, doc(cfg(feature = "float-nightly")))] f16: Immutable, TryFromBytes, FromZeros, FromBytes, IntoBytes); + #[cfg(feature = "float-nightly")] + unsafe_impl!(#[cfg_attr(doc_cfg, doc(cfg(feature = "float-nightly")))] f128: Immutable, TryFromBytes, FromZeros, FromBytes, IntoBytes); } safety_comment! { diff --git a/src/lib.rs b/src/lib.rs index 44699ac4a7..1ff923a509 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -137,6 +137,10 @@ //! available on nightly. Since these types are unstable, support for any type //! may be removed at any point in the future. //! +//! - **`float-nightly`** +//! Adds support for the unstable `f16` and `f128` types. These types are +//! not yet fully implemented and may not be supported on all platforms. +//! //! [duplicate-import-errors]: https://github.com/google/zerocopy/issues/1587 //! [simd-layout]: https://rust-lang.github.io/unsafe-code-guidelines/layout/packed-simd-vectors.html //! @@ -304,6 +308,7 @@ all(feature = "simd-nightly", any(target_arch = "powerpc", target_arch = "powerpc64")), feature(stdarch_powerpc) )] +#![cfg_attr(feature = "float-nightly", feature(f16, f128))] #![cfg_attr(doc_cfg, feature(doc_cfg))] #![cfg_attr( __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS, diff --git a/src/util/macros.rs b/src/util/macros.rs index 263fde6ac7..5d9eb54a6a 100644 --- a/src/util/macros.rs +++ b/src/util/macros.rs @@ -62,10 +62,37 @@ macro_rules! unsafe_impl { unsafe_impl!(@method $trait $(; |$candidate: MaybeAligned<$repr>| $is_bit_valid)?); } }; + // Implement all `$traits` for `$ty` with no bounds. - ($ty:ty: $($traits:ident),*) => { - $( unsafe_impl!($ty: $traits); )* + // + // The 2 arms under this one are there so we can apply + // N attributes for each one of M trait implementations. + // The simple solution of: + // + // ($(#[$attrs:meta])* $ty:ty: $($traits:ident),*) => { + // $( unsafe_impl!( $(#[$attrs])* $ty: $traits ) );* + // } + // + // Won't work. The macro processor sees that the outer repetition + // contains both $attrs and $traits and expects them to match the same + // amount of fragments. + // + // To solve this we must: + // 1. Pack the attributes into a single token tree fragment we can match over. + // 2. Expand the traits. + // 3. Unpack and expand the attributes. + ($(#[$attrs:meta])* $ty:ty: $($traits:ident),*) => { + unsafe_impl!(@impl_traits_with_packed_attrs { $(#[$attrs])* } $ty: $($traits),*) }; + + (@impl_traits_with_packed_attrs $attrs:tt $ty:ty: $($traits:ident),*) => { + $( unsafe_impl!(@unpack_attrs $attrs $ty: $traits); )* + }; + + (@unpack_attrs { $(#[$attrs:meta])* } $ty:ty: $traits:ident) => { + unsafe_impl!($(#[$attrs])* $ty: $traits); + }; + // This arm is identical to the following one, except it contains a // preceding `const`. If we attempt to handle these with a single arm, there // is an inherent ambiguity between `const` (the keyword) and `const` (the