about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCaleb Zulawski <caleb.zulawski@gmail.com>2023-10-01 21:28:03 -0400
committerCaleb Zulawski <caleb.zulawski@gmail.com>2023-10-01 22:40:19 -0400
commita93ded542652cdff67e8b222c91a401d8e905777 (patch)
tree261eddda3598cea25ea5266b30da570b9ae453cc
parent4825b2a64d765317066948867e8714674419359b (diff)
downloadrust-a93ded542652cdff67e8b222c91a401d8e905777.tar.gz
rust-a93ded542652cdff67e8b222c91a401d8e905777.zip
Remove generic_const_exprs
-rw-r--r--crates/core_simd/Cargo.toml1
-rw-r--r--crates/core_simd/src/lib.rs2
-rw-r--r--crates/core_simd/src/masks.rs5
-rw-r--r--crates/core_simd/src/masks/bitmask.rs2
-rw-r--r--crates/core_simd/src/masks/full_masks.rs25
-rw-r--r--crates/core_simd/src/masks/to_bitmask.rs64
-rw-r--r--crates/core_simd/src/mod.rs5
-rw-r--r--crates/core_simd/src/to_bytes.rs147
-rw-r--r--crates/core_simd/tests/masks.rs1
-rw-r--r--crates/core_simd/tests/to_bytes.rs6
10 files changed, 148 insertions, 110 deletions
diff --git a/crates/core_simd/Cargo.toml b/crates/core_simd/Cargo.toml
index d1a3a515a7e..b4a8fd70f4c 100644
--- a/crates/core_simd/Cargo.toml
+++ b/crates/core_simd/Cargo.toml
@@ -12,7 +12,6 @@ license = "MIT OR Apache-2.0"
 default = ["as_crate"]
 as_crate = []
 std = []
-generic_const_exprs = []
 all_lane_counts = []
 
 [target.'cfg(target_arch = "wasm32")'.dev-dependencies]
diff --git a/crates/core_simd/src/lib.rs b/crates/core_simd/src/lib.rs
index 2d68e4cce85..dd3c546e014 100644
--- a/crates/core_simd/src/lib.rs
+++ b/crates/core_simd/src/lib.rs
@@ -14,8 +14,6 @@
     strict_provenance,
     ptr_metadata
 )]
-#![cfg_attr(feature = "generic_const_exprs", feature(generic_const_exprs))]
-#![cfg_attr(feature = "generic_const_exprs", allow(incomplete_features))]
 #![warn(missing_docs, clippy::missing_inline_in_public_items)] // basically all items, really
 #![deny(unsafe_op_in_unsafe_fn, clippy::undocumented_unsafe_blocks)]
 #![allow(internal_features)]
diff --git a/crates/core_simd/src/masks.rs b/crates/core_simd/src/masks.rs
index fea687bdc1a..b6af9f83581 100644
--- a/crates/core_simd/src/masks.rs
+++ b/crates/core_simd/src/masks.rs
@@ -13,10 +13,7 @@
 mod mask_impl;
 
 mod to_bitmask;
-pub use to_bitmask::ToBitMask;
-
-#[cfg(feature = "generic_const_exprs")]
-pub use to_bitmask::{bitmask_len, ToBitMaskArray};
+pub use to_bitmask::{ToBitMask, ToBitMaskArray};
 
 use crate::simd::{intrinsics, LaneCount, Simd, SimdElement, SimdPartialEq, SupportedLaneCount};
 use core::cmp::Ordering;
diff --git a/crates/core_simd/src/masks/bitmask.rs b/crates/core_simd/src/masks/bitmask.rs
index 20465ba9b07..a7df6304bc7 100644
--- a/crates/core_simd/src/masks/bitmask.rs
+++ b/crates/core_simd/src/masks/bitmask.rs
@@ -119,7 +119,6 @@ where
         unsafe { Self(intrinsics::simd_bitmask(value), PhantomData) }
     }
 
