@@ -8,9 +8,9 @@ use rustc_apfloat::{
8
8
use rustc_macros:: HashStable ;
9
9
use rustc_target:: abi:: { HasDataLayout , Size , TargetDataLayout } ;
10
10
11
- use crate :: ty:: { ParamEnv , Ty , TyCtxt } ;
11
+ use crate :: ty:: { ParamEnv , ScalarInt , Ty , TyCtxt } ;
12
12
13
- use super :: { sign_extend, truncate , AllocId , Allocation , InterpResult , Pointer , PointerArithmetic } ;
13
+ use super :: { sign_extend, AllocId , Allocation , InterpResult , Pointer , PointerArithmetic } ;
14
14
15
15
/// Represents the result of const evaluation via the `eval_to_allocation` query.
16
16
#[ derive( Clone , HashStable , TyEncodable , TyDecodable ) ]
@@ -103,12 +103,7 @@ impl<'tcx> ConstValue<'tcx> {
103
103
#[ derive( HashStable ) ]
104
104
pub enum Scalar < Tag = ( ) > {
105
105
/// The raw bytes of a simple value.
106
- Raw {
107
- /// The first `size` bytes of `data` are the value.
108
- /// Do not try to read less or more bytes than that. The remaining bytes must be 0.
109
- data : u128 ,
110
- size : u8 ,
111
- } ,
106
+ Raw ( ScalarInt ) ,
112
107
113
108
/// A pointer into an `Allocation`. An `Allocation` in the `memory` module has a list of
114
109
/// relocations, but a `Scalar` is only large enough to contain one, so we just represent the
@@ -125,16 +120,7 @@ impl<Tag: fmt::Debug> fmt::Debug for Scalar<Tag> {
125
120
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
126
121
match self {
127
122
Scalar :: Ptr ( ptr) => write ! ( f, "{:?}" , ptr) ,
128
- & Scalar :: Raw { data, size } => {
129
- Scalar :: check_data ( data, size) ;
130
- if size == 0 {
131
- write ! ( f, "<ZST>" )
132
- } else {
133
- // Format as hex number wide enough to fit any value of the given `size`.
134
- // So data=20, size=1 will be "0x14", but with size=4 it'll be "0x00000014".
135
- write ! ( f, "0x{:>0width$x}" , data, width = ( size * 2 ) as usize )
136
- }
137
- }
123
+ Scalar :: Raw ( int) => write ! ( f, "{:?}" , int) ,
138
124
}
139
125
}
140
126
}
@@ -163,29 +149,14 @@ impl<Tag> From<Double> for Scalar<Tag> {
163
149
}
164
150
165
151
impl Scalar < ( ) > {
166
- /// Make sure the `data` fits in `size`.
167
- /// This is guaranteed by all constructors here, but since the enum variants are public,
168
- /// it could still be violated (even though no code outside this file should
169
- /// construct `Scalar`s).
170
- #[ inline( always) ]
171
- fn check_data ( data : u128 , size : u8 ) {
172
- debug_assert_eq ! (
173
- truncate( data, Size :: from_bytes( u64 :: from( size) ) ) ,
174
- data,
175
- "Scalar value {:#x} exceeds size of {} bytes" ,
176
- data,
177
- size
178
- ) ;
179
- }
180
-
181
152
/// Tag this scalar with `new_tag` if it is a pointer, leave it unchanged otherwise.
182
153
///
183
154
/// Used by `MemPlace::replace_tag`.
184
155
#[ inline]
185
156
pub fn with_tag < Tag > ( self , new_tag : Tag ) -> Scalar < Tag > {
186
157
match self {
187
158
Scalar :: Ptr ( ptr) => Scalar :: Ptr ( ptr. with_tag ( new_tag) ) ,
188
- Scalar :: Raw { data , size } => Scalar :: Raw { data , size } ,
159
+ Scalar :: Raw ( int ) => Scalar :: Raw ( int ) ,
189
160
}
190
161
}
191
162
}
@@ -198,18 +169,18 @@ impl<'tcx, Tag> Scalar<Tag> {
198
169
pub fn erase_tag ( self ) -> Scalar {
199
170
match self {
200
171
Scalar :: Ptr ( ptr) => Scalar :: Ptr ( ptr. erase_tag ( ) ) ,
201
- Scalar :: Raw { data , size } => Scalar :: Raw { data , size } ,
172
+ Scalar :: Raw ( int ) => Scalar :: Raw ( int ) ,
202
173
}
203
174
}
204
175
205
176
#[ inline]
206
177
pub fn null_ptr ( cx : & impl HasDataLayout ) -> Self {
207
- Scalar :: Raw { data : 0 , size : cx. data_layout ( ) . pointer_size . bytes ( ) as u8 }
178
+ Scalar :: Raw ( ScalarInt :: null ( cx. data_layout ( ) . pointer_size ) )
208
179
}
209
180
210
181
#[ inline]
211
182
pub fn zst ( ) -> Self {
212
- Scalar :: Raw { data : 0 , size : 0 }
183
+ Scalar :: Raw ( ScalarInt :: zst ( ) )
213
184
}
214
185
215
186
#[ inline( always) ]
@@ -220,10 +191,7 @@ impl<'tcx, Tag> Scalar<Tag> {
220
191
f_ptr : impl FnOnce ( Pointer < Tag > ) -> InterpResult < ' tcx , Pointer < Tag > > ,
221
192
) -> InterpResult < ' tcx , Self > {
222
193
match self {
223
- Scalar :: Raw { data, size } => {
224
- assert_eq ! ( u64 :: from( size) , dl. pointer_size. bytes( ) ) ;
225
- Ok ( Scalar :: Raw { data : u128:: from ( f_int ( u64:: try_from ( data) . unwrap ( ) ) ?) , size } )
226
- }
194
+ Scalar :: Raw ( int) => Ok ( Scalar :: Raw ( int. ptr_sized_op ( dl, f_int) ?) ) ,
227
195
Scalar :: Ptr ( ptr) => Ok ( Scalar :: Ptr ( f_ptr ( ptr) ?) ) ,
228
196
}
229
197
}
@@ -264,24 +232,17 @@ impl<'tcx, Tag> Scalar<Tag> {
264
232
265
233
#[ inline]
266
234
pub fn from_bool ( b : bool ) -> Self {
267
- // Guaranteed to be truncated and does not need sign extension.
268
- Scalar :: Raw { data : b as u128 , size : 1 }
235
+ Scalar :: Raw ( b. into ( ) )
269
236
}
270
237
271
238
#[ inline]
272
239
pub fn from_char ( c : char ) -> Self {
273
- // Guaranteed to be truncated and does not need sign extension.
274
- Scalar :: Raw { data : c as u128 , size : 4 }
240
+ Scalar :: Raw ( c. into ( ) )
275
241
}
276
242
277
243
#[ inline]
278
244
pub fn try_from_uint ( i : impl Into < u128 > , size : Size ) -> Option < Self > {
279
- let i = i. into ( ) ;
280
- if truncate ( i, size) == i {
281
- Some ( Scalar :: Raw { data : i, size : size. bytes ( ) as u8 } )
282
- } else {
283
- None
284
- }
245
+ ScalarInt :: try_from_uint ( i, size) . map ( Scalar :: Raw )
285
246
}
286
247
287
248
#[ inline]
@@ -293,26 +254,22 @@ impl<'tcx, Tag> Scalar<Tag> {
293
254
294
255
#[ inline]
295
256
pub fn from_u8 ( i : u8 ) -> Self {
296
- // Guaranteed to be truncated and does not need sign extension.
297
- Scalar :: Raw { data : i. into ( ) , size : 1 }
257
+ Scalar :: Raw ( i. into ( ) )
298
258
}
299
259
300
260
#[ inline]
301
261
pub fn from_u16 ( i : u16 ) -> Self {
302
- // Guaranteed to be truncated and does not need sign extension.
303
- Scalar :: Raw { data : i. into ( ) , size : 2 }
262
+ Scalar :: Raw ( i. into ( ) )
304
263
}
305
264
306
265
#[ inline]
307
266
pub fn from_u32 ( i : u32 ) -> Self {
308
- // Guaranteed to be truncated and does not need sign extension.
309
- Scalar :: Raw { data : i. into ( ) , size : 4 }
267
+ Scalar :: Raw ( i. into ( ) )
310
268
}
311
269
312
270
#[ inline]
313
271
pub fn from_u64 ( i : u64 ) -> Self {
314
- // Guaranteed to be truncated and does not need sign extension.
315
- Scalar :: Raw { data : i. into ( ) , size : 8 }
272
+ Scalar :: Raw ( i. into ( ) )
316
273
}
317
274
318
275
#[ inline]
@@ -322,14 +279,7 @@ impl<'tcx, Tag> Scalar<Tag> {
322
279
323
280
#[ inline]
324
281
pub fn try_from_int ( i : impl Into < i128 > , size : Size ) -> Option < Self > {
325
- let i = i. into ( ) ;
326
- // `into` performed sign extension, we have to truncate
327
- let truncated = truncate ( i as u128 , size) ;
328
- if sign_extend ( truncated, size) as i128 == i {
329
- Some ( Scalar :: Raw { data : truncated, size : size. bytes ( ) as u8 } )
330
- } else {
331
- None
332
- }
282
+ ScalarInt :: try_from_int ( i, size) . map ( Scalar :: Raw )
333
283
}
334
284
335
285
#[ inline]
@@ -366,14 +316,12 @@ impl<'tcx, Tag> Scalar<Tag> {
366
316
367
317
#[ inline]
368
318
pub fn from_f32 ( f : Single ) -> Self {
369
- // We trust apfloat to give us properly truncated data.
370
- Scalar :: Raw { data : f. to_bits ( ) , size : 4 }
319
+ Scalar :: Raw ( f. into ( ) )
371
320
}
372
321
373
322
#[ inline]
374
323
pub fn from_f64 ( f : Double ) -> Self {
375
- // We trust apfloat to give us properly truncated data.
376
- Scalar :: Raw { data : f. to_bits ( ) , size : 8 }
324
+ Scalar :: Raw ( f. into ( ) )
377
325
}
378
326
379
327
/// This is very rarely the method you want! You should dispatch on the type
@@ -388,11 +336,7 @@ impl<'tcx, Tag> Scalar<Tag> {
388
336
) -> Result < u128 , Pointer < Tag > > {
389
337
assert_ne ! ( target_size. bytes( ) , 0 , "you should never look at the bits of a ZST" ) ;
390
338
match self {
391
- Scalar :: Raw { data, size } => {
392
- assert_eq ! ( target_size. bytes( ) , u64 :: from( size) ) ;
393
- Scalar :: check_data ( data, size) ;
394
- Ok ( data)
395
- }
339
+ Scalar :: Raw ( int) => Ok ( int. assert_bits ( target_size) ) ,
396
340
Scalar :: Ptr ( ptr) => {
397
341
assert_eq ! ( target_size, cx. data_layout( ) . pointer_size) ;
398
342
Err ( ptr)
@@ -406,16 +350,7 @@ impl<'tcx, Tag> Scalar<Tag> {
406
350
fn to_bits ( self , target_size : Size ) -> InterpResult < ' tcx , u128 > {
407
351
assert_ne ! ( target_size. bytes( ) , 0 , "you should never look at the bits of a ZST" ) ;
408
352
match self {
409
- Scalar :: Raw { data, size } => {
410
- if target_size. bytes ( ) != u64:: from ( size) {
411
- throw_ub ! ( ScalarSizeMismatch {
412
- target_size: target_size. bytes( ) ,
413
- data_size: u64 :: from( size) ,
414
- } ) ;
415
- }
416
- Scalar :: check_data ( data, size) ;
417
- Ok ( data)
418
- }
353
+ Scalar :: Raw ( int) => int. to_bits ( target_size) ,
419
354
Scalar :: Ptr ( _) => throw_unsup ! ( ReadPointerAsBytes ) ,
420
355
}
421
356
}
0 commit comments