From 25930e47ba0f53b6ff3bd439f6478747884a05b2 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sun, 5 Apr 2020 20:02:55 +0200 Subject: [PATCH] update codegen of `discriminant_value` --- src/librustc_codegen_llvm/intrinsic.rs | 12 +++++++++--- src/librustc_mir/interpret/intrinsics.rs | 9 ++++++--- src/librustc_typeck/check/intrinsic.rs | 2 +- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index ddf21ff6338e..1e6d2e3dbb74 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -188,11 +188,11 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { } "size_of" | "pref_align_of" | "min_align_of" | "needs_drop" | "type_id" | "type_name" => { - let ty_name = self + let value = self .tcx .const_eval_instance(ty::ParamEnv::reveal_all(), instance, None) .unwrap(); - OperandRef::from_const(self, ty_name, ret_ty).immediate_or_packed_pair(self) + OperandRef::from_const(self, value, ret_ty).immediate_or_packed_pair(self) } // Effectively no-op "forget" => { @@ -549,7 +549,13 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { } } - "discriminant_value" => args[0].deref(self.cx()).codegen_get_discr(self, ret_ty), + "discriminant_value" => { + if ret_ty.is_integral() { + args[0].deref(self.cx()).codegen_get_discr(self, ret_ty) + } else { + span_bug!(span, "Invalid discriminant type for `{:?}`", arg_tys[0]) + } + } name if name.starts_with("simd_") => { match generic_simd_intrinsic(self, name, callee_ty, args, ret_ty, llret_ty, span) { diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index c8bf328ce8ee..42b969c99917 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -2,8 +2,6 @@ //! looking at their MIR. Intrinsics/functions supported here are shared by CTFE //! and miri. -use std::convert::TryFrom; - use rustc_hir::def_id::DefId; use rustc_middle::mir::{ self, @@ -220,7 +218,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { sym::discriminant_value => { let place = self.deref_operand(args[0])?; let discr_val = self.read_discriminant(place.into())?.0; - self.write_scalar(Scalar::from_u64(u64::try_from(discr_val).unwrap()), dest)?; + let scalar = match dest.layout.ty.kind { + ty::Int(_) => Scalar::from_int(discr_val as i128, dest.layout.size), + ty::Uint(_) => Scalar::from_uint(discr_val, dest.layout.size), + _ => bug!("invalid `discriminant_value` return layout: {:?}", dest.layout), + }; + self.write_scalar(scalar, dest)?; } sym::unchecked_shl | sym::unchecked_shr diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 68f9025fd19e..bded2c695c9d 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -8,7 +8,7 @@ use rustc_hir as hir; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::subst::Subst; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_span::symbol::{Ident, Symbol}; +use rustc_span::symbol::Symbol; use rustc_target::spec::abi::Abi; use std::iter;