-    #[cfg(feature = "generic_const_exprs")]
     #[inline]
     #[must_use = "method returns a new array and does not mutate the original value"]
     pub fn to_bitmask_array<const N: usize>(self) -> [u8; N] {
@@ -129,7 +128,6 @@ where
         unsafe { core::mem::transmute_copy(&self.0) }
     }
 
-    #[cfg(feature = "generic_const_exprs")]
     #[inline]
     #[must_use = "method returns a new mask and does not mutate the original value"]
     pub fn from_bitmask_array<const N: usize>(bitmask: [u8; N]) -> Self {
diff --git a/crates/core_simd/src/masks/full_masks.rs b/crates/core_simd/src/masks/full_masks.rs
index 1d13c45b8e7..4b36adece71 100644
--- a/crates/core_simd/src/masks/full_masks.rs
+++ b/crates/core_simd/src/masks/full_masks.rs
@@ -1,12 +1,9 @@
 //! Masks that take up full SIMD vector registers.
 
-use super::MaskElement;
+use super::{to_bitmask::ToBitMaskArray, MaskElement};
 use crate::simd::intrinsics;
 use crate::simd::{LaneCount, Simd, SupportedLaneCount, ToBitMask};
 
-#[cfg(feature = "generic_const_exprs")]
-use crate::simd::ToBitMaskArray;
-
 #[repr(transparent)]
 pub struct Mask<T, const LANES: usize>(Simd<T, LANES>)
 where
@@ -145,23 +142,19 @@ where
         unsafe { Mask(intrinsics::simd_cast(self.0)) }
     }
 
-    #[cfg(feature = "generic_const_exprs")]
     #[inline]
     #[must_use = "method returns a new array and does not mutate the original value"]
     pub fn to_bitmask_array<const N: usize>(self) -> [u8; N]
     where
         super::Mask<T, LANES>: ToBitMaskArray,
-        [(); <super::Mask<T, LANES> as ToBitMaskArray>::BYTES]: Sized,
     {
-        assert_eq!(<super::Mask<T, LANES> as ToBitMaskArray>::BYTES, N);
-
-        // Safety: N is the correct bitmask size
+        // Safety: Bytes is the right size array
         unsafe {
             // Compute the bitmask
-            let bitmask: [u8; <super::Mask<T, LANES> as ToBitMaskArray>::BYTES] =
+            let bitmask: <super::Mask<T, LANES> as ToBitMaskArray>::BitMaskArray =
                 intrinsics::simd_bitmask(self.0);
 
-            // Transmute to the return type, previously asserted to be the same size
+            // Transmute to the return type
             let mut bitmask: [u8; N] = core::mem::transmute_copy(&bitmask);
 
             // LLVM assumes bit order should match endianness
@@ -175,17 +168,13 @@ where
         }
     }
 
-    #[cfg(feature = "generic_const_exprs")]
     #[inline]
     #[must_use = "method returns a new mask and does not mutate the original value"]
     pub fn from_bitmask_array<const N: usize>(mut bitmask: [u8; N]) -> Self
     where
         super::Mask<T, LANES>: ToBitMaskArray,
