@@ -302,38 +302,33 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
302
302
let right = right. to_scalar ( ) ?;
303
303
304
304
trace ! ( "Running binary op {:?}: {:?} ({:?}), {:?} ({:?})" ,
305
- bin_op, left, left_layout. ty. sty , right, right_layout. ty. sty ) ;
305
+ bin_op, left, left_layout. ty, right, right_layout. ty) ;
306
306
307
307
match left_layout. ty . sty {
308
308
ty:: Char => {
309
309
assert_eq ! ( left_layout. ty, right_layout. ty) ;
310
- let l = left. to_char ( ) ?;
311
- let r = right. to_char ( ) ?;
312
- self . binary_char_op ( bin_op, l , r )
310
+ let left = left. to_char ( ) ?;
311
+ let right = right. to_char ( ) ?;
312
+ self . binary_char_op ( bin_op, left , right )
313
313
}
314
314
ty:: Bool => {
315
315
assert_eq ! ( left_layout. ty, right_layout. ty) ;
316
- let l = left. to_bool ( ) ?;
317
- let r = right. to_bool ( ) ?;
318
- self . binary_bool_op ( bin_op, l , r )
316
+ let left = left. to_bool ( ) ?;
317
+ let right = right. to_bool ( ) ?;
318
+ self . binary_bool_op ( bin_op, left , right )
319
319
}
320
320
ty:: Float ( fty) => {
321
321
assert_eq ! ( left_layout. ty, right_layout. ty) ;
322
- let l = left. to_bits ( left_layout. size ) ?;
323
- let r = right. to_bits ( right_layout. size ) ?;
324
- self . binary_float_op ( bin_op, fty, l , r )
322
+ let left = left. to_bits ( left_layout. size ) ?;
323
+ let right = right. to_bits ( right_layout. size ) ?;
324
+ self . binary_float_op ( bin_op, fty, left , right )
325
325
}
326
326
_ => {
327
- // Must be integer(-like) types
328
- #[ inline]
329
- fn is_ptr < ' tcx > ( ty : ty:: Ty < ' tcx > ) -> bool {
330
- match ty. sty {
331
- ty:: RawPtr ( ..) | ty:: Ref ( ..) | ty:: FnPtr ( ..) => true ,
332
- _ => false ,
333
- }
334
- }
335
- assert ! ( left_layout. ty. is_integral( ) || is_ptr( left_layout. ty) ) ;
336
- assert ! ( right_layout. ty. is_integral( ) || is_ptr( right_layout. ty) ) ;
327
+ // Must be integer(-like) types. Don't forget about == on fn pointers.
328
+ assert ! ( left_layout. ty. is_integral( ) || left_layout. ty. is_unsafe_ptr( ) ||
329
+ left_layout. ty. is_fn( ) ) ;
330
+ assert ! ( right_layout. ty. is_integral( ) || right_layout. ty. is_unsafe_ptr( ) ||
331
+ right_layout. ty. is_fn( ) ) ;
337
332
338
333
// Handle operations that support pointer values
339
334
if let Some ( handled) =
@@ -343,9 +338,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
343
338
}
344
339
345
340
// Everything else only works with "proper" bits
346
- let l = left. to_bits ( left_layout. size ) ?;
347
- let r = right. to_bits ( right_layout. size ) ?;
348
- self . binary_int_op ( bin_op, l , left_layout, r , right_layout)
341
+ let left = left. to_bits ( left_layout. size ) ?;
342
+ let right = right. to_bits ( right_layout. size ) ?;
343
+ self . binary_int_op ( bin_op, left , left_layout, right , right_layout)
349
344
}
350
345
}
351
346
}
@@ -360,25 +355,42 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
360
355
use rustc_apfloat:: ieee:: { Single , Double } ;
361
356
use rustc_apfloat:: Float ;
362
357
363
- let size = layout. size ;
364
- let bytes = val. to_bits ( size) ?;
365
-
366
- let result_bytes = match ( un_op, & layout. ty . sty ) {
367
-
368
- ( Not , ty:: Bool ) => !val. to_bool ( ) ? as u128 ,
369
-
370
- ( Not , _) => !bytes,
358
+ trace ! ( "Running unary op {:?}: {:?} ({:?})" , un_op, val, layout. ty. sty) ;
371
359
372
- ( Neg , ty:: Float ( FloatTy :: F32 ) ) => Single :: to_bits ( -Single :: from_bits ( bytes) ) ,
373
- ( Neg , ty:: Float ( FloatTy :: F64 ) ) => Double :: to_bits ( -Double :: from_bits ( bytes) ) ,
374
-
375
- ( Neg , _) if bytes == ( 1 << ( size. bits ( ) - 1 ) ) => return err ! ( OverflowNeg ) ,
376
- ( Neg , _) => ( -( bytes as i128 ) ) as u128 ,
377
- } ;
378
-
379
- Ok ( Scalar :: Bits {
380
- bits : self . truncate ( result_bytes, layout) ,
381
- size : size. bytes ( ) as u8 ,
382
- } )
360
+ match layout. ty . sty {
361
+ ty:: Bool => {
362
+ let val = val. to_bool ( ) ?;
363
+ let res = match un_op {
364
+ Not => !val,
365
+ _ => bug ! ( "Invalid bool op {:?}" , un_op)
366
+ } ;
367
+ Ok ( Scalar :: from_bool ( res) )
368
+ }
369
+ ty:: Float ( fty) => {
370
+ let val = val. to_bits ( layout. size ) ?;
371
+ let res = match ( un_op, fty) {
372
+ ( Neg , FloatTy :: F32 ) => Single :: to_bits ( -Single :: from_bits ( val) ) ,
373
+ ( Neg , FloatTy :: F64 ) => Double :: to_bits ( -Double :: from_bits ( val) ) ,
374
+ _ => bug ! ( "Invalid float op {:?}" , un_op)
375
+ } ;
376
+ Ok ( Scalar :: Bits { bits : res, size : layout. size . bytes ( ) as u8 } )
377
+ }
378
+ _ => {
379
+ assert ! ( layout. ty. is_integral( ) ) ;
380
+ let val = val. to_bits ( layout. size ) ?;
381
+ let res = match un_op {
382
+ Not => !val,
383
+ Neg => {
384
+ assert ! ( layout. abi. is_signed( ) ) ;
385
+ ( -( val as i128 ) ) as u128
386
+ }
387
+ } ;
388
+ // res needs tuncating
389
+ Ok ( Scalar :: Bits {
390
+ bits : self . truncate ( res, layout) ,
391
+ size : layout. size . bytes ( ) as u8 ,
392
+ } )
393
+ }
394
+ }
383
395
}
384
396
}
0 commit comments