1
1
//! Functions concerning immediate values and operands, and reading from operands.
2
2
//! All high-level functions to read from memory work on operands as sources.
3
3
4
- use std:: convert:: TryInto ;
4
+ use std:: convert:: { TryInto , TryFrom } ;
5
5
6
6
use rustc:: { mir, ty} ;
7
7
use rustc:: ty:: layout:: {
@@ -671,8 +671,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
671
671
ref niche_variants,
672
672
niche_start,
673
673
} => {
674
- let variants_start = niche_variants. start ( ) . as_u32 ( ) as u128 ;
675
- let variants_end = niche_variants. end ( ) . as_u32 ( ) as u128 ;
674
+ let variants_start = niche_variants. start ( ) . as_u32 ( ) ;
675
+ let variants_end = niche_variants. end ( ) . as_u32 ( ) ;
676
676
let raw_discr = raw_discr. not_undef ( ) . map_err ( |_| {
677
677
err_unsup ! ( InvalidDiscriminant ( ScalarMaybeUndef :: Undef ) )
678
678
} ) ?;
@@ -687,7 +687,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
687
687
( dataful_variant. as_u32 ( ) as u128 , dataful_variant)
688
688
} ,
689
689
Ok ( raw_discr) => {
690
- // We need to use machine arithmetic to get the relative variant idx.
690
+ // We need to use machine arithmetic to get the relative variant idx:
691
+ // variant_index_relative = discr_val - niche_start_val
691
692
let discr_layout = self . layout_of ( discr_layout. value . to_int_ty ( * self . tcx ) ) ?;
692
693
let discr_val = ImmTy :: from_uint ( raw_discr, discr_layout) ;
693
694
let niche_start_val = ImmTy :: from_uint ( niche_start, discr_layout) ;
@@ -699,21 +700,21 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
699
700
let variant_index_relative = variant_index_relative_val
700
701
. to_scalar ( ) ?
701
702
. assert_bits ( discr_val. layout . size ) ;
702
- // Then computing the absolute variant idx should not overflow any more.
703
- let variant_index = variants_start
704
- . checked_add ( variant_index_relative)
705
- . expect ( "oveflow computing absolute variant idx" ) ;
706
703
// Check if this is in the range that indicates an actual discriminant.
707
- if variants_start <= variant_index && variant_index <= variants_end {
708
- let index = variant_index as usize ;
709
- assert_eq ! ( index as u128 , variant_index) ;
710
- assert ! ( index < rval. layout. ty
704
+ if variant_index_relative <= u128:: from ( variants_end - variants_start) {
705
+ let variant_index_relative = u32:: try_from ( variant_index_relative)
706
+ . expect ( "we checked that this fits into a u32" ) ;
707
+ // Then computing the absolute variant idx should not overflow any more.
708
+ let variant_index = variants_start
709
+ . checked_add ( variant_index_relative)
710
+ . expect ( "oveflow computing absolute variant idx" ) ;
711
+ assert ! ( ( variant_index as usize ) < rval. layout. ty
711
712
. ty_adt_def( )
712
713
. expect( "tagged layout for non adt" )
713
714
. variants. len( ) ) ;
714
- ( variant_index, VariantIdx :: from_usize ( index ) )
715
+ ( u128 :: from ( variant_index) , VariantIdx :: from_u32 ( variant_index ) )
715
716
} else {
716
- ( dataful_variant. as_u32 ( ) as u128 , dataful_variant)
717
+ ( u128 :: from ( dataful_variant. as_u32 ( ) ) , dataful_variant)
717
718
}
718
719
} ,
719
720
}
0 commit comments