@@ -10,6 +10,7 @@ use rustc::mir::interpret::{
10
10
GlobalId , AllocId , InboundsCheck ,
11
11
ConstValue , Pointer , Scalar ,
12
12
EvalResult , EvalErrorKind ,
13
+ sign_extend, truncate,
13
14
} ;
14
15
use super :: {
15
16
EvalContext , Machine , AllocMap , Allocation , AllocationExtra ,
@@ -633,20 +634,17 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
633
634
Err ( _) => return err ! ( InvalidDiscriminant ( raw_discr. erase_tag( ) ) ) ,
634
635
} ;
635
636
let real_discr = if discr_val. layout . ty . is_signed ( ) {
636
- let i = bits_discr as i128 ;
637
637
// going from layout tag type to typeck discriminant type
638
638
// requires first sign extending with the layout discriminant
639
- let shift = 128 - discr_val. layout . size . bits ( ) ;
640
- let sexted = ( i << shift) >> shift;
639
+ let sexted = sign_extend ( bits_discr, discr_val. layout . size ) as i128 ;
641
640
// and then zeroing with the typeck discriminant type
642
641
let discr_ty = rval. layout . ty
643
642
. ty_adt_def ( ) . expect ( "tagged layout corresponds to adt" )
644
643
. repr
645
644
. discr_type ( ) ;
646
- let discr_ty = layout:: Integer :: from_attr ( self , discr_ty) ;
647
- let shift = 128 - discr_ty. size ( ) . bits ( ) ;
645
+ let size = layout:: Integer :: from_attr ( self , discr_ty) . size ( ) ;
648
646
let truncatee = sexted as u128 ;
649
- ( truncatee << shift ) >> shift
647
+ truncate ( truncatee, size )
650
648
} else {
651
649
bits_discr
652
650
} ;
0 commit comments