about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCaleb Zulawski <caleb.zulawski@gmail.com>2023-10-20 19:10:50 -0400
committerGitHub <noreply@github.com>2023-10-20 19:10:50 -0400
commit3e4e13c82f8d1e56b3a2a9baf4911a7709e4db95 (patch)
treea1322ccc173d8427687e79314293dcb70cea3517
parentd21ba251a11bb3eb2e57d1d8d7fedbc99d698529 (diff)
parentafe28b13e73da85c3b8e711e24dc709829a142b9 (diff)
downloadrust-3e4e13c82f8d1e56b3a2a9baf4911a7709e4db95.tar.gz
rust-3e4e13c82f8d1e56b3a2a9baf4911a7709e4db95.zip
Merge pull request #368 from rust-lang/remove-generic-const-exprs
Remove `generic_const_exprs`
-rw-r--r--.github/workflows/ci.yml12
-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.rs73
-rw-r--r--crates/core_simd/src/mod.rs5
-rw-r--r--crates/core_simd/src/to_bytes.rs135
-rw-r--r--crates/core_simd/tests/masks.rs1
-rw-r--r--crates/core_simd/tests/to_bytes.rs6
11 files changed, 149 insertions, 118 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ed1589be4f1..90543044ea8 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -238,7 +238,7 @@ jobs:
         run: cross test --verbose --target=${{ matrix.target }} --release
 
   features:
-    name: "Check cargo features (${{ matrix.simd }} × ${{ matrix.features }})"
+    name: "Test cargo features (${{ matrix.simd }} × ${{ matrix.features }})"
     runs-on: ubuntu-latest
     strategy:
       fail-fast: false
@@ -249,12 +249,8 @@ jobs:
         features:
           - ""
           - "--features std"
-          - "--features generic_const_exprs"
-          - "--features std --features generic_const_exprs"
           - "--features all_lane_counts"
-          - "--features all_lane_counts --features std"
-          - "--features all_lane_counts --features generic_const_exprs"
-          - "--features all_lane_counts --features std --features generic_const_exprs"
+          - "--all-features"
 
     steps:
       - uses: actions/checkout@v2
@@ -266,9 +262,9 @@ jobs:
         run: echo "CPU_FEATURE=$(lscpu | grep -o avx512[a-z]* | sed s/avx/+avx/ | tr '\n' ',' )" >> $GITHUB_ENV
       - name: Check build
         if: ${{ matrix.simd == '' }}
-        run: RUSTFLAGS="-Dwarnings" cargo check --all-targets --no-default-features ${{ matrix.features }}
+        run: RUSTFLAGS="-Dwarnings" cargo test --all-targets --no-default-features ${{ matrix.features }}
       - name: Check AVX
         if: ${{ matrix.simd == 'avx512' && contains(env.CPU_FEATURE, 'avx512') }}
         run: |
           echo "Found AVX features: $CPU_FEATURE"
-          RUSTFLAGS="-Dwarnings -Ctarget-feature=$CPU_FEATURE" cargo check --all-targets --no-default-features ${{ matrix.features }}
+          RUSTFLAGS="-Dwarnings -Ctarget-feature=$CPU_FEATURE" cargo test --all-targets --no-default-features ${{ matrix.features }}
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 e04448a50be..13ae5088fb9 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..12cb1771ce1 100644
--- a/crates/core_simd/src/masks/to_bitmask.rs
+++ b/crates/core_simd/src/masks/to_bitmask.rs
@@ -1,5 +1,6 @@
 use super::{mask_impl, Mask, MaskElement};
 use crate::simd::{LaneCount, SupportedLaneCount};
+use core::borrow::{Borrow, BorrowMut};
 
 mod sealed {
     pub trait Sealed {}
@@ -30,19 +31,26 @@ 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: Copy
+        + Unpin
+        + Send
+        + Sync
+        + AsRef<[u8]>
+        + AsMut<[u8]>
+        + Borrow<[u8]>
+        + BorrowMut<[u8]>
+        + 'static;
 
     /// 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 +70,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 +100,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..3c93fe47404 100644
--- a/crates/core_simd/src/to_bytes.rs
+++ b/crates/core_simd/src/to_bytes.rs
@@ -1,74 +1,116 @@
-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: Copy
+        + Unpin
+        + Send
+        + Sync
+        + AsRef<[u8]>
+        + AsMut<[u8]>
+        + SimdUint<Scalar = u8>
+        + 'static;
+
+    /// 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, 1  } => { impl_to_bytes! { $ty, 1  * [1, 2, 4, 8, 16, 32, 64] } };
+    { $ty:tt, 2  } => { impl_to_bytes! { $ty, 2  * [1, 2, 4, 8, 16, 32] } };
+    { $ty:tt, 4  } => { impl_to_bytes! { $ty, 4  * [1, 2, 4, 8, 16] } };
+    { $ty:tt, 8  } => { impl_to_bytes! { $ty, 8  * [1, 2, 4, 8] } };
+    { $ty:tt, 16 } => { impl_to_bytes! { $ty, 16 * [1, 2, 4] } };
+    { $ty:tt, 32 } => { impl_to_bytes! { $ty, 32 * [1, 2] } };
+    { $ty:tt, 64 } => { impl_to_bytes! { $ty, 64 * [1] } };
+
+    { $ty:tt, $size:literal * [$($elems:literal),*] } => {
+        $(
+        impl ToBytes for Simd<$ty, $elems> {
+            type Bytes = Simd<u8, { $size * $elems }>;
+
             #[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 +131,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() {