Merge pull request #347 from thomcc/attrs
Add `#[inline]` to functions which were missing it, and `#[track_caller]` to ones with runtime panics from user input
This commit is contained in:
commit
cd3c67b7e5
6 changed files with 37 additions and 2 deletions
|
|
@ -10,6 +10,7 @@ macro_rules! impl_traits {
|
|||
where
|
||||
LaneCount<LANES>: SupportedLaneCount,
|
||||
{
|
||||
#[inline]
|
||||
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
|
||||
iter.fold(Simd::splat(0 as $type), Add::add)
|
||||
}
|
||||
|
|
@ -19,6 +20,7 @@ macro_rules! impl_traits {
|
|||
where
|
||||
LaneCount<LANES>: SupportedLaneCount,
|
||||
{
|
||||
#[inline]
|
||||
fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
|
||||
iter.fold(Simd::splat(1 as $type), Mul::mul)
|
||||
}
|
||||
|
|
@ -28,6 +30,7 @@ macro_rules! impl_traits {
|
|||
where
|
||||
LaneCount<LANES>: SupportedLaneCount,
|
||||
{
|
||||
#[inline]
|
||||
fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
|
||||
iter.fold(Simd::splat(0 as $type), Add::add)
|
||||
}
|
||||
|
|
@ -37,6 +40,7 @@ macro_rules! impl_traits {
|
|||
where
|
||||
LaneCount<LANES>: SupportedLaneCount,
|
||||
{
|
||||
#[inline]
|
||||
fn product<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
|
||||
iter.fold(Simd::splat(1 as $type), Mul::mul)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
)]
|
||||
#![cfg_attr(feature = "generic_const_exprs", feature(generic_const_exprs))]
|
||||
#![cfg_attr(feature = "generic_const_exprs", allow(incomplete_features))]
|
||||
#![warn(missing_docs)]
|
||||
#![warn(missing_docs, clippy::missing_inline_in_public_items)] // basically all items, really
|
||||
#![deny(unsafe_op_in_unsafe_fn, clippy::undocumented_unsafe_blocks)]
|
||||
#![unstable(feature = "portable_simd", issue = "86656")]
|
||||
//! Portable SIMD module.
|
||||
|
|
|
|||
|
|
@ -179,6 +179,7 @@ where
|
|||
/// Panics if any lane is not 0 or -1.
|
||||
#[inline]
|
||||
#[must_use = "method returns a new mask and does not mutate the original value"]
|
||||
#[track_caller]
|
||||
pub fn from_int(value: Simd<T, LANES>) -> Self {
|
||||
assert!(T::valid(value), "all values must be either 0 or -1",);
|
||||
// Safety: the validity has been checked
|
||||
|
|
@ -217,6 +218,7 @@ where
|
|||
/// Panics if `lane` is greater than or equal to the number of lanes in the vector.
|
||||
#[inline]
|
||||
#[must_use = "method returns a new bool and does not mutate the original value"]
|
||||
#[track_caller]
|
||||
pub fn test(&self, lane: usize) -> bool {
|
||||
assert!(lane < LANES, "lane index out of range");
|
||||
// Safety: the lane index has been checked
|
||||
|
|
@ -240,6 +242,7 @@ where
|
|||
/// # Panics
|
||||
/// Panics if `lane` is greater than or equal to the number of lanes in the vector.
|
||||
#[inline]
|
||||
#[track_caller]
|
||||
pub fn set(&mut self, lane: usize, value: bool) {
|
||||
assert!(lane < LANES, "lane index out of range");
|
||||
// Safety: the lane index has been checked
|
||||
|
|
@ -327,6 +330,7 @@ where
|
|||
T: MaskElement + fmt::Debug,
|
||||
LaneCount<LANES>: SupportedLaneCount,
|
||||
{
|
||||
#[inline]
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_list()
|
||||
.entries((0..LANES).map(|lane| self.test(lane)))
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ where
|
|||
I: core::slice::SliceIndex<[T]>,
|
||||
{
|
||||
type Output = I::Output;
|
||||
#[inline]
|
||||
fn index(&self, index: I) -> &Self::Output {
|
||||
&self.as_array()[index]
|
||||
}
|
||||
|
|
@ -26,6 +27,7 @@ where
|
|||
LaneCount<LANES>: SupportedLaneCount,
|
||||
I: core::slice::SliceIndex<[T]>,
|
||||
{
|
||||
#[inline]
|
||||
fn index_mut(&mut self, index: I) -> &mut Self::Output {
|
||||
&mut self.as_mut_array()[index]
|
||||
}
|
||||
|
|
@ -118,10 +120,14 @@ macro_rules! for_base_types {
|
|||
|
||||
#[inline]
|
||||
#[must_use = "operator returns a new vector without mutating the inputs"]
|
||||
// TODO: only useful for int Div::div, but we hope that this
|
||||
// will essentially always always get inlined anyway.
|
||||
#[track_caller]
|
||||
fn $call(self, rhs: Self) -> Self::Output {
|
||||
$macro_impl!(self, rhs, $inner, $scalar)
|
||||
}
|
||||
})*
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ macro_rules! impl_integer {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[track_caller]
|
||||
fn simd_clamp(self, min: Self, max: Self) -> Self {
|
||||
assert!(
|
||||
min.simd_le(max).all(),
|
||||
|
|
@ -200,6 +201,7 @@ macro_rules! impl_mask {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[track_caller]
|
||||
fn simd_clamp(self, min: Self, max: Self) -> Self {
|
||||
assert!(
|
||||
min.simd_le(max).all(),
|
||||
|
|
@ -254,6 +256,7 @@ where
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[track_caller]
|
||||
fn simd_clamp(self, min: Self, max: Self) -> Self {
|
||||
assert!(
|
||||
min.simd_le(max).all(),
|
||||
|
|
@ -303,6 +306,7 @@ where
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[track_caller]
|
||||
fn simd_clamp(self, min: Self, max: Self) -> Self {
|
||||
assert!(
|
||||
min.simd_le(max).all(),
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ where
|
|||
/// let v = u32x4::splat(0);
|
||||
/// assert_eq!(v.lanes(), 4);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub const fn lanes(&self) -> usize {
|
||||
Self::LANES
|
||||
}
|
||||
|
|
@ -136,6 +137,7 @@ where
|
|||
/// let v = u32x4::splat(8);
|
||||
/// assert_eq!(v.as_array(), &[8, 8, 8, 8]);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn splat(value: T) -> Self {
|
||||
// This is preferred over `[value; N]`, since it's explicitly a splat:
|
||||
// https://github.com/rust-lang/rust/issues/97804
|
||||
|
|
@ -156,6 +158,7 @@ where
|
|||
/// let v: u64x4 = Simd::from_array([0, 1, 2, 3]);
|
||||
/// assert_eq!(v.as_array(), &[0, 1, 2, 3]);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub const fn as_array(&self) -> &[T; N] {
|
||||
// SAFETY: `Simd<T, N>` is just an overaligned `[T; N]` with
|
||||
// potential padding at the end, so pointer casting to a
|
||||
|
|
@ -167,6 +170,7 @@ where
|
|||
}
|
||||
|
||||
/// Returns a mutable array reference containing the entire SIMD vector.
|
||||
#[inline]
|
||||
pub fn as_mut_array(&mut self) -> &mut [T; N] {
|
||||
// SAFETY: `Simd<T, N>` is just an overaligned `[T; N]` with
|
||||
// potential padding at the end, so pointer casting to a
|
||||
|
|
@ -184,6 +188,7 @@ where
|
|||
///
|
||||
/// # Safety
|
||||
/// Reading `ptr` must be safe, as if by `<*const [T; N]>::read_unaligned`.
|
||||
#[inline]
|
||||
const unsafe fn load(ptr: *const [T; N]) -> Self {
|
||||
// There are potentially simpler ways to write this function, but this should result in
|
||||
// LLVM `load <N x T>`
|
||||
|
|
@ -204,6 +209,7 @@ where
|
|||
///
|
||||
/// # Safety
|
||||
/// Writing to `ptr` must be safe, as if by `<*mut [T; N]>::write_unaligned`.
|
||||
#[inline]
|
||||
const unsafe fn store(self, ptr: *mut [T; N]) {
|
||||
// There are potentially simpler ways to write this function, but this should result in
|
||||
// LLVM `store <N x T>`
|
||||
|
|
@ -216,6 +222,7 @@ where
|
|||
}
|
||||
|
||||
/// Converts an array to a SIMD vector.
|
||||
#[inline]
|
||||
pub const fn from_array(array: [T; N]) -> Self {
|
||||
// SAFETY: `&array` is safe to read.
|
||||
//
|
||||
|
|
@ -228,6 +235,7 @@ where
|
|||
}
|
||||
|
||||
/// Converts a SIMD vector to an array.
|
||||
#[inline]
|
||||
pub const fn to_array(self) -> [T; N] {
|
||||
let mut tmp = core::mem::MaybeUninit::uninit();
|
||||
// SAFETY: writing to `tmp` is safe and initializes it.
|
||||
|
|
@ -259,6 +267,8 @@ where
|
|||
/// assert_eq!(v.as_array(), &[1, 2, 3, 4]);
|
||||
/// ```
|
||||
#[must_use]
|
||||
#[inline]
|
||||
#[track_caller]
|
||||
pub const fn from_slice(slice: &[T]) -> Self {
|
||||
assert!(
|
||||
slice.len() >= Self::LANES,
|
||||
|
|
@ -287,6 +297,8 @@ where
|
|||
/// v.copy_to_slice(&mut dest);
|
||||
/// assert_eq!(&dest, &[1, 2, 3, 4, 0, 0]);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[track_caller]
|
||||
pub fn copy_to_slice(self, slice: &mut [T]) {
|
||||
assert!(
|
||||
slice.len() >= Self::LANES,
|
||||
|
|
@ -718,6 +730,7 @@ where
|
|||
LaneCount<N>: SupportedLaneCount,
|
||||
T: SimdElement,
|
||||
{
|
||||
#[inline]
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
|
|
@ -862,6 +875,7 @@ where
|
|||
LaneCount<N>: SupportedLaneCount,
|
||||
T: SimdElement,
|
||||
{
|
||||
#[inline]
|
||||
fn from(array: [T; N]) -> Self {
|
||||
Self::from_array(array)
|
||||
}
|
||||
|
|
@ -872,6 +886,7 @@ where
|
|||
LaneCount<N>: SupportedLaneCount,
|
||||
T: SimdElement,
|
||||
{
|
||||
#[inline]
|
||||
fn from(vector: Simd<T, N>) -> Self {
|
||||
vector.to_array()
|
||||
}
|
||||
|
|
@ -884,6 +899,7 @@ where
|
|||
{
|
||||
type Error = core::array::TryFromSliceError;
|
||||
|
||||
#[inline]
|
||||
fn try_from(slice: &[T]) -> Result<Self, core::array::TryFromSliceError> {
|
||||
Ok(Self::from_array(slice.try_into()?))
|
||||
}
|
||||
|
|
@ -896,6 +912,7 @@ where
|
|||
{
|
||||
type Error = core::array::TryFromSliceError;
|
||||
|
||||
#[inline]
|
||||
fn try_from(slice: &mut [T]) -> Result<Self, core::array::TryFromSliceError> {
|
||||
Ok(Self::from_array(slice.try_into()?))
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue