From 2c9e4524f2da2fa377289d5e6d74a11afcf0e1f5 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Fri, 7 Nov 2025 01:03:17 -0500 Subject: [PATCH] Use generic trait parameters to minimize associated types --- crates/core_simd/src/simd/cmp/eq.rs | 46 ++++----- crates/core_simd/src/simd/cmp/ord.rs | 78 ++++++++------- crates/core_simd/src/simd/num/float.rs | 109 +++++++++------------ crates/core_simd/src/simd/num/int.rs | 105 +++++++++----------- crates/core_simd/src/simd/num/uint.rs | 53 +++++----- crates/core_simd/src/simd/ptr/const_ptr.rs | 69 +++++-------- crates/core_simd/src/simd/ptr/mut_ptr.rs | 69 +++++-------- crates/core_simd/src/to_bytes.rs | 9 +- 8 files changed, 230 insertions(+), 308 deletions(-) diff --git a/crates/core_simd/src/simd/cmp/eq.rs b/crates/core_simd/src/simd/cmp/eq.rs index d553d6c040c..3034fcb95fc 100644 --- a/crates/core_simd/src/simd/cmp/eq.rs +++ b/crates/core_simd/src/simd/cmp/eq.rs @@ -4,35 +4,32 @@ use crate::simd::{ }; /// Parallel `PartialEq`. -pub trait SimdPartialEq { - /// The mask type returned by each comparison. - type Mask; - +pub trait SimdPartialEq +where + T: SimdElement, +{ /// Test if each element is equal to the corresponding element in `other`. #[must_use = "method returns a new mask and does not mutate the original value"] - fn simd_eq(self, other: Self) -> Self::Mask; + fn simd_eq(self, other: Self) -> Mask<::Mask, N>; /// Test if each element is not equal to the corresponding element in `other`. #[must_use = "method returns a new mask and does not mutate the original value"] - fn simd_ne(self, other: Self) -> Self::Mask; + fn simd_ne(self, other: Self) -> Mask<::Mask, N>; } macro_rules! impl_number { { $($number:ty),* } => { $( - impl SimdPartialEq for Simd<$number, N> - { - type Mask = Mask<<$number as SimdElement>::Mask, N>; - + impl SimdPartialEq<$number, N> for Simd<$number, N> { #[inline] - fn simd_eq(self, other: Self) -> Self::Mask { + fn simd_eq(self, other: Self) -> Mask<<$number as SimdElement>::Mask, N> { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_eq(self, other)) } } #[inline] - fn simd_ne(self, other: Self) -> Self::Mask { + fn simd_ne(self, other: Self) -> Mask<<$number as SimdElement>::Mask, N> { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_ne(self, other)) } @@ -47,19 +44,16 @@ impl_number! { f32, f64, u8, u16, u32, u64, usize, i8, i16, i32, i64, isize } macro_rules! impl_mask { { $($integer:ty),* } => { $( - impl SimdPartialEq for Mask<$integer, N> - { - type Mask = Self; - + impl SimdPartialEq<$integer, N> for Mask<$integer, N> { #[inline] - fn simd_eq(self, other: Self) -> Self::Mask { + fn simd_eq(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_eq(self.to_simd(), other.to_simd())) } } #[inline] - fn simd_ne(self, other: Self) -> Self::Mask { + fn simd_ne(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_ne(self.to_simd(), other.to_simd())) } @@ -71,30 +65,26 @@ macro_rules! impl_mask { impl_mask! { i8, i16, i32, i64, isize } -impl SimdPartialEq for Simd<*const T, N> { - type Mask = Mask; - +impl SimdPartialEq<*const T, N> for Simd<*const T, N> { #[inline] - fn simd_eq(self, other: Self) -> Self::Mask { + fn simd_eq(self, other: Self) -> Mask { self.addr().simd_eq(other.addr()) } #[inline] - fn simd_ne(self, other: Self) -> Self::Mask { + fn simd_ne(self, other: Self) -> Mask { self.addr().simd_ne(other.addr()) } } -impl SimdPartialEq for Simd<*mut T, N> { - type Mask = Mask; - +impl SimdPartialEq<*mut T, N> for Simd<*mut T, N> { #[inline] - fn simd_eq(self, other: Self) -> Self::Mask { + fn simd_eq(self, other: Self) -> Mask { self.addr().simd_eq(other.addr()) } #[inline] - fn simd_ne(self, other: Self) -> Self::Mask { + fn simd_ne(self, other: Self) -> Mask { self.addr().simd_ne(other.addr()) } } diff --git a/crates/core_simd/src/simd/cmp/ord.rs b/crates/core_simd/src/simd/cmp/ord.rs index 5672fbbf54c..aa239f1a1b1 100644 --- a/crates/core_simd/src/simd/cmp/ord.rs +++ b/crates/core_simd/src/simd/cmp/ord.rs @@ -1,30 +1,36 @@ use crate::simd::{ - Mask, Select, Simd, + Mask, Select, Simd, SimdElement, cmp::SimdPartialEq, ptr::{SimdConstPtr, SimdMutPtr}, }; /// Parallel `PartialOrd`. -pub trait SimdPartialOrd: SimdPartialEq { +pub trait SimdPartialOrd: SimdPartialEq +where + T: SimdElement, +{ /// Test if each element is less than the corresponding element in `other`. #[must_use = "method returns a new mask and does not mutate the original value"] - fn simd_lt(self, other: Self) -> Self::Mask; + fn simd_lt(self, other: Self) -> Mask<::Mask, N>; /// Test if each element is less than or equal to the corresponding element in `other`. #[must_use = "method returns a new mask and does not mutate the original value"] - fn simd_le(self, other: Self) -> Self::Mask; + fn simd_le(self, other: Self) -> Mask<::Mask, N>; /// Test if each element is greater than the corresponding element in `other`. #[must_use = "method returns a new mask and does not mutate the original value"] - fn simd_gt(self, other: Self) -> Self::Mask; + fn simd_gt(self, other: Self) -> Mask<::Mask, N>; /// Test if each element is greater than or equal to the corresponding element in `other`. #[must_use = "method returns a new mask and does not mutate the original value"] - fn simd_ge(self, other: Self) -> Self::Mask; + fn simd_ge(self, other: Self) -> Mask<::Mask, N>; } /// Parallel `Ord`. -pub trait SimdOrd: SimdPartialOrd { +pub trait SimdOrd: SimdPartialOrd +where + T: SimdElement, +{ /// Returns the element-wise maximum with `other`. #[must_use = "method returns a new vector and does not mutate the original value"] fn simd_max(self, other: Self) -> Self; @@ -48,38 +54,38 @@ pub trait SimdOrd: SimdPartialOrd { macro_rules! impl_integer { { $($integer:ty),* } => { $( - impl SimdPartialOrd for Simd<$integer, N> + impl SimdPartialOrd<$integer, N> for Simd<$integer, N> { #[inline] - fn simd_lt(self, other: Self) -> Self::Mask { + fn simd_lt(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_lt(self, other)) } } #[inline] - fn simd_le(self, other: Self) -> Self::Mask { + fn simd_le(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_le(self, other)) } } #[inline] - fn simd_gt(self, other: Self) -> Self::Mask { + fn simd_gt(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_gt(self, other)) } } #[inline] - fn simd_ge(self, other: Self) -> Self::Mask { + fn simd_ge(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_ge(self, other)) } } } - impl SimdOrd for Simd<$integer, N> + impl SimdOrd<$integer, N> for Simd<$integer, N> { #[inline] fn simd_max(self, other: Self) -> Self { @@ -110,31 +116,31 @@ impl_integer! { u8, u16, u32, u64, usize, i8, i16, i32, i64, isize } macro_rules! impl_float { { $($float:ty),* } => { $( - impl SimdPartialOrd for Simd<$float, N> + impl SimdPartialOrd<$float, N> for Simd<$float, N> { #[inline] - fn simd_lt(self, other: Self) -> Self::Mask { + fn simd_lt(self, other: Self) -> Mask<<$float as SimdElement>::Mask, N> { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_lt(self, other)) } } #[inline] - fn simd_le(self, other: Self) -> Self::Mask { + fn simd_le(self, other: Self) -> Mask<<$float as SimdElement>::Mask, N> { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_le(self, other)) } } #[inline] - fn simd_gt(self, other: Self) -> Self::Mask { + fn simd_gt(self, other: Self) -> Mask<<$float as SimdElement>::Mask, N> { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_gt(self, other)) } } #[inline] - fn simd_ge(self, other: Self) -> Self::Mask { + fn simd_ge(self, other: Self) -> Mask<<$float as SimdElement>::Mask, N> { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_ge(self, other)) } @@ -149,38 +155,38 @@ impl_float! { f32, f64 } macro_rules! impl_mask { { $($integer:ty),* } => { $( - impl SimdPartialOrd for Mask<$integer, N> + impl SimdPartialOrd<$integer, N> for Mask<$integer, N> { #[inline] - fn simd_lt(self, other: Self) -> Self::Mask { + fn simd_lt(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_lt(self.to_simd(), other.to_simd())) } } #[inline] - fn simd_le(self, other: Self) -> Self::Mask { + fn simd_le(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_le(self.to_simd(), other.to_simd())) } } #[inline] - fn simd_gt(self, other: Self) -> Self::Mask { + fn simd_gt(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_gt(self.to_simd(), other.to_simd())) } } #[inline] - fn simd_ge(self, other: Self) -> Self::Mask { + fn simd_ge(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_ge(self.to_simd(), other.to_simd())) } } } - impl SimdOrd for Mask<$integer, N> + impl SimdOrd<$integer, N> for Mask<$integer, N> { #[inline] fn simd_max(self, other: Self) -> Self { @@ -208,29 +214,29 @@ macro_rules! impl_mask { impl_mask! { i8, i16, i32, i64, isize } -impl SimdPartialOrd for Simd<*const T, N> { +impl SimdPartialOrd<*const T, N> for Simd<*const T, N> { #[inline] - fn simd_lt(self, other: Self) -> Self::Mask { + fn simd_lt(self, other: Self) -> Mask { self.addr().simd_lt(other.addr()) } #[inline] - fn simd_le(self, other: Self) -> Self::Mask { + fn simd_le(self, other: Self) -> Mask { self.addr().simd_le(other.addr()) } #[inline] - fn simd_gt(self, other: Self) -> Self::Mask { + fn simd_gt(self, other: Self) -> Mask { self.addr().simd_gt(other.addr()) } #[inline] - fn simd_ge(self, other: Self) -> Self::Mask { + fn simd_ge(self, other: Self) -> Mask { self.addr().simd_ge(other.addr()) } } -impl SimdOrd for Simd<*const T, N> { +impl SimdOrd<*const T, N> for Simd<*const T, N> { #[inline] fn simd_max(self, other: Self) -> Self { self.simd_lt(other).select(other, self) @@ -252,29 +258,29 @@ impl SimdOrd for Simd<*const T, N> { } } -impl SimdPartialOrd for Simd<*mut T, N> { +impl SimdPartialOrd<*mut T, N> for Simd<*mut T, N> { #[inline] - fn simd_lt(self, other: Self) -> Self::Mask { + fn simd_lt(self, other: Self) -> Mask { self.addr().simd_lt(other.addr()) } #[inline] - fn simd_le(self, other: Self) -> Self::Mask { + fn simd_le(self, other: Self) -> Mask { self.addr().simd_le(other.addr()) } #[inline] - fn simd_gt(self, other: Self) -> Self::Mask { + fn simd_gt(self, other: Self) -> Mask { self.addr().simd_gt(other.addr()) } #[inline] - fn simd_ge(self, other: Self) -> Self::Mask { + fn simd_ge(self, other: Self) -> Mask { self.addr().simd_ge(other.addr()) } } -impl SimdOrd for Simd<*mut T, N> { +impl SimdOrd<*mut T, N> for Simd<*mut T, N> { #[inline] fn simd_max(self, other: Self) -> Self { self.simd_lt(other).select(other, self) diff --git a/crates/core_simd/src/simd/num/float.rs b/crates/core_simd/src/simd/num/float.rs index efd7c246951..12f651f02c3 100644 --- a/crates/core_simd/src/simd/num/float.rs +++ b/crates/core_simd/src/simd/num/float.rs @@ -5,19 +5,12 @@ use crate::simd::{ }; /// Operations on SIMD vectors of floats. -pub trait SimdFloat: Copy + Sealed { - /// Mask type used for manipulating this SIMD vector type. - type Mask; - - /// Scalar type contained by this SIMD vector type. - type Scalar; - +pub trait SimdFloat: Copy + Sealed +where + T: SimdElement, +{ /// Bit representation of this SIMD vector type. - type Bits; - - /// A SIMD vector with a different element type. - type Cast; - + type Bits: SimdElement; /// Performs elementwise conversion of this vector's elements to another SIMD-valid type. /// /// This follows the semantics of Rust's `as` conversion for floats (truncating or saturating @@ -42,7 +35,7 @@ pub trait SimdFloat: Copy + Sealed { /// assert_eq!(floats_again, Simd::from_array([1.0, -4.0, 2147483647.0, 0.0])); /// ``` #[must_use] - fn cast(self) -> Self::Cast; + fn cast(self) -> Simd; /// Rounds toward zero and converts to the same-width integer type, assuming that /// the value is finite and fits in that type. @@ -58,19 +51,19 @@ pub trait SimdFloat: Copy + Sealed { /// which saturates on conversion. /// /// [cast]: Simd::cast - unsafe fn to_int_unchecked(self) -> Self::Cast + unsafe fn to_int_unchecked(self) -> Simd where - Self::Scalar: core::convert::FloatToInt; + T: core::convert::FloatToInt; /// Raw transmutation to an unsigned integer vector type with the /// same size and number of elements. #[must_use = "method returns a new vector and does not mutate the original value"] - fn to_bits(self) -> Self::Bits; + fn to_bits(self) -> Simd; /// Raw transmutation from an unsigned integer vector type with the /// same size and number of elements. #[must_use = "method returns a new vector and does not mutate the original value"] - fn from_bits(bits: Self::Bits) -> Self; + fn from_bits(bits: Simd) -> Self; /// Produces a vector where every element has the absolute value of the /// equivalently-indexed element in `self`. @@ -92,33 +85,33 @@ pub trait SimdFloat: Copy + Sealed { /// Returns true for each element if it has a positive sign, including /// `+0.0`, `NaN`s with positive sign bit and positive infinity. #[must_use = "method returns a new mask and does not mutate the original value"] - fn is_sign_positive(self) -> Self::Mask; + fn is_sign_positive(self) -> Mask<::Mask, N>; /// Returns true for each element if it has a negative sign, including /// `-0.0`, `NaN`s with negative sign bit and negative infinity. #[must_use = "method returns a new mask and does not mutate the original value"] - fn is_sign_negative(self) -> Self::Mask; + fn is_sign_negative(self) -> Mask<::Mask, N>; /// Returns true for each element if its value is `NaN`. #[must_use = "method returns a new mask and does not mutate the original value"] - fn is_nan(self) -> Self::Mask; + fn is_nan(self) -> Mask<::Mask, N>; /// Returns true for each element if its value is positive infinity or negative infinity. #[must_use = "method returns a new mask and does not mutate the original value"] - fn is_infinite(self) -> Self::Mask; + fn is_infinite(self) -> Mask<::Mask, N>; /// Returns true for each element if its value is neither infinite nor `NaN`. #[must_use = "method returns a new mask and does not mutate the original value"] - fn is_finite(self) -> Self::Mask; + fn is_finite(self) -> Mask<::Mask, N>; /// Returns true for each element if its value is subnormal. #[must_use = "method returns a new mask and does not mutate the original value"] - fn is_subnormal(self) -> Self::Mask; + fn is_subnormal(self) -> Mask<::Mask, N>; /// Returns true for each element if its value is neither zero, infinite, /// subnormal, nor `NaN`. #[must_use = "method returns a new mask and does not mutate the original value"] - fn is_normal(self) -> Self::Mask; + fn is_normal(self) -> Mask<::Mask, N>; /// Replaces each element with a number that represents its sign. /// @@ -166,7 +159,7 @@ pub trait SimdFloat: Copy + Sealed { /// let v = f32x2::from_array([1., 2.]); /// assert_eq!(v.reduce_sum(), 3.); /// ``` - fn reduce_sum(self) -> Self::Scalar; + fn reduce_sum(self) -> T; /// Reducing multiply. Returns the product of the elements of the vector. /// @@ -180,7 +173,7 @@ pub trait SimdFloat: Copy + Sealed { /// let v = f32x2::from_array([3., 4.]); /// assert_eq!(v.reduce_product(), 12.); /// ``` - fn reduce_product(self) -> Self::Scalar; + fn reduce_product(self) -> T; /// Returns the maximum element in the vector. /// @@ -207,7 +200,7 @@ pub trait SimdFloat: Copy + Sealed { /// let v = f32x2::from_array([f32::NAN, f32::NAN]); /// assert!(v.reduce_max().is_nan()); /// ``` - fn reduce_max(self) -> Self::Scalar; + fn reduce_max(self) -> T; /// Returns the minimum element in the vector. /// @@ -234,7 +227,7 @@ pub trait SimdFloat: Copy + Sealed { /// let v = f32x2::from_array([f32::NAN, f32::NAN]); /// assert!(v.reduce_min().is_nan()); /// ``` - fn reduce_min(self) -> Self::Scalar; + fn reduce_min(self) -> T; } macro_rules! impl_trait { @@ -242,17 +235,12 @@ macro_rules! impl_trait { $( impl Sealed for Simd<$ty, N> {} - impl SimdFloat for Simd<$ty, N> - { - type Mask = Mask<<$mask_ty as SimdElement>::Mask, N>; - type Scalar = $ty; - type Bits = Simd<$bits_ty, N>; - type Cast = Simd; + impl SimdFloat<$ty, N> for Simd<$ty, N> { + type Bits = $bits_ty; #[cfg(not(target_arch = "aarch64"))] #[inline] - fn cast(self) -> Self::Cast - { + fn cast(self) -> Simd { // Safety: supported types are guaranteed by SimdCast unsafe { core::intrinsics::simd::simd_as(self) } } @@ -261,8 +249,7 @@ macro_rules! impl_trait { // tracked in: https://github.com/rust-lang/rust/issues/135982 #[cfg(target_arch = "aarch64")] #[inline] - fn cast(self) -> Self::Cast - { + fn cast(self) -> Simd { const { assert!(N <= 64) }; if N <= 2 || N == 4 || N == 8 || N == 16 || N == 32 || N == 64 { // Safety: supported types are guaranteed by SimdCast @@ -287,24 +274,24 @@ macro_rules! impl_trait { #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - unsafe fn to_int_unchecked(self) -> Self::Cast + unsafe fn to_int_unchecked(self) -> Simd where - Self::Scalar: core::convert::FloatToInt, + $ty: core::convert::FloatToInt, { // Safety: supported types are guaranteed by SimdCast, the caller is responsible for the extra invariants unsafe { core::intrinsics::simd::simd_cast(self) } } #[inline] - fn to_bits(self) -> Simd<$bits_ty, N> { - assert_eq!(size_of::(), size_of::()); + fn to_bits(self) -> Simd { + assert_eq!(size_of::(), size_of::>()); // Safety: transmuting between vector types is safe unsafe { core::mem::transmute_copy(&self) } } #[inline] - fn from_bits(bits: Simd<$bits_ty, N>) -> Self { - assert_eq!(size_of::(), size_of::()); + fn from_bits(bits: Simd) -> Self { + assert_eq!(size_of::(), size_of::>()); // Safety: transmuting between vector types is safe unsafe { core::mem::transmute_copy(&bits) } } @@ -323,56 +310,56 @@ macro_rules! impl_trait { #[inline] fn to_degrees(self) -> Self { // to_degrees uses a special constant for better precision, so extract that constant - self * Self::splat(Self::Scalar::to_degrees(1.)) + self * Self::splat(<$ty>::to_degrees(1.)) } #[inline] fn to_radians(self) -> Self { - self * Self::splat(Self::Scalar::to_radians(1.)) + self * Self::splat(<$ty>::to_radians(1.)) } #[inline] - fn is_sign_positive(self) -> Self::Mask { + fn is_sign_positive(self) -> Mask<<$mask_ty as SimdElement>::Mask, N> { !self.is_sign_negative() } #[inline] - fn is_sign_negative(self) -> Self::Mask { + fn is_sign_negative(self) -> Mask<<$mask_ty as SimdElement>::Mask, N> { let sign_bits = self.to_bits() & Simd::splat((!0 >> 1) + 1); sign_bits.simd_gt(Simd::splat(0)) } #[inline] - fn is_nan(self) -> Self::Mask { + fn is_nan(self) -> Mask<<$mask_ty as SimdElement>::Mask, N> { self.simd_ne(self) } #[inline] - fn is_infinite(self) -> Self::Mask { - self.abs().simd_eq(Self::splat(Self::Scalar::INFINITY)) + fn is_infinite(self) -> Mask<<$mask_ty as SimdElement>::Mask, N> { + self.abs().simd_eq(Self::splat(<$ty>::INFINITY)) } #[inline] - fn is_finite(self) -> Self::Mask { - self.abs().simd_lt(Self::splat(Self::Scalar::INFINITY)) + fn is_finite(self) -> Mask<<$mask_ty as SimdElement>::Mask, N> { + self.abs().simd_lt(Self::splat(<$ty>::INFINITY)) } #[inline] - fn is_subnormal(self) -> Self::Mask { + fn is_subnormal(self) -> Mask<<$mask_ty as SimdElement>::Mask, N> { // On some architectures (e.g. armv7 and some ppc) subnormals are flushed to zero, // so this comparison must be done with integers. let not_zero = self.abs().to_bits().simd_ne(Self::splat(0.0).to_bits()); - not_zero & (self.to_bits() & Self::splat(Self::Scalar::INFINITY).to_bits()).simd_eq(Simd::splat(0)) + not_zero & (self.to_bits() & Self::splat(<$ty>::INFINITY).to_bits()).simd_eq(Simd::splat(0)) } #[inline] - fn is_normal(self) -> Self::Mask { + fn is_normal(self) -> Mask<<$mask_ty as SimdElement>::Mask, N> { !(self.abs().simd_eq(Self::splat(0.0)) | self.is_nan() | self.is_subnormal() | self.is_infinite()) } #[inline] fn signum(self) -> Self { - self.is_nan().select(Self::splat(Self::Scalar::NAN), Self::splat(1.0).copysign(self)) + self.is_nan().select(Self::splat(<$ty>::NAN), Self::splat(1.0).copysign(self)) } #[inline] @@ -407,7 +394,7 @@ macro_rules! impl_trait { } #[inline] - fn reduce_sum(self) -> Self::Scalar { + fn reduce_sum(self) -> $ty { // LLVM sum is inaccurate on i586 if cfg!(all(target_arch = "x86", not(target_feature = "sse2"))) { self.as_array().iter().sum() @@ -418,7 +405,7 @@ macro_rules! impl_trait { } #[inline] - fn reduce_product(self) -> Self::Scalar { + fn reduce_product(self) -> $ty { // LLVM product is inaccurate on i586 if cfg!(all(target_arch = "x86", not(target_feature = "sse2"))) { self.as_array().iter().product() @@ -429,13 +416,13 @@ macro_rules! impl_trait { } #[inline] - fn reduce_max(self) -> Self::Scalar { + fn reduce_max(self) -> $ty { // Safety: `self` is a float vector unsafe { core::intrinsics::simd::simd_reduce_max(self) } } #[inline] - fn reduce_min(self) -> Self::Scalar { + fn reduce_min(self) -> $ty { // Safety: `self` is a float vector unsafe { core::intrinsics::simd::simd_reduce_min(self) } } diff --git a/crates/core_simd/src/simd/num/int.rs b/crates/core_simd/src/simd/num/int.rs index 6ebf0ba397c..86ae0dd033d 100644 --- a/crates/core_simd/src/simd/num/int.rs +++ b/crates/core_simd/src/simd/num/int.rs @@ -4,25 +4,19 @@ use crate::simd::{ }; /// Operations on SIMD vectors of signed integers. -pub trait SimdInt: Copy + Sealed { - /// Mask type used for manipulating this SIMD vector type. - type Mask; - - /// Scalar type contained by this SIMD vector type. - type Scalar; - - /// A SIMD vector of unsigned integers with the same element size. - type Unsigned; - - /// A SIMD vector with a different element type. - type Cast; +pub trait SimdInt: Copy + Sealed +where + T: SimdElement, +{ + /// Unsigned element type with the same width as `T`. + type Unsigned: SimdElement; /// Performs elementwise conversion of this vector's elements to another SIMD-valid type. /// /// This follows the semantics of Rust's `as` conversion for casting integers (wrapping to /// other integer types, and saturating to float types). #[must_use] - fn cast(self) -> Self::Cast; + fn cast(self) -> Simd; /// Lanewise saturating add. /// @@ -88,7 +82,7 @@ pub trait SimdInt: Copy + Sealed { /// let b = Simd::from_array([MAX, MIN, -80, -120]); /// assert_eq!(a.abs_diff(b), Simd::from_array([u32::MAX, u32::MAX, 180, 20])); /// ``` - fn abs_diff(self, second: Self) -> Self::Unsigned; + fn abs_diff(self, second: Self) -> Simd; /// Lanewise saturating absolute value, implemented in Rust. /// As abs(), except the MIN value becomes MAX instead of itself. @@ -127,10 +121,10 @@ pub trait SimdInt: Copy + Sealed { fn saturating_neg(self) -> Self; /// Returns true for each positive element and false if it is zero or negative. - fn is_positive(self) -> Self::Mask; + fn is_positive(self) -> Mask<::Mask, N>; /// Returns true for each negative element and false if it is zero or positive. - fn is_negative(self) -> Self::Mask; + fn is_negative(self) -> Mask<::Mask, N>; /// Returns numbers representing the sign of each element. /// * `0` if the number is zero @@ -154,7 +148,7 @@ pub trait SimdInt: Copy + Sealed { /// let v = i32x4::from_array([i32::MAX, 1, 0, 0]); /// assert_eq!(v.reduce_sum(), i32::MIN); /// ``` - fn reduce_sum(self) -> Self::Scalar; + fn reduce_sum(self) -> T; /// Returns the product of the elements of the vector, with wrapping multiplication. /// @@ -172,7 +166,7 @@ pub trait SimdInt: Copy + Sealed { /// let v = i32x4::from_array([i32::MAX, 2, 1, 1]); /// assert!(v.reduce_product() < i32::MAX); /// ``` - fn reduce_product(self) -> Self::Scalar; + fn reduce_product(self) -> T; /// Returns the maximum element in the vector. /// @@ -186,7 +180,7 @@ pub trait SimdInt: Copy + Sealed { /// let v = i32x4::from_array([1, 2, 3, 4]); /// assert_eq!(v.reduce_max(), 4); /// ``` - fn reduce_max(self) -> Self::Scalar; + fn reduce_max(self) -> T; /// Returns the minimum element in the vector. /// @@ -200,16 +194,16 @@ pub trait SimdInt: Copy + Sealed { /// let v = i32x4::from_array([1, 2, 3, 4]); /// assert_eq!(v.reduce_min(), 1); /// ``` - fn reduce_min(self) -> Self::Scalar; + fn reduce_min(self) -> T; /// Returns the cumulative bitwise "and" across the elements of the vector. - fn reduce_and(self) -> Self::Scalar; + fn reduce_and(self) -> T; /// Returns the cumulative bitwise "or" across the elements of the vector. - fn reduce_or(self) -> Self::Scalar; + fn reduce_or(self) -> T; /// Returns the cumulative bitwise "xor" across the elements of the vector. - fn reduce_xor(self) -> Self::Scalar; + fn reduce_xor(self) -> T; /// Reverses the byte order of each element. fn swap_bytes(self) -> Self; @@ -219,22 +213,22 @@ pub trait SimdInt: Copy + Sealed { fn reverse_bits(self) -> Self; /// Returns the number of ones in the binary representation of each element. - fn count_ones(self) -> Self::Unsigned; + fn count_ones(self) -> Simd; /// Returns the number of zeros in the binary representation of each element. - fn count_zeros(self) -> Self::Unsigned; + fn count_zeros(self) -> Simd; /// Returns the number of leading zeros in the binary representation of each element. - fn leading_zeros(self) -> Self::Unsigned; + fn leading_zeros(self) -> Simd; /// Returns the number of trailing zeros in the binary representation of each element. - fn trailing_zeros(self) -> Self::Unsigned; + fn trailing_zeros(self) -> Simd; /// Returns the number of leading ones in the binary representation of each element. - fn leading_ones(self) -> Self::Unsigned; + fn leading_ones(self) -> Simd; /// Returns the number of trailing ones in the binary representation of each element. - fn trailing_ones(self) -> Self::Unsigned; + fn trailing_ones(self) -> Simd; } macro_rules! impl_trait { @@ -242,14 +236,11 @@ macro_rules! impl_trait { $( impl Sealed for Simd<$ty, N> {} - impl SimdInt for Simd<$ty, N> { - type Mask = Mask<<$ty as SimdElement>::Mask, N>; - type Scalar = $ty; - type Unsigned = Simd<$unsigned, N>; - type Cast = Simd; + impl SimdInt<$ty, N> for Simd<$ty, N> { + type Unsigned = $unsigned; #[inline] - fn cast(self) -> Self::Cast { + fn cast(self) -> Simd { // Safety: supported types are guaranteed by SimdCast unsafe { core::intrinsics::simd::simd_as(self) } } @@ -274,7 +265,7 @@ macro_rules! impl_trait { } #[inline] - fn abs_diff(self, second: Self) -> Self::Unsigned { + fn abs_diff(self, second: Self) -> Simd { let max = self.simd_max(second); let min = self.simd_min(second); (max - min).cast() @@ -294,12 +285,12 @@ macro_rules! impl_trait { } #[inline] - fn is_positive(self) -> Self::Mask { + fn is_positive(self) -> Mask<<$ty as SimdElement>::Mask, N> { self.simd_gt(Self::splat(0)) } #[inline] - fn is_negative(self) -> Self::Mask { + fn is_negative(self) -> Mask<<$ty as SimdElement>::Mask, N> { self.simd_lt(Self::splat(0)) } @@ -312,43 +303,43 @@ macro_rules! impl_trait { } #[inline] - fn reduce_sum(self) -> Self::Scalar { + fn reduce_sum(self) -> $ty { // Safety: `self` is an integer vector unsafe { core::intrinsics::simd::simd_reduce_add_ordered(self, 0) } } #[inline] - fn reduce_product(self) -> Self::Scalar { + fn reduce_product(self) -> $ty { // Safety: `self` is an integer vector unsafe { core::intrinsics::simd::simd_reduce_mul_ordered(self, 1) } } #[inline] - fn reduce_max(self) -> Self::Scalar { + fn reduce_max(self) -> $ty { // Safety: `self` is an integer vector unsafe { core::intrinsics::simd::simd_reduce_max(self) } } #[inline] - fn reduce_min(self) -> Self::Scalar { + fn reduce_min(self) -> $ty { // Safety: `self` is an integer vector unsafe { core::intrinsics::simd::simd_reduce_min(self) } } #[inline] - fn reduce_and(self) -> Self::Scalar { + fn reduce_and(self) -> $ty { // Safety: `self` is an integer vector unsafe { core::intrinsics::simd::simd_reduce_and(self) } } #[inline] - fn reduce_or(self) -> Self::Scalar { + fn reduce_or(self) -> $ty { // Safety: `self` is an integer vector unsafe { core::intrinsics::simd::simd_reduce_or(self) } } #[inline] - fn reduce_xor(self) -> Self::Scalar { + fn reduce_xor(self) -> $ty { // Safety: `self` is an integer vector unsafe { core::intrinsics::simd::simd_reduce_xor(self) } } @@ -366,33 +357,33 @@ macro_rules! impl_trait { } #[inline] - fn count_ones(self) -> Self::Unsigned { - self.cast::<$unsigned>().count_ones() + fn count_ones(self) -> Simd { + self.cast::().count_ones() } #[inline] - fn count_zeros(self) -> Self::Unsigned { - self.cast::<$unsigned>().count_zeros() + fn count_zeros(self) -> Simd { + self.cast::().count_zeros() } #[inline] - fn leading_zeros(self) -> Self::Unsigned { - self.cast::<$unsigned>().leading_zeros() + fn leading_zeros(self) -> Simd { + self.cast::().leading_zeros() } #[inline] - fn trailing_zeros(self) -> Self::Unsigned { - self.cast::<$unsigned>().trailing_zeros() + fn trailing_zeros(self) -> Simd { + self.cast::().trailing_zeros() } #[inline] - fn leading_ones(self) -> Self::Unsigned { - self.cast::<$unsigned>().leading_ones() + fn leading_ones(self) -> Simd { + self.cast::().leading_ones() } #[inline] - fn trailing_ones(self) -> Self::Unsigned { - self.cast::<$unsigned>().trailing_ones() + fn trailing_ones(self) -> Simd { + self.cast::().trailing_ones() } } )* diff --git a/crates/core_simd/src/simd/num/uint.rs b/crates/core_simd/src/simd/num/uint.rs index f8a40f8ec56..32b1406d1a1 100644 --- a/crates/core_simd/src/simd/num/uint.rs +++ b/crates/core_simd/src/simd/num/uint.rs @@ -2,19 +2,18 @@ use super::sealed::Sealed; use crate::simd::{Simd, SimdCast, SimdElement, cmp::SimdOrd}; /// Operations on SIMD vectors of unsigned integers. -pub trait SimdUint: Copy + Sealed { - /// Scalar type contained by this SIMD vector type. - type Scalar; - - /// A SIMD vector with a different element type. - type Cast; - +pub trait SimdUint: Copy + Sealed +where + T: SimdElement, +{ + /// Signed element type with the same width as `T`. + type Signed: SimdElement; /// Performs elementwise conversion of this vector's elements to another SIMD-valid type. /// /// This follows the semantics of Rust's `as` conversion for casting integers (wrapping to /// other integer types, and saturating to float types). #[must_use] - fn cast(self) -> Self::Cast; + fn cast(self) -> Simd; /// Wrapping negation. /// @@ -74,25 +73,25 @@ pub trait SimdUint: Copy + Sealed { fn abs_diff(self, second: Self) -> Self; /// Returns the sum of the elements of the vector, with wrapping addition. - fn reduce_sum(self) -> Self::Scalar; + fn reduce_sum(self) -> T; /// Returns the product of the elements of the vector, with wrapping multiplication. - fn reduce_product(self) -> Self::Scalar; + fn reduce_product(self) -> T; /// Returns the maximum element in the vector. - fn reduce_max(self) -> Self::Scalar; + fn reduce_max(self) -> T; /// Returns the minimum element in the vector. - fn reduce_min(self) -> Self::Scalar; + fn reduce_min(self) -> T; /// Returns the cumulative bitwise "and" across the elements of the vector. - fn reduce_and(self) -> Self::Scalar; + fn reduce_and(self) -> T; /// Returns the cumulative bitwise "or" across the elements of the vector. - fn reduce_or(self) -> Self::Scalar; + fn reduce_or(self) -> T; /// Returns the cumulative bitwise "xor" across the elements of the vector. - fn reduce_xor(self) -> Self::Scalar; + fn reduce_xor(self) -> T; /// Reverses the byte order of each element. fn swap_bytes(self) -> Self; @@ -125,13 +124,11 @@ macro_rules! impl_trait { $( impl Sealed for Simd<$ty, N> {} - impl SimdUint for Simd<$ty, N> - { - type Scalar = $ty; - type Cast = Simd; + impl SimdUint<$ty, N> for Simd<$ty, N> { + type Signed = $signed; #[inline] - fn cast(self) -> Self::Cast { + fn cast(self) -> Simd { // Safety: supported types are guaranteed by SimdCast unsafe { core::intrinsics::simd::simd_as(self) } } @@ -139,7 +136,7 @@ macro_rules! impl_trait { #[inline] fn wrapping_neg(self) -> Self { use crate::simd::num::SimdInt; - (-self.cast::<$signed>()).cast() + (-self.cast::()).cast() } #[inline] @@ -162,43 +159,43 @@ macro_rules! impl_trait { } #[inline] - fn reduce_sum(self) -> Self::Scalar { + fn reduce_sum(self) -> $ty { // Safety: `self` is an integer vector unsafe { core::intrinsics::simd::simd_reduce_add_ordered(self, 0) } } #[inline] - fn reduce_product(self) -> Self::Scalar { + fn reduce_product(self) -> $ty { // Safety: `self` is an integer vector unsafe { core::intrinsics::simd::simd_reduce_mul_ordered(self, 1) } } #[inline] - fn reduce_max(self) -> Self::Scalar { + fn reduce_max(self) -> $ty { // Safety: `self` is an integer vector unsafe { core::intrinsics::simd::simd_reduce_max(self) } } #[inline] - fn reduce_min(self) -> Self::Scalar { + fn reduce_min(self) -> $ty { // Safety: `self` is an integer vector unsafe { core::intrinsics::simd::simd_reduce_min(self) } } #[inline] - fn reduce_and(self) -> Self::Scalar { + fn reduce_and(self) -> $ty { // Safety: `self` is an integer vector unsafe { core::intrinsics::simd::simd_reduce_and(self) } } #[inline] - fn reduce_or(self) -> Self::Scalar { + fn reduce_or(self) -> $ty { // Safety: `self` is an integer vector unsafe { core::intrinsics::simd::simd_reduce_or(self) } } #[inline] - fn reduce_xor(self) -> Self::Scalar { + fn reduce_xor(self) -> $ty { // Safety: `self` is an integer vector unsafe { core::intrinsics::simd::simd_reduce_xor(self) } } diff --git a/crates/core_simd/src/simd/ptr/const_ptr.rs b/crates/core_simd/src/simd/ptr/const_ptr.rs index 7ef9dc21373..d21047379be 100644 --- a/crates/core_simd/src/simd/ptr/const_ptr.rs +++ b/crates/core_simd/src/simd/ptr/const_ptr.rs @@ -2,34 +2,19 @@ use super::sealed::Sealed; use crate::simd::{Mask, Simd, cmp::SimdPartialEq, num::SimdUint}; /// Operations on SIMD vectors of constant pointers. -pub trait SimdConstPtr: Copy + Sealed { - /// Vector of `usize` with the same number of elements. - type Usize; - - /// Vector of `isize` with the same number of elements. - type Isize; - - /// Vector of const pointers with the same number of elements. - type CastPtr; - - /// Vector of mutable pointers to the same type. - type MutPtr; - - /// Mask type used for manipulating this SIMD vector type. - type Mask; - +pub trait SimdConstPtr: Copy + Sealed { /// Returns `true` for each element that is null. - fn is_null(self) -> Self::Mask; + fn is_null(self) -> Mask; /// Casts to a pointer of another type. /// /// Equivalent to calling [`pointer::cast`] on each element. - fn cast(self) -> Self::CastPtr; + fn cast(self) -> Simd<*const U, N>; /// Changes constness without changing the type. /// /// Equivalent to calling [`pointer::cast_mut`] on each element. - fn cast_mut(self) -> Self::MutPtr; + fn cast_mut(self) -> Simd<*mut T, N>; /// Gets the "address" portion of the pointer. /// @@ -40,7 +25,7 @@ pub trait SimdConstPtr: Copy + Sealed { /// *address-space* information. To properly restore that information, use [`Self::with_addr`]. /// /// Equivalent to calling [`pointer::addr`] on each element. - fn addr(self) -> Self::Usize; + fn addr(self) -> Simd; /// Converts an address to a pointer without giving it any provenance. /// @@ -53,7 +38,7 @@ pub trait SimdConstPtr: Copy + Sealed { /// previously exposed provenance. /// /// Equivalent to calling [`core::ptr::without_provenance`] on each element. - fn without_provenance(addr: Self::Usize) -> Self; + fn without_provenance(addr: Simd) -> Self; /// Creates a new pointer with the given address. /// @@ -61,49 +46,43 @@ pub trait SimdConstPtr: Copy + Sealed { /// *provenance* of `self` to the new pointer. /// /// Equivalent to calling [`pointer::with_addr`] on each element. - fn with_addr(self, addr: Self::Usize) -> Self; + fn with_addr(self, addr: Simd) -> Self; /// Exposes the "provenance" part of the pointer for future use in /// [`Self::with_exposed_provenance`] and returns the "address" portion. - fn expose_provenance(self) -> Self::Usize; + fn expose_provenance(self) -> Simd; /// Converts an address back to a pointer, picking up a previously "exposed" provenance. /// /// Equivalent to calling [`core::ptr::with_exposed_provenance`] on each element. - fn with_exposed_provenance(addr: Self::Usize) -> Self; + fn with_exposed_provenance(addr: Simd) -> Self; /// Calculates the offset from a pointer using wrapping arithmetic. /// /// Equivalent to calling [`pointer::wrapping_offset`] on each element. - fn wrapping_offset(self, offset: Self::Isize) -> Self; + fn wrapping_offset(self, offset: Simd) -> Self; /// Calculates the offset from a pointer using wrapping arithmetic. /// /// Equivalent to calling [`pointer::wrapping_add`] on each element. - fn wrapping_add(self, count: Self::Usize) -> Self; + fn wrapping_add(self, count: Simd) -> Self; /// Calculates the offset from a pointer using wrapping arithmetic. /// /// Equivalent to calling [`pointer::wrapping_sub`] on each element. - fn wrapping_sub(self, count: Self::Usize) -> Self; + fn wrapping_sub(self, count: Simd) -> Self; } impl Sealed for Simd<*const T, N> {} -impl SimdConstPtr for Simd<*const T, N> { - type Usize = Simd; - type Isize = Simd; - type CastPtr = Simd<*const U, N>; - type MutPtr = Simd<*mut T, N>; - type Mask = Mask; - +impl SimdConstPtr for Simd<*const T, N> { #[inline] - fn is_null(self) -> Self::Mask { + fn is_null(self) -> Mask { Simd::splat(core::ptr::null()).simd_eq(self) } #[inline] - fn cast(self) -> Self::CastPtr { + fn cast(self) -> Simd<*const U, N> { // SimdElement currently requires zero-sized metadata, so this should never fail. // If this ever changes, `simd_cast_ptr` should produce a post-mono error. use core::ptr::Pointee; @@ -115,13 +94,13 @@ impl SimdConstPtr for Simd<*const T, N> { } #[inline] - fn cast_mut(self) -> Self::MutPtr { + fn cast_mut(self) -> Simd<*mut T, N> { // Safety: pointers can be cast unsafe { core::intrinsics::simd::simd_cast_ptr(self) } } #[inline] - fn addr(self) -> Self::Usize { + fn addr(self) -> Simd { // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. // SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the // provenance). @@ -129,7 +108,7 @@ impl SimdConstPtr for Simd<*const T, N> { } #[inline] - fn without_provenance(addr: Self::Usize) -> Self { + fn without_provenance(addr: Simd) -> Self { // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. // SAFETY: Integer-to-pointer transmutes are valid (if you are okay with not getting any // provenance). @@ -137,7 +116,7 @@ impl SimdConstPtr for Simd<*const T, N> { } #[inline] - fn with_addr(self, addr: Self::Usize) -> Self { + fn with_addr(self, addr: Simd) -> Self { // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. // // In the mean-time, this operation is defined to be "as if" it was @@ -149,30 +128,30 @@ impl SimdConstPtr for Simd<*const T, N> { } #[inline] - fn expose_provenance(self) -> Self::Usize { + fn expose_provenance(self) -> Simd { // Safety: `self` is a pointer vector unsafe { core::intrinsics::simd::simd_expose_provenance(self) } } #[inline] - fn with_exposed_provenance(addr: Self::Usize) -> Self { + fn with_exposed_provenance(addr: Simd) -> Self { // Safety: `self` is a pointer vector unsafe { core::intrinsics::simd::simd_with_exposed_provenance(addr) } } #[inline] - fn wrapping_offset(self, count: Self::Isize) -> Self { + fn wrapping_offset(self, count: Simd) -> Self { // Safety: simd_arith_offset takes a vector of pointers and a vector of offsets unsafe { core::intrinsics::simd::simd_arith_offset(self, count) } } #[inline] - fn wrapping_add(self, count: Self::Usize) -> Self { + fn wrapping_add(self, count: Simd) -> Self { self.wrapping_offset(count.cast()) } #[inline] - fn wrapping_sub(self, count: Self::Usize) -> Self { + fn wrapping_sub(self, count: Simd) -> Self { self.wrapping_offset(-count.cast::()) } } diff --git a/crates/core_simd/src/simd/ptr/mut_ptr.rs b/crates/core_simd/src/simd/ptr/mut_ptr.rs index 3b9b75ddf56..8d724d7f9d7 100644 --- a/crates/core_simd/src/simd/ptr/mut_ptr.rs +++ b/crates/core_simd/src/simd/ptr/mut_ptr.rs @@ -2,34 +2,19 @@ use super::sealed::Sealed; use crate::simd::{Mask, Simd, cmp::SimdPartialEq, num::SimdUint}; /// Operations on SIMD vectors of mutable pointers. -pub trait SimdMutPtr: Copy + Sealed { - /// Vector of `usize` with the same number of elements. - type Usize; - - /// Vector of `isize` with the same number of elements. - type Isize; - - /// Vector of const pointers with the same number of elements. - type CastPtr; - - /// Vector of constant pointers to the same type. - type ConstPtr; - - /// Mask type used for manipulating this SIMD vector type. - type Mask; - +pub trait SimdMutPtr: Copy + Sealed { /// Returns `true` for each element that is null. - fn is_null(self) -> Self::Mask; + fn is_null(self) -> Mask; /// Casts to a pointer of another type. /// /// Equivalent to calling [`pointer::cast`] on each element. - fn cast(self) -> Self::CastPtr; + fn cast(self) -> Simd<*mut U, N>; /// Changes constness without changing the type. /// /// Equivalent to calling [`pointer::cast_const`] on each element. - fn cast_const(self) -> Self::ConstPtr; + fn cast_const(self) -> Simd<*const T, N>; /// Gets the "address" portion of the pointer. /// @@ -37,7 +22,7 @@ pub trait SimdMutPtr: Copy + Sealed { /// directly cast into a valid pointer. /// /// Equivalent to calling [`pointer::addr`] on each element. - fn addr(self) -> Self::Usize; + fn addr(self) -> Simd; /// Converts an address to a pointer without giving it any provenance. /// @@ -50,7 +35,7 @@ pub trait SimdMutPtr: Copy + Sealed { /// previously exposed provenance. /// /// Equivalent to calling [`core::ptr::without_provenance`] on each element. - fn without_provenance(addr: Self::Usize) -> Self; + fn without_provenance(addr: Simd) -> Self; /// Creates a new pointer with the given address. /// @@ -58,49 +43,43 @@ pub trait SimdMutPtr: Copy + Sealed { /// *provenance* of `self` to the new pointer. /// /// Equivalent to calling [`pointer::with_addr`] on each element. - fn with_addr(self, addr: Self::Usize) -> Self; + fn with_addr(self, addr: Simd) -> Self; /// Exposes the "provenance" part of the pointer for future use in /// [`Self::with_exposed_provenance`] and returns the "address" portion. - fn expose_provenance(self) -> Self::Usize; + fn expose_provenance(self) -> Simd; /// Converts an address back to a pointer, picking up a previously "exposed" provenance. /// /// Equivalent to calling [`core::ptr::with_exposed_provenance_mut`] on each element. - fn with_exposed_provenance(addr: Self::Usize) -> Self; + fn with_exposed_provenance(addr: Simd) -> Self; /// Calculates the offset from a pointer using wrapping arithmetic. /// /// Equivalent to calling [`pointer::wrapping_offset`] on each element. - fn wrapping_offset(self, offset: Self::Isize) -> Self; + fn wrapping_offset(self, offset: Simd) -> Self; /// Calculates the offset from a pointer using wrapping arithmetic. /// /// Equivalent to calling [`pointer::wrapping_add`] on each element. - fn wrapping_add(self, count: Self::Usize) -> Self; + fn wrapping_add(self, count: Simd) -> Self; /// Calculates the offset from a pointer using wrapping arithmetic. /// /// Equivalent to calling [`pointer::wrapping_sub`] on each element. - fn wrapping_sub(self, count: Self::Usize) -> Self; + fn wrapping_sub(self, count: Simd) -> Self; } impl Sealed for Simd<*mut T, N> {} -impl SimdMutPtr for Simd<*mut T, N> { - type Usize = Simd; - type Isize = Simd; - type CastPtr = Simd<*mut U, N>; - type ConstPtr = Simd<*const T, N>; - type Mask = Mask; - +impl SimdMutPtr for Simd<*mut T, N> { #[inline] - fn is_null(self) -> Self::Mask { + fn is_null(self) -> Mask { Simd::splat(core::ptr::null_mut()).simd_eq(self) } #[inline] - fn cast(self) -> Self::CastPtr { + fn cast(self) -> Simd<*mut U, N> { // SimdElement currently requires zero-sized metadata, so this should never fail. // If this ever changes, `simd_cast_ptr` should produce a post-mono error. use core::ptr::Pointee; @@ -112,13 +91,13 @@ impl SimdMutPtr for Simd<*mut T, N> { } #[inline] - fn cast_const(self) -> Self::ConstPtr { + fn cast_const(self) -> Simd<*const T, N> { // Safety: pointers can be cast unsafe { core::intrinsics::simd::simd_cast_ptr(self) } } #[inline] - fn addr(self) -> Self::Usize { + fn addr(self) -> Simd { // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. // SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the // provenance). @@ -126,7 +105,7 @@ impl SimdMutPtr for Simd<*mut T, N> { } #[inline] - fn without_provenance(addr: Self::Usize) -> Self { + fn without_provenance(addr: Simd) -> Self { // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. // SAFETY: Integer-to-pointer transmutes are valid (if you are okay with not getting any // provenance). @@ -134,7 +113,7 @@ impl SimdMutPtr for Simd<*mut T, N> { } #[inline] - fn with_addr(self, addr: Self::Usize) -> Self { + fn with_addr(self, addr: Simd) -> Self { // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. // // In the mean-time, this operation is defined to be "as if" it was @@ -146,30 +125,30 @@ impl SimdMutPtr for Simd<*mut T, N> { } #[inline] - fn expose_provenance(self) -> Self::Usize { + fn expose_provenance(self) -> Simd { // Safety: `self` is a pointer vector unsafe { core::intrinsics::simd::simd_expose_provenance(self) } } #[inline] - fn with_exposed_provenance(addr: Self::Usize) -> Self { + fn with_exposed_provenance(addr: Simd) -> Self { // Safety: `self` is a pointer vector unsafe { core::intrinsics::simd::simd_with_exposed_provenance(addr) } } #[inline] - fn wrapping_offset(self, count: Self::Isize) -> Self { + fn wrapping_offset(self, count: Simd) -> Self { // Safety: simd_arith_offset takes a vector of pointers and a vector of offsets unsafe { core::intrinsics::simd::simd_arith_offset(self, count) } } #[inline] - fn wrapping_add(self, count: Self::Usize) -> Self { + fn wrapping_add(self, count: Simd) -> Self { self.wrapping_offset(count.cast()) } #[inline] - fn wrapping_sub(self, count: Self::Usize) -> Self { + fn wrapping_sub(self, count: Simd) -> Self { self.wrapping_offset(-count.cast::()) } } diff --git a/crates/core_simd/src/to_bytes.rs b/crates/core_simd/src/to_bytes.rs index 1fd285e457d..927c9c7c6c8 100644 --- a/crates/core_simd/src/to_bytes.rs +++ b/crates/core_simd/src/to_bytes.rs @@ -13,14 +13,7 @@ use sealed::Sealed; /// Converts 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 - + 'static; + type Bytes: Copy + Unpin + Send + Sync + AsRef<[u8]> + AsMut<[u8]> + 'static; /// Returns the memory representation of this integer as a byte array in native byte /// order.