diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 11b079806af2..d9bf93dd6793 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -517,7 +517,7 @@ rustc_queries! { /// Extracts a field of a (variant of a) const. query const_field( key: ty::ParamEnvAnd<'tcx, (&'tcx ty::Const<'tcx>, mir::Field)> - ) -> &'tcx ty::Const<'tcx> { + ) -> ConstValue<'tcx> { no_force desc { "extract field of const" } } @@ -531,7 +531,7 @@ rustc_queries! { desc { "destructure constant" } } - query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> &'tcx ty::Const<'tcx> { + query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> ConstValue<'tcx> { no_force desc { "get a &core::panic::Location referring to a span" } } diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index ddaaab412a47..33312e730f20 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -14,7 +14,7 @@ use crate::middle::resolve_lifetime::{ObjectLifetimeDefault, Region, ResolveLife use crate::middle::stability::{self, DeprecationEntry}; use crate::mir; use crate::mir::interpret::GlobalId; -use crate::mir::interpret::{ConstEvalRawResult, ConstEvalResult}; +use crate::mir::interpret::{ConstEvalRawResult, ConstEvalResult, ConstValue}; use crate::mir::interpret::{LitToConstError, LitToConstInput}; use crate::mir::mono::CodegenUnit; use crate::session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion}; diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 341a4a77c3c0..3d1e72e1c73d 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -193,8 +193,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { .tcx .const_eval_instance(ty::ParamEnv::reveal_all(), instance, None) .unwrap(); - let const_ = ty::Const { val: ty::ConstKind::Value(ty_name), ty: ret_ty }; - OperandRef::from_const(self, &const_).immediate_or_packed_pair(self) + OperandRef::from_const(self, ty_name, ret_ty).immediate_or_packed_pair(self) } "init" => { let ty = substs.type_at(0); diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 916c15eb1b6e..d684f842ddc6 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -991,7 +991,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { caller.line as u32, caller.col_display as u32 + 1, )); - OperandRef::from_const(bx, const_loc) + OperandRef::from_const(bx, const_loc, bx.tcx().caller_location_ty()) }) } diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs index d7e87419c171..8722aacca721 100644 --- a/src/librustc_codegen_ssa/mir/constant.rs +++ b/src/librustc_codegen_ssa/mir/constant.rs @@ -1,7 +1,7 @@ use crate::mir::operand::OperandRef; use crate::traits::*; use rustc::mir; -use rustc::mir::interpret::ErrorHandled; +use rustc::mir::interpret::{ConstValue, ErrorHandled}; use rustc::ty::layout::{self, HasTyCtxt}; use rustc::ty::{self, Ty}; use rustc_index::vec::Idx; @@ -30,7 +30,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } _ => { let val = self.eval_mir_constant(constant)?; - Ok(OperandRef::from_const(bx, &val)) + Ok(OperandRef::from_const(bx, val.clone(), constant.literal.ty)) } } } @@ -38,19 +38,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn eval_mir_constant( &mut self, constant: &mir::Constant<'tcx>, - ) -> Result<&'tcx ty::Const<'tcx>, ErrorHandled> { + ) -> Result, ErrorHandled> { match constant.literal.val { ty::ConstKind::Unevaluated(def_id, substs, promoted) => { let substs = self.monomorphize(&substs); self.cx .tcx() .const_eval_resolve(ty::ParamEnv::reveal_all(), def_id, substs, promoted, None) - .map(|val| { - self.cx.tcx().mk_const(ty::Const { - val: ty::ConstKind::Value(val), - ty: constant.literal.ty, - }) - }) .map_err(|err| { if promoted.is_none() { self.cx @@ -61,7 +55,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { err }) } - _ => Ok(self.monomorphize(&constant.literal)), + ty::ConstKind::Value(value) => Ok(value), + _ => { + let const_ = self.monomorphize(&constant.literal); + if let ty::ConstKind::Value(value) = const_.val { + Ok(value) + } else { + bug!("encountered bad ConstKind in codegen"); + } + } } } @@ -71,21 +73,22 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx: &Bx, span: Span, ty: Ty<'tcx>, - constant: Result<&'tcx ty::Const<'tcx>, ErrorHandled>, + constant: Result, ErrorHandled>, ) -> (Bx::Value, Ty<'tcx>) { constant - .map(|c| { - let field_ty = c.ty.builtin_index().unwrap(); - let fields = match c.ty.kind { + .map(|val| { + let field_ty = ty.builtin_index().unwrap(); + let fields = match ty.kind { ty::Array(_, n) => n.eval_usize(bx.tcx(), ty::ParamEnv::reveal_all()), - _ => bug!("invalid simd shuffle type: {}", c.ty), + _ => bug!("invalid simd shuffle type: {}", ty), }; + let c = bx.tcx().mk_const(ty::Const { val: ty::ConstKind::Value(val), ty }); let values: Vec<_> = (0..fields) .map(|field| { let field = bx.tcx().const_field( ty::ParamEnv::reveal_all().and((&c, mir::Field::new(field as usize))), ); - if let Some(prim) = field.val.try_to_scalar() { + if let Some(prim) = field.try_to_scalar() { let layout = bx.layout_of(field_ty); let scalar = match layout.abi { layout::Abi::Scalar(ref x) => x, diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index 7745606b8417..07c8829e7d88 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -8,8 +8,8 @@ use crate::MemFlags; use rustc::mir; use rustc::mir::interpret::{ConstValue, ErrorHandled, Pointer, Scalar}; -use rustc::ty; use rustc::ty::layout::{self, Align, LayoutOf, Size, TyLayout}; +use rustc::ty::Ty; use std::fmt; @@ -66,20 +66,16 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { pub fn from_const>( bx: &mut Bx, - val: &ty::Const<'tcx>, + val: ConstValue<'tcx>, + ty: Ty<'tcx>, ) -> Self { - let layout = bx.layout_of(val.ty); + let layout = bx.layout_of(ty); if layout.is_zst() { return OperandRef::new_zst(bx, layout); } - let val_val = match val.val { - ty::ConstKind::Value(val_val) => val_val, - _ => bug!("encountered bad ConstKind in codegen"), - }; - - let val = match val_val { + let val = match val { ConstValue::Scalar(x) => { let scalar = match layout.abi { layout::Abi::Scalar(ref x) => x, diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 5e6db565a7d0..5915520535d2 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -26,7 +26,7 @@ pub(crate) fn const_field<'tcx>( variant: Option, field: mir::Field, value: &'tcx ty::Const<'tcx>, -) -> &'tcx ty::Const<'tcx> { +) -> ConstValue<'tcx> { trace!("const_field: {:?}, {:?}", field, value); let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false); // get the operand again @@ -40,26 +40,19 @@ pub(crate) fn const_field<'tcx>( let field = ecx.operand_field(down, field.index() as u64).unwrap(); // and finally move back to the const world, always normalizing because // this is not called for statics. - let val = op_to_const(&ecx, field); - tcx.mk_const(ty::Const { val: ty::ConstKind::Value(val), ty: op.layout.ty }) + op_to_const(&ecx, field) } pub(crate) fn const_caller_location<'tcx>( tcx: TyCtxt<'tcx>, (file, line, col): (Symbol, u32, u32), -) -> &'tcx ty::Const<'tcx> { +) -> ConstValue<'tcx> { trace!("const_caller_location: {}:{}:{}", file, line, col); let mut ecx = mk_eval_cx(tcx, DUMMY_SP, ty::ParamEnv::reveal_all(), false); - let loc_ty = tcx.caller_location_ty(); let loc_place = ecx.alloc_caller_location(file, line, col); intern_const_alloc_recursive(&mut ecx, InternKind::Constant, loc_place, false).unwrap(); - let loc_const = ty::Const { - ty: loc_ty, - val: ty::ConstKind::Value(ConstValue::Scalar(loc_place.ptr.into())), - }; - - tcx.mk_const(loc_const) + ConstValue::Scalar(loc_place.ptr.into()) } // this function uses `unwrap` copiously, because an already validated constant