about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMarkus Everling <markuseverling@gmail.com>2023-04-22 21:12:35 +0000
committerMarkus Everling <markuseverling@gmail.com>2023-04-22 21:40:36 +0000
commitafad9c3f644ddbfef3301f617cb9d23ca4e71fe0 (patch)
treea64fa253401212e007e3326439b8799b09abf37b
parentceb26115928c5c69b10268fd2f9e500865c142d6 (diff)
downloadrust-afad9c3f644ddbfef3301f617cb9d23ca4e71fe0.tar.gz
rust-afad9c3f644ddbfef3301f617cb9d23ca4e71fe0.zip
Don't use direct field access in `Simd` functions
-rw-r--r--crates/core_simd/src/lib.rs2
-rw-r--r--crates/core_simd/src/vector.rs26
2 files changed, 20 insertions, 8 deletions
diff --git a/crates/core_simd/src/lib.rs b/crates/core_simd/src/lib.rs
index 927b1654f8e..a372e2e40c4 100644
--- a/crates/core_simd/src/lib.rs
+++ b/crates/core_simd/src/lib.rs
@@ -1,6 +1,8 @@
 #![no_std]
 #![feature(
     const_ptr_read,
+    const_refs_to_cell,
+    const_transmute_copy,
     convert_float_to_int,
     decl_macro,
     intra_doc_pointers,
diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs
index 3e39f1d623c..c1af4af5f57 100644
--- a/crates/core_simd/src/vector.rs
+++ b/crates/core_simd/src/vector.rs
@@ -135,22 +135,32 @@ where
     /// assert_eq!(v.as_array(), &[0, 1, 2, 3]);
     /// ```
     pub const fn as_array(&self) -> &[T; LANES] {
-        &self.0
+        // SAFETY: Transmuting between `Simd<T, LANES>` and `[T; LANES]`
+        // is always valid and `Simd<T, LANES>` never has a lower alignment
+        // than `[T; LANES]`.
+        unsafe { &*(self as *const Self as *const [T; LANES]) }
     }
 
     /// Returns a mutable array reference containing the entire SIMD vector.
     pub fn as_mut_array(&mut self) -> &mut [T; LANES] {
-        &mut self.0
+        // SAFETY: Transmuting between `Simd<T, LANES>` and `[T; LANES]`
+        // is always valid and `Simd<T, LANES>` never has a lower alignment
+        // than `[T; LANES]`.
+        unsafe { &mut *(self as *mut Self as *mut [T; LANES]) }
     }
 
     /// Converts an array to a SIMD vector.
     pub const fn from_array(array: [T; LANES]) -> Self {
-        Self(array)
+        // SAFETY: Transmuting between `Simd<T, LANES>` and `[T; LANES]`
+        // is always valid.
+        unsafe { core::mem::transmute_copy(&array) }
     }
 
     /// Converts a SIMD vector to an array.
     pub const fn to_array(self) -> [T; LANES] {
-        self.0
+        // SAFETY: Transmuting between `Simd<T, LANES>` and `[T; LANES]`
+        // is always valid.
+        unsafe { core::mem::transmute_copy(&self) }
     }
 
     /// Converts a slice to a SIMD vector containing `slice[..LANES]`.
@@ -735,7 +745,7 @@ where
 {
     #[inline]
     fn as_ref(&self) -> &[T; LANES] {
-        &self.0
+        self.as_array()
     }
 }
 
@@ -746,7 +756,7 @@ where
 {
     #[inline]
     fn as_mut(&mut self) -> &mut [T; LANES] {
-        &mut self.0
+        self.as_mut_array()
     }
 }
 
@@ -758,7 +768,7 @@ where
 {
     #[inline]
     fn as_ref(&self) -> &[T] {
-        &self.0
+        self.as_array()
     }
 }
 
@@ -769,7 +779,7 @@ where
 {
     #[inline]
     fn as_mut(&mut self) -> &mut [T] {
-        &mut self.0
+        self.as_mut_array()
     }
 }