5
5
macro_rules! simd_ty {
6
6
( $id: ident [ $elem_type: ty ; $len: literal] : $( $param_name: ident) ,* ) => {
7
7
#[ repr( simd) ]
8
- #[ derive( Copy , Clone , Debug , PartialEq ) ]
8
+ #[ derive( Copy , Clone ) ]
9
9
pub ( crate ) struct $id( [ $elem_type; $len] ) ;
10
10
11
11
#[ allow( clippy:: use_self) ]
@@ -38,13 +38,32 @@ macro_rules! simd_ty {
38
38
/// Use for testing only.
39
39
// FIXME: Workaround rust@60637
40
40
#[ 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( ) )
48
67
}
49
68
}
50
69
}
@@ -53,7 +72,7 @@ macro_rules! simd_ty {
53
72
macro_rules! simd_m_ty {
54
73
( $id: ident [ $elem_type: ident ; $len: literal] : $( $param_name: ident) ,* ) => {
55
74
#[ repr( simd) ]
56
- #[ derive( Copy , Clone , Debug , PartialEq ) ]
75
+ #[ derive( Copy , Clone ) ]
57
76
pub ( crate ) struct $id( [ $elem_type; $len] ) ;
58
77
59
78
#[ allow( clippy:: use_self) ]
@@ -79,6 +98,30 @@ macro_rules! simd_m_ty {
79
98
// a simd type with exactly one element.
80
99
unsafe { simd_shuffle!( one, one, [ 0 ; $len] ) }
81
100
}
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
+ }
82
125
}
83
126
}
84
127
}
@@ -968,7 +1011,7 @@ simd_ty!(
968
1011
pub ( crate ) fn debug_simd_finish < T : crate :: fmt:: Debug , const N : usize > (
969
1012
formatter : & mut crate :: fmt:: Formatter < ' _ > ,
970
1013
type_name : & str ,
971
- array : [ T ; N ] ,
1014
+ array : & [ T ; N ] ,
972
1015
) -> crate :: fmt:: Result {
973
1016
crate :: fmt:: Formatter :: debug_tuple_fields_finish (
974
1017
formatter,
0 commit comments