@@ -2,7 +2,6 @@ use crate::mir::interpret::{sign_extend, truncate, InterpErrorInfo, InterpResult
2
2
use crate :: throw_ub;
3
3
use rustc_apfloat:: ieee:: { Double , Single } ;
4
4
use rustc_apfloat:: Float ;
5
- use rustc_macros:: HashStable ;
6
5
use rustc_serialize:: { Decodable , Decoder , Encodable , Encoder } ;
7
6
use rustc_target:: abi:: { Size , TargetDataLayout } ;
8
7
use std:: convert:: { TryFrom , TryInto } ;
@@ -29,7 +28,7 @@ impl std::fmt::Debug for ConstInt {
29
28
fn fmt ( & self , fmt : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
30
29
let Self { int, signed, is_ptr_sized_integral } = * self ;
31
30
let size = int. size ( ) . bytes ( ) ;
32
- let raw = int. data ( ) ;
31
+ let raw = int. data ;
33
32
if signed {
34
33
let bit_size = size * 8 ;
35
34
let min = 1u128 << ( bit_size - 1 ) ;
@@ -116,41 +115,46 @@ impl std::fmt::Debug for ConstInt {
116
115
117
116
// FIXME: reuse in `super::int::ConstInt` and `Scalar::Bits`
118
117
/// The raw bytes of a simple value.
118
+ ///
119
+ /// This is a packed struct in order to allow this type to be optimally embedded in enums
120
+ /// (like Scalar).
119
121
#[ derive( Clone , Copy , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
120
- #[ derive ( HashStable ) ]
122
+ #[ repr ( packed ) ]
121
123
pub struct ScalarInt {
122
124
/// The first `size` bytes of `data` are the value.
123
125
/// Do not try to read less or more bytes than that. The remaining bytes must be 0.
124
- ///
125
- /// This is an array in order to allow this type to be optimally embedded in enums
126
- /// (like Scalar).
127
- bytes : [ u8 ; 16 ] ,
126
+ data : u128 ,
128
127
size : u8 ,
129
128
}
130
129
130
+ // Cannot derive these, as the derives take references to the fields, and we
131
+ // can't take references to fields of packed structs.
132
+ impl < CTX > crate :: ty:: HashStable < CTX > for ScalarInt {
133
+ fn hash_stable ( & self , hcx : & mut CTX , hasher : & mut crate :: ty:: StableHasher ) {
134
+ { self . data } . hash_stable ( hcx, hasher) ;
135
+ self . size . hash_stable ( hcx, hasher) ;
136
+ }
137
+ }
138
+
131
139
impl < S : Encoder > Encodable < S > for ScalarInt {
132
140
fn encode ( & self , s : & mut S ) -> Result < ( ) , S :: Error > {
133
- s. emit_u128 ( self . data ( ) ) ?;
141
+ s. emit_u128 ( self . data ) ?;
134
142
s. emit_u8 ( self . size )
135
143
}
136
144
}
137
145
138
146
impl < D : Decoder > Decodable < D > for ScalarInt {
139
147
fn decode ( d : & mut D ) -> Result < ScalarInt , D :: Error > {
140
- Ok ( ScalarInt { bytes : d. read_u128 ( ) ?. to_ne_bytes ( ) , size : d. read_u8 ( ) ? } )
148
+ Ok ( ScalarInt { data : d. read_u128 ( ) ?, size : d. read_u8 ( ) ? } )
141
149
}
142
150
}
143
151
144
152
impl ScalarInt {
145
- pub const TRUE : ScalarInt = ScalarInt { bytes : 1_u128 . to_ne_bytes ( ) , size : 1 } ;
153
+ pub const TRUE : ScalarInt = ScalarInt { data : 1_u128 , size : 1 } ;
146
154
147
- pub const FALSE : ScalarInt = ScalarInt { bytes : 0_u128 . to_ne_bytes ( ) , size : 1 } ;
155
+ pub const FALSE : ScalarInt = ScalarInt { data : 0_u128 , size : 1 } ;
148
156
149
- pub const ZST : ScalarInt = ScalarInt { bytes : 0_u128 . to_ne_bytes ( ) , size : 0 } ;
150
-
151
- fn data ( self ) -> u128 {
152
- u128:: from_ne_bytes ( self . bytes )
153
- }
157
+ pub const ZST : ScalarInt = ScalarInt { data : 0_u128 , size : 0 } ;
154
158
155
159
#[ inline]
156
160
pub fn size ( self ) -> Size {
@@ -164,10 +168,10 @@ impl ScalarInt {
164
168
#[ inline( always) ]
165
169
fn check_data ( self ) {
166
170
debug_assert_eq ! (
167
- truncate( self . data( ) , self . size( ) ) ,
168
- self . data( ) ,
171
+ truncate( self . data, self . size( ) ) ,
172
+ { self . data } ,
169
173
"Scalar value {:#x} exceeds size of {} bytes" ,
170
- self . data( ) ,
174
+ { self . data } ,
171
175
self . size
172
176
) ;
173
177
}
@@ -179,7 +183,7 @@ impl ScalarInt {
179
183
180
184
#[ inline]
181
185
pub fn null ( size : Size ) -> Self {
182
- Self { bytes : [ 0 ; 16 ] , size : size. bytes ( ) as u8 }
186
+ Self { data : 0 , size : size. bytes ( ) as u8 }
183
187
}
184
188
185
189
pub ( crate ) fn ptr_sized_op < ' tcx > (
@@ -188,17 +192,14 @@ impl ScalarInt {
188
192
f_int : impl FnOnce ( u64 ) -> InterpResult < ' tcx , u64 > ,
189
193
) -> InterpResult < ' tcx , Self > {
190
194
assert_eq ! ( u64 :: from( self . size) , dl. pointer_size. bytes( ) ) ;
191
- Ok ( Self {
192
- bytes : u128:: from ( f_int ( u64:: try_from ( self . data ( ) ) . unwrap ( ) ) ?) . to_ne_bytes ( ) ,
193
- size : self . size ,
194
- } )
195
+ Ok ( Self { data : u128:: from ( f_int ( u64:: try_from ( self . data ) . unwrap ( ) ) ?) , size : self . size } )
195
196
}
196
197
197
198
#[ inline]
198
199
pub fn try_from_uint ( i : impl Into < u128 > , size : Size ) -> Option < Self > {
199
200
let data = i. into ( ) ;
200
201
if truncate ( data, size) == data {
201
- Some ( Self { bytes : data. to_ne_bytes ( ) , size : size. bytes ( ) as u8 } )
202
+ Some ( Self { data, size : size. bytes ( ) as u8 } )
202
203
} else {
203
204
None
204
205
}
@@ -210,7 +211,7 @@ impl ScalarInt {
210
211
// `into` performed sign extension, we have to truncate
211
212
let truncated = truncate ( i as u128 , size) ;
212
213
if sign_extend ( truncated, size) as i128 == i {
213
- Some ( Self { bytes : truncated. to_ne_bytes ( ) , size : size. bytes ( ) as u8 } )
214
+ Some ( Self { data : truncated, size : size. bytes ( ) as u8 } )
214
215
} else {
215
216
None
216
217
}
@@ -221,7 +222,7 @@ impl ScalarInt {
221
222
assert_ne ! ( target_size. bytes( ) , 0 , "you should never look at the bits of a ZST" ) ;
222
223
assert_eq ! ( target_size. bytes( ) , u64 :: from( self . size) ) ;
223
224
self . check_data ( ) ;
224
- self . data ( )
225
+ self . data
225
226
}
226
227
227
228
#[ inline]
@@ -234,7 +235,7 @@ impl ScalarInt {
234
235
} ) ;
235
236
}
236
237
self . check_data ( ) ;
237
- Ok ( self . data ( ) )
238
+ Ok ( self . data )
238
239
}
239
240
}
240
241
@@ -245,7 +246,7 @@ macro_rules! from {
245
246
#[ inline]
246
247
fn from( u: $ty) -> Self {
247
248
Self {
248
- bytes : u128 :: from( u) . to_ne_bytes ( ) ,
249
+ data : u128 :: from( u) ,
249
250
size: std:: mem:: size_of:: <$ty>( ) as u8 ,
250
251
}
251
252
}
@@ -274,7 +275,7 @@ try_from!(u8, u16, u32, u64, u128);
274
275
impl From < char > for ScalarInt {
275
276
#[ inline]
276
277
fn from ( c : char ) -> Self {
277
- Self { bytes : ( c as u128 ) . to_ne_bytes ( ) , size : std:: mem:: size_of :: < char > ( ) as u8 }
278
+ Self { data : c as u128 , size : std:: mem:: size_of :: < char > ( ) as u8 }
278
279
}
279
280
}
280
281
@@ -291,7 +292,7 @@ impl From<Single> for ScalarInt {
291
292
#[ inline]
292
293
fn from ( f : Single ) -> Self {
293
294
// We trust apfloat to give us properly truncated data.
294
- Self { bytes : f. to_bits ( ) . to_ne_bytes ( ) , size : 4 }
295
+ Self { data : f. to_bits ( ) , size : 4 }
295
296
}
296
297
}
297
298
@@ -307,7 +308,7 @@ impl From<Double> for ScalarInt {
307
308
#[ inline]
308
309
fn from ( f : Double ) -> Self {
309
310
// We trust apfloat to give us properly truncated data.
310
- Self { bytes : f. to_bits ( ) . to_ne_bytes ( ) , size : 8 }
311
+ Self { data : f. to_bits ( ) , size : 8 }
311
312
}
312
313
}
313
314
@@ -335,6 +336,6 @@ impl fmt::LowerHex for ScalarInt {
335
336
self . check_data ( ) ;
336
337
// Format as hex number wide enough to fit any value of the given `size`.
337
338
// So data=20, size=1 will be "0x14", but with size=4 it'll be "0x00000014".
338
- write ! ( f, "{:01$x}" , self . data( ) , self . size as usize * 2 )
339
+ write ! ( f, "{:01$x}" , { self . data } , self . size as usize * 2 )
339
340
}
340
341
}
0 commit comments