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,32 @@ 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+ #[ inline]
58+ fn eq( & self , other: & Self ) -> bool {
59+ self . as_array( ) == other. as_array( )
60+ }
61+ }
62+
63+ impl core:: fmt:: Debug for $id {
64+ #[ inline]
65+ fn fmt( & self , f: & mut core:: fmt:: Formatter <' _>) -> core:: fmt:: Result {
66+ debug_simd_finish( f, stringify!( $id) , self . as_array( ) )
4867 }
4968 }
5069 }
@@ -53,7 +72,7 @@ macro_rules! simd_ty {
5372macro_rules! simd_m_ty {
5473 ( $id: ident [ $elem_type: ident ; $len: literal] : $( $param_name: ident) ,* ) => {
5574 #[ repr( simd) ]
56- #[ derive( Copy , Clone , Debug , PartialEq ) ]
75+ #[ derive( Copy , Clone ) ]
5776 pub ( crate ) struct $id( [ $elem_type; $len] ) ;
5877
5978 #[ allow( clippy:: use_self) ]
@@ -79,6 +98,30 @@ macro_rules! simd_m_ty {
7998 // a simd type with exactly one element.
8099 unsafe { simd_shuffle!( one, one, [ 0 ; $len] ) }
81100 }
101+
102+ #[ inline]
103+ pub ( crate ) fn as_array( & self ) -> & [ $elem_type; $len] {
104+ let simd_ptr: * const Self = self ;
105+ let array_ptr: * const [ $elem_type; $len] = simd_ptr. cast( ) ;
106+ // SAFETY: We can always read the prefix of a simd type as an array.
107+ // There might be more padding afterwards for some widths, but
108+ // that's not a problem for reading less than that.
109+ unsafe { & * array_ptr }
110+ }
111+ }
112+
113+ impl core:: cmp:: PartialEq for $id {
114+ #[ inline]
115+ fn eq( & self , other: & Self ) -> bool {
116+ self . as_array( ) == other. as_array( )
117+ }
118+ }
119+
120+ impl core:: fmt:: Debug for $id {
121+ #[ inline]
122+ fn fmt( & self , f: & mut core:: fmt:: Formatter <' _>) -> core:: fmt:: Result {
123+ debug_simd_finish( f, stringify!( $id) , self . as_array( ) )
124+ }
82125 }
83126 }
84127}
@@ -968,7 +1011,7 @@ simd_ty!(
9681011pub ( crate ) fn debug_simd_finish < T : crate :: fmt:: Debug , const N : usize > (
9691012 formatter : & mut crate :: fmt:: Formatter < ' _ > ,
9701013 type_name : & str ,
971- array : [ T ; N ] ,
1014+ array : & [ T ; N ] ,
9721015) -> crate :: fmt:: Result {
9731016 crate :: fmt:: Formatter :: debug_tuple_fields_finish (
9741017 formatter,
0 commit comments