Skip to content

Commit 1de533a

Browse files
committed
first determine if the variant is a niche-variant, then compute absolute variant
1 parent b21622c commit 1de533a

File tree

2 files changed

+17
-15
lines changed

2 files changed

+17
-15
lines changed

src/librustc_mir/interpret/operand.rs

+15-14
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
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

66
use rustc::{mir, ty};
77
use 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
}

src/librustc_mir/interpret/place.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1064,7 +1064,8 @@ where
10641064
let variant_index_relative = variant_index.as_u32()
10651065
.checked_sub(variants_start)
10661066
.expect("overflow computing relative variant idx");
1067-
// We need to use machine arithmetic when taking into account `niche_start`.
1067+
// We need to use machine arithmetic when taking into account `niche_start`:
1068+
// discr_val = variant_index_relative + niche_start_val
10681069
let discr_layout = self.layout_of(discr_layout.value.to_int_ty(*self.tcx))?;
10691070
let niche_start_val = ImmTy::from_uint(niche_start, discr_layout);
10701071
let variant_index_relative_val =

0 commit comments

Comments
 (0)