@@ -2,7 +2,6 @@ use crate::mir::interpret::{sign_extend, truncate, InterpErrorInfo, InterpResult
22use crate :: throw_ub;
33use rustc_apfloat:: ieee:: { Double , Single } ;
44use rustc_apfloat:: Float ;
5- use rustc_macros:: HashStable ;
65use rustc_serialize:: { Decodable , Decoder , Encodable , Encoder } ;
76use rustc_target:: abi:: { Size , TargetDataLayout } ;
87use std:: convert:: { TryFrom , TryInto } ;
@@ -29,7 +28,7 @@ impl std::fmt::Debug for ConstInt {
2928 fn fmt ( & self , fmt : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
3029 let Self { int, signed, is_ptr_sized_integral } = * self ;
3130 let size = int. size ( ) . bytes ( ) ;
32- let raw = int. data ( ) ;
31+ let raw = int. data ;
3332 if signed {
3433 let bit_size = size * 8 ;
3534 let min = 1u128 << ( bit_size - 1 ) ;
@@ -116,41 +115,46 @@ impl std::fmt::Debug for ConstInt {
116115
117116// FIXME: reuse in `super::int::ConstInt` and `Scalar::Bits`
118117/// 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).
119121#[ derive( Clone , Copy , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
120- #[ derive ( HashStable ) ]
122+ #[ repr ( packed ) ]
121123pub struct ScalarInt {
122124 /// The first `size` bytes of `data` are the value.
123125 /// 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 ,
128127 size : u8 ,
129128}
130129
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+
131139impl < S : Encoder > Encodable < S > for ScalarInt {
132140 fn encode ( & self , s : & mut S ) -> Result < ( ) , S :: Error > {
133- s. emit_u128 ( self . data ( ) ) ?;
141+ s. emit_u128 ( self . data ) ?;
134142 s. emit_u8 ( self . size )
135143 }
136144}
137145
138146impl < D : Decoder > Decodable < D > for ScalarInt {
139147 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 ( ) ? } )
141149 }
142150}
143151
144152impl 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 } ;
146154
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 } ;
148156
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 } ;
154158
155159 #[ inline]
156160 pub fn size ( self ) -> Size {
@@ -164,10 +168,10 @@ impl ScalarInt {
164168 #[ inline( always) ]
165169 fn check_data ( self ) {
166170 debug_assert_eq ! (
167- truncate( self . data( ) , self . size( ) ) ,
168- self . data( ) ,
171+ truncate( self . data, self . size( ) ) ,
172+ { self . data } ,
169173 "Scalar value {:#x} exceeds size of {} bytes" ,
170- self . data( ) ,
174+ { self . data } ,
171175 self . size
172176 ) ;
173177 }
@@ -179,7 +183,7 @@ impl ScalarInt {
179183
180184 #[ inline]
181185 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 }
183187 }
184188
185189 pub ( crate ) fn ptr_sized_op < ' tcx > (
@@ -188,17 +192,14 @@ impl ScalarInt {
188192 f_int : impl FnOnce ( u64 ) -> InterpResult < ' tcx , u64 > ,
189193 ) -> InterpResult < ' tcx , Self > {
190194 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 } )
195196 }
196197
197198 #[ inline]
198199 pub fn try_from_uint ( i : impl Into < u128 > , size : Size ) -> Option < Self > {
199200 let data = i. into ( ) ;
200201 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 } )
202203 } else {
203204 None
204205 }
@@ -210,7 +211,7 @@ impl ScalarInt {
210211 // `into` performed sign extension, we have to truncate
211212 let truncated = truncate ( i as u128 , size) ;
212213 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 } )
214215 } else {
215216 None
216217 }
@@ -221,7 +222,7 @@ impl ScalarInt {
221222 assert_ne ! ( target_size. bytes( ) , 0 , "you should never look at the bits of a ZST" ) ;
222223 assert_eq ! ( target_size. bytes( ) , u64 :: from( self . size) ) ;
223224 self . check_data ( ) ;
224- self . data ( )
225+ self . data
225226 }
226227
227228 #[ inline]
@@ -234,7 +235,7 @@ impl ScalarInt {
234235 } ) ;
235236 }
236237 self . check_data ( ) ;
237- Ok ( self . data ( ) )
238+ Ok ( self . data )
238239 }
239240}
240241
@@ -245,7 +246,7 @@ macro_rules! from {
245246 #[ inline]
246247 fn from( u: $ty) -> Self {
247248 Self {
248- bytes : u128 :: from( u) . to_ne_bytes ( ) ,
249+ data : u128 :: from( u) ,
249250 size: std:: mem:: size_of:: <$ty>( ) as u8 ,
250251 }
251252 }
@@ -274,7 +275,7 @@ try_from!(u8, u16, u32, u64, u128);
274275impl From < char > for ScalarInt {
275276 #[ inline]
276277 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 }
278279 }
279280}
280281
@@ -291,7 +292,7 @@ impl From<Single> for ScalarInt {
291292 #[ inline]
292293 fn from ( f : Single ) -> Self {
293294 // 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 }
295296 }
296297}
297298
@@ -307,7 +308,7 @@ impl From<Double> for ScalarInt {
307308 #[ inline]
308309 fn from ( f : Double ) -> Self {
309310 // 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 }
311312 }
312313}
313314
@@ -335,6 +336,6 @@ impl fmt::LowerHex for ScalarInt {
335336 self . check_data ( ) ;
336337 // Format as hex number wide enough to fit any value of the given `size`.
337338 // 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 )
339340 }
340341}
0 commit comments