diff --git a/crates/core_simd/src/elements/float.rs b/crates/core_simd/src/elements/float.rs index 5a628f2121e..67e4454e5e1 100644 --- a/crates/core_simd/src/elements/float.rs +++ b/crates/core_simd/src/elements/float.rs @@ -202,17 +202,20 @@ macro_rules! impl_trait { #[inline] fn to_bits(self) -> Simd<$bits_ty, LANES> { assert_eq!(core::mem::size_of::(), core::mem::size_of::()); + // Safety: transmuting between vector types is safe unsafe { core::mem::transmute_copy(&self) } } #[inline] fn from_bits(bits: Simd<$bits_ty, LANES>) -> Self { assert_eq!(core::mem::size_of::(), core::mem::size_of::()); + // Safety: transmuting between vector types is safe unsafe { core::mem::transmute_copy(&bits) } } #[inline] fn abs(self) -> Self { + // Safety: `self` is a float vector unsafe { intrinsics::simd_fabs(self) } } @@ -283,11 +286,13 @@ macro_rules! impl_trait { #[inline] fn simd_min(self, other: Self) -> Self { + // Safety: `self` and `other` are float vectors unsafe { intrinsics::simd_fmin(self, other) } } #[inline] fn simd_max(self, other: Self) -> Self { + // Safety: `self` and `other` are floating point vectors unsafe { intrinsics::simd_fmax(self, other) } } diff --git a/crates/core_simd/src/lib.rs b/crates/core_simd/src/lib.rs index 2632073622e..715f258f617 100644 --- a/crates/core_simd/src/lib.rs +++ b/crates/core_simd/src/lib.rs @@ -12,7 +12,7 @@ #![cfg_attr(feature = "generic_const_exprs", feature(generic_const_exprs))] #![cfg_attr(feature = "generic_const_exprs", allow(incomplete_features))] #![warn(missing_docs)] -#![deny(unsafe_op_in_unsafe_fn)] +#![deny(unsafe_op_in_unsafe_fn, clippy::undocumented_unsafe_blocks)] #![unstable(feature = "portable_simd", issue = "86656")] //! Portable SIMD module. diff --git a/crates/core_simd/src/masks.rs b/crates/core_simd/src/masks.rs index 11d7288eccb..c36c336d8a2 100644 --- a/crates/core_simd/src/masks.rs +++ b/crates/core_simd/src/masks.rs @@ -68,6 +68,7 @@ macro_rules! impl_element { const FALSE: Self = 0; } + // Safety: this is a valid mask element type unsafe impl MaskElement for $ty {} } } diff --git a/crates/core_simd/src/masks/to_bitmask.rs b/crates/core_simd/src/masks/to_bitmask.rs index 954f88ea511..65d3ce9be65 100644 --- a/crates/core_simd/src/masks/to_bitmask.rs +++ b/crates/core_simd/src/masks/to_bitmask.rs @@ -16,11 +16,7 @@ where /// Converts masks to and from integer bitmasks. /// /// Each bit of the bitmask corresponds to a mask lane, starting with the LSB. -/// -/// # Safety -/// This trait is `unsafe` and sealed, since the `BitMask` type must match the number of lanes in -/// the mask. -pub unsafe trait ToBitMask: Sealed { +pub trait ToBitMask: Sealed { /// The integer bitmask type. type BitMask; @@ -34,12 +30,8 @@ pub unsafe 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. -/// -/// # Safety -/// This trait is `unsafe` and sealed, since the `BYTES` value must match the number of lanes in -/// the mask. #[cfg(feature = "generic_const_exprs")] -pub unsafe trait ToBitMaskArray: Sealed { +pub trait ToBitMaskArray: Sealed { /// The length of the bitmask array. const BYTES: usize; @@ -51,9 +43,9 @@ pub unsafe trait ToBitMaskArray: Sealed { } macro_rules! impl_integer_intrinsic { - { $(unsafe impl ToBitMask for Mask<_, $lanes:literal>)* } => { + { $(impl ToBitMask for Mask<_, $lanes:literal>)* } => { $( - unsafe impl ToBitMask for Mask { + impl ToBitMask for Mask { type BitMask = $int; fn to_bitmask(self) -> $int { @@ -69,13 +61,13 @@ macro_rules! impl_integer_intrinsic { } impl_integer_intrinsic! { - unsafe impl ToBitMask for Mask<_, 1> - unsafe impl ToBitMask for Mask<_, 2> - unsafe impl ToBitMask for Mask<_, 4> - unsafe impl ToBitMask for Mask<_, 8> - unsafe impl ToBitMask for Mask<_, 16> - unsafe impl ToBitMask for Mask<_, 32> - unsafe impl ToBitMask for Mask<_, 64> + impl ToBitMask for Mask<_, 1> + impl ToBitMask for Mask<_, 2> + impl ToBitMask for Mask<_, 4> + impl ToBitMask for Mask<_, 8> + impl ToBitMask for Mask<_, 16> + impl ToBitMask for Mask<_, 32> + impl ToBitMask for Mask<_, 64> } /// Returns the minimum numnber of bytes in a bitmask with `lanes` lanes. @@ -85,7 +77,7 @@ pub const fn bitmask_len(lanes: usize) -> usize { } #[cfg(feature = "generic_const_exprs")] -unsafe impl ToBitMaskArray for Mask +impl ToBitMaskArray for Mask where LaneCount: SupportedLaneCount, { diff --git a/crates/core_simd/src/ops.rs b/crates/core_simd/src/ops.rs index 8dbae346b5f..5a077a469d8 100644 --- a/crates/core_simd/src/ops.rs +++ b/crates/core_simd/src/ops.rs @@ -33,6 +33,7 @@ where macro_rules! unsafe_base { ($lhs:ident, $rhs:ident, {$simd_call:ident}, $($_:tt)*) => { + // Safety: $lhs and $rhs are vectors unsafe { $crate::simd::intrinsics::$simd_call($lhs, $rhs) } }; } @@ -49,6 +50,7 @@ macro_rules! unsafe_base { macro_rules! wrap_bitshift { ($lhs:ident, $rhs:ident, {$simd_call:ident}, $int:ident) => { #[allow(clippy::suspicious_arithmetic_impl)] + // Safety: $lhs and the bitand result are vectors unsafe { $crate::simd::intrinsics::$simd_call( $lhs, @@ -91,6 +93,7 @@ macro_rules! int_divrem_guard { // Nice base case to make it easy to const-fold away the other branch. $rhs }; + // Safety: $lhs and rhs are vectors unsafe { $crate::simd::intrinsics::$simd_call($lhs, rhs) } } }; diff --git a/crates/core_simd/src/ops/unary.rs b/crates/core_simd/src/ops/unary.rs index 4ebea560fc6..4ad02215034 100644 --- a/crates/core_simd/src/ops/unary.rs +++ b/crates/core_simd/src/ops/unary.rs @@ -14,6 +14,7 @@ macro_rules! neg { #[inline] #[must_use = "operator returns a new vector without mutating the input"] fn neg(self) -> Self::Output { + // Safety: `self` is a signed vector unsafe { intrinsics::simd_neg(self) } } })* diff --git a/crates/core_simd/src/round.rs b/crates/core_simd/src/round.rs index 556bc2cc1fe..e111f3e0494 100644 --- a/crates/core_simd/src/round.rs +++ b/crates/core_simd/src/round.rs @@ -30,6 +30,8 @@ macro_rules! implement { $type: FloatToInt, I: SimdElement, { + // Safety: `self` is a vector, and `FloatToInt` ensures the type can be casted to + // an integer. unsafe { intrinsics::simd_cast(self) } } } diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs index 9eb51f957d1..fac7dca51f4 100644 --- a/crates/core_simd/src/vector.rs +++ b/crates/core_simd/src/vector.rs @@ -213,7 +213,7 @@ where #[inline] #[cfg(not(bootstrap))] pub fn cast(self) -> Simd { - // Safety: The input argument is a vector of a known SIMD type. + // Safety: The input argument is a vector of a valid SIMD element type. unsafe { intrinsics::simd_as(self) } } @@ -624,61 +624,85 @@ pub unsafe trait SimdElement: Sealed + Copy { } impl Sealed for u8 {} + +// Safety: u8 is a valid SIMD element type, and is supported by this API unsafe impl SimdElement for u8 { type Mask = i8; } impl Sealed for u16 {} + +// Safety: u16 is a valid SIMD element type, and is supported by this API unsafe impl SimdElement for u16 { type Mask = i16; } impl Sealed for u32 {} + +// Safety: u32 is a valid SIMD element type, and is supported by this API unsafe impl SimdElement for u32 { type Mask = i32; } impl Sealed for u64 {} + +// Safety: u64 is a valid SIMD element type, and is supported by this API unsafe impl SimdElement for u64 { type Mask = i64; } impl Sealed for usize {} + +// Safety: usize is a valid SIMD element type, and is supported by this API unsafe impl SimdElement for usize { type Mask = isize; } impl Sealed for i8 {} + +// Safety: i8 is a valid SIMD element type, and is supported by this API unsafe impl SimdElement for i8 { type Mask = i8; } impl Sealed for i16 {} + +// Safety: i16 is a valid SIMD element type, and is supported by this API unsafe impl SimdElement for i16 { type Mask = i16; } impl Sealed for i32 {} + +// Safety: i32 is a valid SIMD element type, and is supported by this API unsafe impl SimdElement for i32 { type Mask = i32; } impl Sealed for i64 {} + +// Safety: i64 is a valid SIMD element type, and is supported by this API unsafe impl SimdElement for i64 { type Mask = i64; } impl Sealed for isize {} + +// Safety: isize is a valid SIMD element type, and is supported by this API unsafe impl SimdElement for isize { type Mask = isize; } impl Sealed for f32 {} + +// Safety: f32 is a valid SIMD element type, and is supported by this API unsafe impl SimdElement for f32 { type Mask = i32; } impl Sealed for f64 {} + +// Safety: f64 is a valid SIMD element type, and is supported by this API unsafe impl SimdElement for f64 { type Mask = i64; }