@@ -302,38 +302,33 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
302302 let right = right. to_scalar ( ) ?;
303303
304304 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) ;
306306
307307 match left_layout. ty . sty {
308308 ty:: Char => {
309309 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 )
313313 }
314314 ty:: Bool => {
315315 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 )
319319 }
320320 ty:: Float ( fty) => {
321321 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 )
325325 }
326326 _ => {
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( ) ) ;
337332
338333 // Handle operations that support pointer values
339334 if let Some ( handled) =
@@ -343,9 +338,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
343338 }
344339
345340 // 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)
349344 }
350345 }
351346 }
@@ -360,25 +355,42 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
360355 use rustc_apfloat:: ieee:: { Single , Double } ;
361356 use rustc_apfloat:: Float ;
362357
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) ;
371359
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+ }
383395 }
384396}
0 commit comments