-        [(); <super::Mask<T, LANES> as ToBitMaskArray>::BYTES]: Sized,
     {
-        assert_eq!(<super::Mask<T, LANES> as ToBitMaskArray>::BYTES, N);
-
-        // Safety: N is the correct bitmask size
+        // Safety: Bytes is the right size array
         unsafe {
             // LLVM assumes bit order should match endianness
             if cfg!(target_endian = "big") {
@@ -194,8 +183,8 @@ where
                 }
             }
 
-            // Transmute to the bitmask type, previously asserted to be the same size
-            let bitmask: [u8; <super::Mask<T, LANES> as ToBitMaskArray>::BYTES] =
+            // Transmute to the bitmask
+            let bitmask: <super::Mask<T, LANES> as ToBitMaskArray>::BitMaskArray =
                 core::mem::transmute_copy(&bitmask);
 
             // Compute the regular mask
diff --git a/crates/core_simd/src/masks/to_bitmask.rs b/crates/core_simd/src/masks/to_bitmask.rs
index 8e724c9de8c..7041d15164d 100644
--- a/crates/core_simd/src/masks/to_bitmask.rs
+++ b/crates/core_simd/src/masks/to_bitmask.rs
@@ -30,19 +30,18 @@ pub trait ToBitMask: Sealed {
 /// Converts masks to and from byte array bitmasks.
 ///
 /// Each bit of the bitmask corresponds to a mask lane, starting with the LSB of the first byte.
-#[cfg(feature = "generic_const_exprs")]
 pub trait ToBitMaskArray: Sealed {
-    /// The length of the bitmask array.
-    const BYTES: usize;
+    /// The bitmask array.
+    type BitMaskArray;
 
     /// Converts a mask to a bitmask.
-    fn to_bitmask_array(self) -> [u8; Self::BYTES];
+    fn to_bitmask_array(self) -> Self::BitMaskArray;
 
     /// Converts a bitmask to a mask.
-    fn from_bitmask_array(bitmask: [u8; Self::BYTES]) -> Self;
+    fn from_bitmask_array(bitmask: Self::BitMaskArray) -> Self;
 }
 
-macro_rules! impl_integer_intrinsic {
+macro_rules! impl_integer {
     { $(impl ToBitMask<BitMask=$int:ty> for Mask<_, $lanes:literal>)* } => {
         $(
         impl<T: MaskElement> ToBitMask for Mask<T, $lanes> {
@@ -62,7 +61,27 @@ macro_rules! impl_integer_intrinsic {
     }
 }
 
-impl_integer_intrinsic! {
+macro_rules! impl_array {
+    { $(impl ToBitMaskArray<Bytes=$int:literal> for Mask<_, $lanes:literal>)* } => {
+        $(
+        impl<T: MaskElement> ToBitMaskArray for Mask<T, $lanes> {
+            type BitMaskArray = [u8; $int];
+
+            #[inline]
+            fn to_bitmask_array(self) -> Self::BitMaskArray {
+                self.0.to_bitmask_array()
+            }
+
+            #[inline]
+            fn from_bitmask_array(bitmask: Self::BitMaskArray) -> Self {
+                Self(mask_impl::Mask::from_bitmask_array(bitmask))
+            }
+        }
+        )*
+    }
+}
+
+impl_integer! {
     impl ToBitMask<BitMask=u8> for Mask<_, 1>
     impl ToBitMask<BitMask=u8> for Mask<_, 2>
     impl ToBitMask<BitMask=u8> for Mask<_, 4>
@@ -72,27 +91,12 @@ impl_integer_intrinsic! {
     impl ToBitMask<BitMask=u64> for Mask<_, 64>
 }
 
-/// Returns the minimum number of bytes in a bitmask with `lanes` lanes.
-#[cfg(feature = "generic_const_exprs")]
-#[allow(clippy::missing_inline_in_public_items)]
-pub const fn bitmask_len(lanes: usize) -> usize {
-    (lanes + 7) / 8
-}
-
-#[cfg(feature = "generic_const_exprs")]
-impl<T: MaskElement, const LANES: usize> ToBitMaskArray for Mask<T, LANES>
-where
-    LaneCount<LANES>: SupportedLaneCount,
-{
-    const BYTES: usize = bitmask_len(LANES);
-
-    #[inline]
-    fn to_bitmask_array(self) -> [u8; Self::BYTES] {
-        self.0.to_bitmask_array()
-    }
-
-    #[inline]
-    fn from_bitmask_array(bitmask: [u8; Self::BYTES]) -> Self {
-        Mask(mask_impl::Mask::from_bitmask_array(bitmask))
-    }
+impl_array! {
+    impl ToBitMaskArray<Bytes=1> for Mask<_, 1>
+    impl ToBitMaskArray<Bytes=1> for Mask<_, 2>
+    impl ToBitMaskArray<Bytes=1> for Mask<_, 4>
+    impl ToBitMaskArray<Bytes=1> for Mask<_, 8>
+    impl ToBitMaskArray<Bytes=2> for Mask<_, 16>
+    impl ToBitMaskArray<Bytes=4> for Mask<_, 32>
+    impl ToBitMaskArray<Bytes=8> for Mask<_, 64>
 }
diff --git a/crates/core_simd/src/mod.rs b/crates/core_simd/src/mod.rs
index dd954b7cc48..f489ae36de4 100644
--- a/crates/core_simd/src/mod.rs
+++ b/crates/core_simd/src/mod.rs
@@ -3,9 +3,6 @@ mod swizzle;
 
 pub(crate) mod intrinsics;
 
-#[cfg(feature = "generic_const_exprs")]
-mod to_bytes;
-
 mod alias;
 mod cast;
 mod elements;
@@ -18,6 +15,7 @@ mod ops;
 mod ord;
 mod select;
 mod swizzle_dyn;
+mod to_bytes;
 mod vector;
 mod vendor;
 
@@ -37,5 +35,6 @@ pub mod simd {
     pub use crate::core_simd::ord::*;
     pub use crate::core_simd::swizzle::*;
     pub use crate::core_simd::swizzle_dyn::*;
+    pub use crate::core_simd::to_bytes::ToBytes;
     pub use crate::core_simd::vector::*;
 }
diff --git a/crates/core_simd/src/to_bytes.rs b/crates/core_simd/src/to_bytes.rs
index 5f1374fd5a5..5fe4a77d50d 100644
--- a/crates/core_simd/src/to_bytes.rs
+++ b/crates/core_simd/src/to_bytes.rs
@@ -1,72 +1,126 @@
-use crate::simd::SimdUint;
+use crate::simd::{LaneCount, Simd, SimdElement, SimdFloat, SimdInt, SimdUint, SupportedLaneCount};
+
+mod sealed {
+    use super::*;
+    pub trait Sealed {}
+    impl<T: SimdElement, const N: usize> Sealed for Simd<T, N> where LaneCount<N>: SupportedLaneCount {}
+}
+use sealed::Sealed;
+
+/// Convert SIMD vectors to vectors of bytes
+pub trait ToBytes: Sealed {
+    /// This type, reinterpreted as bytes.
+    type Bytes;
+
+    /// Return the memory representation of this integer as a byte array in native byte
+    /// order.
+    fn to_ne_bytes(self) -> Self::Bytes;
+
+    /// Return the memory representation of this integer as a byte array in big-endian
+    /// (network) byte order.
+    fn to_be_bytes(self) -> Self::Bytes;
+
+    /// Return the memory representation of this integer as a byte array in little-endian
+    /// byte order.
+    fn to_le_bytes(self) -> Self::Bytes;
+
+    /// Create a native endian integer value from its memory representation as a byte array
+    /// in native endianness.
+    fn from_ne_bytes(bytes: Self::Bytes) -> Self;
+
+    /// Create an integer value from its representation as a byte array in big endian.
+    fn from_be_bytes(bytes: Self::Bytes) -> Self;
+
+    /// Create an integer value from its representation as a byte array in little endian.
+    fn from_le_bytes(bytes: Self::Bytes) -> Self;
+}
+
+macro_rules! swap_bytes {
+    { f32, $x:expr } => { Simd::from_bits($x.to_bits().swap_bytes()) };
+    { f64, $x:expr } => { Simd::from_bits($x.to_bits().swap_bytes()) };
+    { $ty:ty, $x:expr } => { $x.swap_bytes() }
+}
 
 macro_rules! impl_to_bytes {
-    { $ty:ty, $size:literal } => {
-        impl<const LANES: usize> crate::simd::Simd<$ty, LANES>
-        where
-            crate::simd::LaneCount<LANES>: crate::simd::SupportedLaneCount,
-            crate::simd::LaneCount<{{ $size * LANES }}>: crate::simd::SupportedLaneCount,
-        {
-            /// Return the memory representation of this integer as a byte array in native byte
-            /// order.
+    { $ty:tt, $size:tt } => {
+        impl_to_bytes! { $ty, $size * 1 }
+        impl_to_bytes! { $ty, $size * 2 }
+        impl_to_bytes! { $ty, $size * 4 }
+        impl_to_bytes! { $ty, $size * 8 }
+        impl_to_bytes! { $ty, $size * 16 }
+        impl_to_bytes! { $ty, $size * 32 }
+        impl_to_bytes! { $ty, $size * 64 }
+    };
+
+    // multiply element size by number of elements
+    { $ty:tt, 1 * $elems:literal } => { impl_to_bytes! { @impl [$ty; $elems], $elems } };
+    { $ty:tt, $size:literal * 1 } => { impl_to_bytes! { @impl [$ty; 1], $size } };
+    { $ty:tt, 2 * 2  } => { impl_to_bytes! { @impl [$ty; 2], 4  } };
+    { $ty:tt, 2 * 4  } => { impl_to_bytes! { @impl [$ty; 4], 8  } };
+    { $ty:tt, 2 * 8  } => { impl_to_bytes! { @impl [$ty; 8], 16 } };
+    { $ty:tt, 2 * 16 } => { impl_to_bytes! { @impl [$ty; 16], 32 } };
+    { $ty:tt, 2 * 32 } => { impl_to_bytes! { @impl [$ty; 32], 64 } };
+    { $ty:tt, 4 * 2  } => { impl_to_bytes! { @impl [$ty; 2], 8  } };
+    { $ty:tt, 4 * 4  } => { impl_to_bytes! { @impl [$ty; 4], 16 } };
+    { $ty:tt, 4 * 8  } => { impl_to_bytes! { @impl [$ty; 8], 32 } };
+    { $ty:tt, 4 * 16 } => { impl_to_bytes! { @impl [$ty; 16], 64 } };
+    { $ty:tt, 8 * 2  } => { impl_to_bytes! { @impl [$ty; 2], 16 } };
+    { $ty:tt, 8 * 4  } => { impl_to_bytes! { @impl [$ty; 4], 32 } };
+    { $ty:tt, 8 * 8  } => { impl_to_bytes! { @impl [$ty; 8], 64 } };
+
+    // unsupported number of lanes
+    { $ty:ty, $a:literal * $b:literal } => { };
+
+    { @impl [$ty:tt; $elem:literal], $bytes:literal } => {
+        impl ToBytes for Simd<$ty, $elem> {
+            type Bytes = Simd<u8, $bytes>;
+
             #[inline]
-            pub fn to_ne_bytes(self) -> crate::simd::Simd<u8, {{ $size * LANES }}> {
+            fn to_ne_bytes(self) -> Self::Bytes {
                 // Safety: transmuting between vectors is safe
-                unsafe { core::mem::transmute_copy(&self) }
+                unsafe { core::mem::transmute(self) }
             }
 
-            /// Return the memory representation of this integer as a byte array in big-endian
-            /// (network) byte order.
             #[inline]
-            pub fn to_be_bytes(self) -> crate::simd::Simd<u8, {{ $size * LANES }}> {
-                let bytes = self.to_ne_bytes();
-                if cfg!(target_endian = "big") {
-                    bytes
-                } else {
-                    bytes.swap_bytes()
+            fn to_be_bytes(mut self) -> Self::Bytes {
+                if !cfg!(target_endian = "big") {
+                    self = swap_bytes!($ty, self);
                 }
+                self.to_ne_bytes()
             }
 
-            /// Return the memory representation of this integer as a byte array in little-endian
-            /// byte order.
             #[inline]
-            pub fn to_le_bytes(self) -> crate::simd::Simd<u8, {{ $size * LANES }}> {
-                let bytes = self.to_ne_bytes();
-                if cfg!(target_endian = "little") {
-                    bytes
-                } else {
-                    bytes.swap_bytes()
+            fn to_le_bytes(mut self) -> Self::Bytes {
+                if !cfg!(target_endian = "little") {
+                    self = swap_bytes!($ty, self);
                 }
+                self.to_ne_bytes()
             }
 
-            /// Create a native endian integer value from its memory representation as a byte array
-            /// in native endianness.
             #[inline]
-            pub fn from_ne_bytes(bytes: crate::simd::Simd<u8, {{ $size * LANES }}>) -> Self {
+            fn from_ne_bytes(bytes: Self::Bytes) -> Self {
                 // Safety: transmuting between vectors is safe
-                unsafe { core::mem::transmute_copy(&bytes) }
+                unsafe { core::mem::transmute(bytes) }
             }
 
-            /// Create an integer value from its representation as a byte array in big endian.
             #[inline]
-            pub fn from_be_bytes(bytes: crate::simd::Simd<u8, {{ $size * LANES }}>) -> Self {
-                let bytes = if cfg!(target_endian = "big") {
-                    bytes
+            fn from_be_bytes(bytes: Self::Bytes) -> Self {
+                let ret = Self::from_ne_bytes(bytes);
+                if cfg!(target_endian = "big") {
+                    ret
                 } else {
-                    bytes.swap_bytes()
-                };
-                Self::from_ne_bytes(bytes)
+                    swap_bytes!($ty, ret)
+                }
             }
 
-            /// Create an integer value from its representation as a byte array in little endian.
             #[inline]
-            pub fn from_le_bytes(bytes: crate::simd::Simd<u8, {{ $size * LANES }}>) -> Self {
-                let bytes = if cfg!(target_endian = "little") {
-                    bytes
+            fn from_le_bytes(bytes: Self::Bytes) -> Self {
+                let ret = Self::from_ne_bytes(bytes);
+                if cfg!(target_endian = "little") {
+                    ret
                 } else {
-                    bytes.swap_bytes()
-                };
-                Self::from_ne_bytes(bytes)
+                    swap_bytes!($ty, ret)
+                }
             }
         }
     }
@@ -89,3 +143,6 @@ impl_to_bytes! { i64, 8 }
 impl_to_bytes! { isize, 4 }
 #[cfg(target_pointer_width = "64")]
 impl_to_bytes! { isize, 8 }
+
+impl_to_bytes! { f32, 4 }
+impl_to_bytes! { f64, 8 }
diff --git a/crates/core_simd/tests/masks.rs b/crates/core_simd/tests/masks.rs
index 9f8bad1c36c..7c1d4c7dd3f 100644
--- a/crates/core_simd/tests/masks.rs
+++ b/crates/core_simd/tests/masks.rs
@@ -125,7 +125,6 @@ macro_rules! test_mask_api {
                 cast_impl::<isize>();
             }
 
-            #[cfg(feature = "generic_const_exprs")]
             #[test]
             fn roundtrip_bitmask_array_conversion() {
                 use core_simd::simd::ToBitMaskArray;
diff --git a/crates/core_simd/tests/to_bytes.rs b/crates/core_simd/tests/to_bytes.rs
index 7dd740d65dd..66a7981cdc3 100644
--- a/crates/core_simd/tests/to_bytes.rs
+++ b/crates/core_simd/tests/to_bytes.rs
@@ -1,8 +1,6 @@
-#![feature(portable_simd, generic_const_exprs, adt_const_params)]
-#![allow(incomplete_features)]
-#![cfg(feature = "generic_const_exprs")]
+#![feature(portable_simd)]
 
-use core_simd::simd::Simd;
+use core_simd::simd::{Simd, ToBytes};
 
 #[test]
 fn byte_convert() {