diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 5ec4754c4535b..e52feea1624c1 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.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. diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 2a0bad2fa746c..94fbd4ac7d7f3 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -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); diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 636b070a3d8f3..9a3d70144a586 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -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);