11//! Functions concerning immediate values and operands, and reading from operands.
22//! All high-level functions to read from memory work on operands as sources.
33
4- use std:: convert:: TryInto ;
4+ use std:: convert:: { TryInto , TryFrom } ;
55
66use rustc:: { mir, ty} ;
77use rustc:: ty:: layout:: {
@@ -671,8 +671,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
671671 ref niche_variants,
672672 niche_start,
673673 } => {
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 ( ) ;
676676 let raw_discr = raw_discr. not_undef ( ) . map_err ( |_| {
677677 err_unsup ! ( InvalidDiscriminant ( ScalarMaybeUndef :: Undef ) )
678678 } ) ?;
@@ -687,7 +687,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
687687 ( dataful_variant. as_u32 ( ) as u128 , dataful_variant)
688688 } ,
689689 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
691692 let discr_layout = self . layout_of ( discr_layout. value . to_int_ty ( * self . tcx ) ) ?;
692693 let discr_val = ImmTy :: from_uint ( raw_discr, discr_layout) ;
693694 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> {
699700 let variant_index_relative = variant_index_relative_val
700701 . to_scalar ( ) ?
701702 . 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" ) ;
706703 // 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
711712 . ty_adt_def( )
712713 . expect( "tagged layout for non adt" )
713714 . variants. len( ) ) ;
714- ( variant_index, VariantIdx :: from_usize ( index ) )
715+ ( u128 :: from ( variant_index) , VariantIdx :: from_u32 ( variant_index ) )
715716 } else {
716- ( dataful_variant. as_u32 ( ) as u128 , dataful_variant)
717+ ( u128 :: from ( dataful_variant. as_u32 ( ) ) , dataful_variant)
717718 }
718719 } ,
719720 }
0 commit comments