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,31 @@ 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
+ 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( ) )
48
66
}
49
67
}
50
68
}
@@ -53,7 +71,7 @@ macro_rules! simd_ty {
53
71
macro_rules! simd_m_ty {
54
72
( $id: ident [ $elem_type: ident ; $len: literal] : $( $param_name: ident) ,* ) => {
55
73
#[ repr( simd) ]
56
- #[ derive( Copy , Clone , Debug , PartialEq ) ]
74
+ #[ derive( Copy , Clone ) ]
57
75
pub ( crate ) struct $id( [ $elem_type; $len] ) ;
58
76
59
77
#[ allow( clippy:: use_self) ]
@@ -79,6 +97,29 @@ macro_rules! simd_m_ty {
79
97
// a simd type with exactly one element.
80
98
unsafe { simd_shuffle!( one, one, [ 0 ; $len] ) }
81
99
}
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
+ }
82
123
}
83
124
}
84
125
}
@@ -968,7 +1009,7 @@ simd_ty!(
968
1009
pub ( crate ) fn debug_simd_finish < T : crate :: fmt:: Debug , const N : usize > (
969
1010
formatter : & mut crate :: fmt:: Formatter < ' _ > ,
970
1011
type_name : & str ,
971
- array : [ T ; N ] ,
1012
+ array : & [ T ; N ] ,
972
1013
) -> crate :: fmt:: Result {
973
1014
crate :: fmt:: Formatter :: debug_tuple_fields_finish (
974
1015
formatter,
0 commit comments