55macro_rules! simd_ty {
66 ( $id: ident [ $elem_type: ty ; $len: literal] : $( $param_name: ident) ,* ) => {
77 #[ repr( simd) ]
8- #[ derive( Copy , Clone , Debug , PartialEq ) ]
8+ #[ derive( Copy , Clone ) ]
99 pub ( crate ) struct $id( [ $elem_type; $len] ) ;
1010
1111 #[ allow( clippy:: use_self) ]
@@ -38,13 +38,31 @@ macro_rules! simd_ty {
3838 /// Use for testing only.
3939 // FIXME: Workaround rust@60637
4040 #[ inline( always) ]
41- pub ( crate ) fn extract( self , index: usize ) -> $elem_type {
42- assert!( index < $len) ;
43- // Now that we know this is in-bounds, use pointer arithmetic to access the right element.
44- let self_ptr = & self as * const Self as * const $elem_type;
45- unsafe {
46- self_ptr. add( index) . read( )
47- }
41+ pub ( crate ) fn extract( & self , index: usize ) -> $elem_type {
42+ self . as_array( ) [ index]
43+ }
44+
45+ #[ inline]
46+ pub ( crate ) fn as_array( & self ) -> & [ $elem_type; $len] {
47+ let simd_ptr: * const Self = self ;
48+ let array_ptr: * const [ $elem_type; $len] = simd_ptr. cast( ) ;
49+ // SAFETY: We can always read the prefix of a simd type as an array.
50+ // There might be more padding afterwards for some widths, but
51+ // that's not a problem for reading less than that.
52+ unsafe { & * array_ptr }
53+ }
54+ }
55+
56+ impl core:: cmp:: PartialEq for $id {
57+ fn eq( & self , other: & Self ) -> bool {
58+ self . as_array( ) == other. as_array( )
59+ }
60+ }
61+
62+ impl core:: fmt:: Debug for $id {
63+ #[ inline]
64+ fn fmt( & self , f: & mut core:: fmt:: Formatter <' _>) -> core:: fmt:: Result {
65+ debug_simd_finish( f, stringify!( $id) , self . as_array( ) )
4866 }
4967 }
5068 }
@@ -53,7 +71,7 @@ macro_rules! simd_ty {
5371macro_rules! simd_m_ty {
5472 ( $id: ident [ $elem_type: ident ; $len: literal] : $( $param_name: ident) ,* ) => {
5573 #[ repr( simd) ]
56- #[ derive( Copy , Clone , Debug , PartialEq ) ]
74+ #[ derive( Copy , Clone ) ]
5775 pub ( crate ) struct $id( [ $elem_type; $len] ) ;
5876
5977 #[ allow( clippy:: use_self) ]
@@ -79,6 +97,29 @@ macro_rules! simd_m_ty {
7997 // a simd type with exactly one element.
8098 unsafe { simd_shuffle!( one, one, [ 0 ; $len] ) }
8199 }
100+
101+ #[ inline]
102+ pub ( crate ) fn as_array( & self ) -> & [ $elem_type; $len] {
103+ let simd_ptr: * const Self = self ;
104+ let array_ptr: * const [ $elem_type; $len] = simd_ptr. cast( ) ;
105+ // SAFETY: We can always read the prefix of a simd type as an array.
106+ // There might be more padding afterwards for some widths, but
107+ // that's not a problem for reading less than that.
108+ unsafe { & * array_ptr }
109+ }
110+ }
111+
112+ impl core:: cmp:: PartialEq for $id {
113+ fn eq( & self , other: & Self ) -> bool {
114+ self . as_array( ) == other. as_array( )
115+ }
116+ }
117+
118+ impl core:: fmt:: Debug for $id {
119+ #[ inline]
120+ fn fmt( & self , f: & mut core:: fmt:: Formatter <' _>) -> core:: fmt:: Result {
121+ debug_simd_finish( f, stringify!( $id) , self . as_array( ) )
122+ }
82123 }
83124 }
84125}
@@ -968,7 +1009,7 @@ simd_ty!(
9681009pub ( crate ) fn debug_simd_finish < T : crate :: fmt:: Debug , const N : usize > (
9691010 formatter : & mut crate :: fmt:: Formatter < ' _ > ,
9701011 type_name : & str ,
971- array : [ T ; N ] ,
1012+ array : & [ T ; N ] ,
9721013) -> crate :: fmt:: Result {
9731014 crate :: fmt:: Formatter :: debug_tuple_fields_finish (
9741015 formatter,
0 commit comments