@@ -10,6 +10,7 @@ use rustc::mir::interpret::{
1010 GlobalId , AllocId , InboundsCheck ,
1111 ConstValue , Pointer , Scalar ,
1212 EvalResult , EvalErrorKind ,
13+ sign_extend, truncate,
1314} ;
1415use super :: {
1516 EvalContext , Machine , AllocMap , Allocation , AllocationExtra ,
@@ -633,20 +634,17 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
633634 Err ( _) => return err ! ( InvalidDiscriminant ( raw_discr. erase_tag( ) ) ) ,
634635 } ;
635636 let real_discr = if discr_val. layout . ty . is_signed ( ) {
636- let i = bits_discr as i128 ;
637637 // going from layout tag type to typeck discriminant type
638638 // 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 ;
641640 // and then zeroing with the typeck discriminant type
642641 let discr_ty = rval. layout . ty
643642 . ty_adt_def ( ) . expect ( "tagged layout corresponds to adt" )
644643 . repr
645644 . 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 ( ) ;
648646 let truncatee = sexted as u128 ;
649- ( truncatee << shift ) >> shift
647+ truncate ( truncatee, size )
650648 } else {
651649 bits_discr
652650 } ;
0 commit comments