From ee69cd79255fbf98d755ff4556c4af4adda1befb Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Sat, 31 Dec 2016 04:55:29 +0200 Subject: [PATCH] Calculate discriminant bounds within 64 bits Since discriminants do not support i128 yet, lets just calculate the boundaries within the 64 bits that are supported. This also avoids an issue with bootstrapping on 32 bit systems due to #38727. --- src/librustc/ty/layout.rs | 20 +++++++++++++------- src/librustc_llvm/ffi.rs | 2 +- src/librustc_trans/abi.rs | 2 +- src/librustc_trans/mir/mod.rs | 1 + src/librustc_trans/mir/operand.rs | 2 +- 5 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 75600ddaabdb..ff95554dbbfc 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -20,7 +20,8 @@ use syntax::ast::{FloatTy, IntTy, UintTy}; use syntax::attr; use syntax_pos::DUMMY_SP; -use rustc_i128::{i128, u128}; +use rustc_i128::u128; +use rustc_const_math::ConstInt; use std::cmp; use std::fmt; @@ -1198,20 +1199,25 @@ pub fn compute_uncached(ty: Ty<'gcx>, if def.is_enum() && def.variants.iter().all(|v| v.fields.is_empty()) { // All bodies empty -> intlike - let (mut min, mut max, mut non_zero) = (i128::max_value(), - i128::min_value(), + let (mut min, mut max, mut non_zero) = (i64::max_value(), + i64::min_value(), true); for v in &def.variants { - let x = v.disr_val.to_u128_unchecked() as i128; + let x = match v.disr_val.erase_type() { + ConstInt::InferSigned(i) => i as i64, + ConstInt::Infer(i) => i as u64 as i64, + _ => bug!() + }; if x == 0 { non_zero = false; } if x < min { min = x; } if x > max { max = x; } } - // FIXME: should take i128? + // FIXME: should handle i128? signed-value based impl is weird and hard to + // grok. let (discr, signed) = Integer::repr_discr(tcx, ty, &hints[..], - min as i64, - max as i64); + min, + max); return success(CEnum { discr: discr, signed: signed, diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index fb188252075e..6815da4cc20f 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -33,7 +33,7 @@ pub enum LLVMRustResult { // Consts for the LLVM CallConv type, pre-cast to usize. /// LLVM CallingConv::ID. Should we wrap this? -#[derive(Copy, Clone, PartialEq)] +#[derive(Copy, Clone, PartialEq, Debug)] #[repr(C)] pub enum CallConv { CCallConv = 0, diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index 3fba75bc253c..65e752232f6a 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -313,7 +313,7 @@ pub fn store_fn_arg(&self, bcx: &BlockAndBuilder, idx: &mut usize, dst: ValueRef /// /// I will do my best to describe this structure, but these /// comments are reverse-engineered and may be inaccurate. -NDM -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct FnType { /// The LLVM types of each argument. pub args: Vec, diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs index 7a50e5cbe8c7..a1373cb9482b 100644 --- a/src/librustc_trans/mir/mod.rs +++ b/src/librustc_trans/mir/mod.rs @@ -205,6 +205,7 @@ pub fn trans_mir<'a, 'tcx: 'a>( sig: &ty::FnSig<'tcx>, abi: Abi, ) { + debug!("fn_ty: {:?}", fn_ty); let debug_context = debuginfo::create_function_debug_context(fcx.ccx, instance, sig, abi, fcx.llfn, mir); let bcx = fcx.get_entry_block(); diff --git a/src/librustc_trans/mir/operand.rs b/src/librustc_trans/mir/operand.rs index a15d51d9da64..526155655af2 100644 --- a/src/librustc_trans/mir/operand.rs +++ b/src/librustc_trans/mir/operand.rs @@ -79,7 +79,7 @@ impl<'a, 'tcx> OperandRef<'tcx> { pub fn immediate(self) -> ValueRef { match self.val { OperandValue::Immediate(s) => s, - _ => bug!() + _ => bug!("not immediate: {:?}", self) } }