Skip to content
Permalink
Browse files

factor getting the discriminant layout to a new method

  • Loading branch information...
RalfJung committed Sep 16, 2019
1 parent b73f1a5 commit 75fe84f4fc764e0684e7fdafbe6139cc92082a44
Showing with 15 additions and 17 deletions.
  1. +11 −0 src/librustc/ty/layout.rs
  2. +2 −8 src/librustc_mir/interpret/operand.rs
  3. +2 −9 src/librustc_mir/interpret/place.rs
@@ -127,6 +127,7 @@ impl IntegerExt for Integer {

pub trait PrimitiveExt {
fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>;
fn to_int_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>;
}

impl PrimitiveExt for Primitive {
@@ -138,6 +139,16 @@ impl PrimitiveExt for Primitive {
Pointer => tcx.mk_mut_ptr(tcx.mk_unit()),
}
}

/// Return an *integer* type matching this primitive.
/// Useful in particular when dealing with enum discriminants.
fn to_int_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
match *self {
Int(i, signed) => i.to_ty(tcx, signed),
Pointer => tcx.types.usize,
Float(..) => bug!("floats do not have an int type"),
}
}
}

/// The first half of a fat pointer.
@@ -5,7 +5,7 @@ use std::convert::TryInto;

use rustc::{mir, ty};
use rustc::ty::layout::{
self, Size, LayoutOf, TyLayout, HasDataLayout, IntegerExt, VariantIdx,
self, Size, LayoutOf, TyLayout, HasDataLayout, IntegerExt, PrimitiveExt, VariantIdx,
};

use rustc::mir::interpret::{
@@ -687,13 +687,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
(dataful_variant.as_u32() as u128, dataful_variant)
},
Ok(raw_discr) => {
// FIXME: WTF, some discriminants don't have integer type.
use layout::Primitive;
let discr_layout = self.layout_of(match discr_layout.value {
Primitive::Int(int, signed) => int.to_ty(*self.tcx, signed),
Primitive::Pointer => self.tcx.types.usize,
Primitive::Float(..) => bug!("there are no float discriminants"),
})?;
let discr_layout = self.layout_of(discr_layout.value.to_int_ty(*self.tcx))?;
let discr_val = ImmTy::from_uint(raw_discr, discr_layout);
// We need to use machine arithmetic.
let niche_start_val = ImmTy::from_uint(niche_start, discr_layout);
@@ -9,7 +9,7 @@ use rustc::mir;
use rustc::mir::interpret::truncate;
use rustc::ty::{self, Ty};
use rustc::ty::layout::{
self, Size, Align, LayoutOf, TyLayout, HasDataLayout, VariantIdx, IntegerExt
self, Size, Align, LayoutOf, TyLayout, HasDataLayout, VariantIdx, PrimitiveExt
};
use rustc::ty::TypeFoldable;

@@ -1060,14 +1060,7 @@ where
variant_index.as_usize() < dest.layout.ty.ty_adt_def().unwrap().variants.len(),
);
if variant_index != dataful_variant {
// FIXME: WTF, some discriminants don't have integer type.
use layout::Primitive;
let discr_layout = self.layout_of(match discr_layout.value {
Primitive::Int(int, signed) => int.to_ty(*self.tcx, signed),
Primitive::Pointer => self.tcx.types.usize,
Primitive::Float(..) => bug!("there are no float discriminants"),
})?;

let discr_layout = self.layout_of(discr_layout.value.to_int_ty(*self.tcx))?;
// We need to use machine arithmetic.
let variants_start = niche_variants.start().as_u32();
let variants_start_val = ImmTy::from_uint(variants_start, discr_layout);

0 comments on commit 75fe84f

Please sign in to comment.
You can’t perform that action at this time.