From a299d0e632772718a7e0bae3f0964a7a3aa7c2e0 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 30 Apr 2020 19:00:25 +0200 Subject: [PATCH] Don't panic on unevaluatable promoted constants --- src/common.rs | 3 ++- src/constant.rs | 32 +++++++++++++++++++++++--------- src/intrinsics/mod.rs | 3 ++- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/common.rs b/src/common.rs index 248ac14d7e4..08afe18ae5d 100644 --- a/src/common.rs +++ b/src/common.rs @@ -351,7 +351,8 @@ impl<'tcx, B: Backend + 'static> FunctionCx<'_, 'tcx, B> { )); crate::constant::trans_const_value( self, - ty::Const::from_value(self.tcx, const_loc, self.tcx.caller_location_ty()), + const_loc, + self.tcx.caller_location_ty(), ) } diff --git a/src/constant.rs b/src/constant.rs index 5c760a467c6..8a22ddefbb2 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -72,7 +72,9 @@ pub(crate) fn trans_constant<'tcx>( fx: &mut FunctionCx<'_, 'tcx, impl Backend>, constant: &Constant<'tcx>, ) -> CValue<'tcx> { - let const_ = match constant.literal.val { + let const_ = fx.monomorphize(&constant.literal); + let const_val = match const_.val { + ConstKind::Value(const_val) => const_val, ConstKind::Unevaluated(def_id, ref substs, promoted) if fx.tcx.is_static(def_id) => { assert!(substs.is_empty()); assert!(promoted.is_none()); @@ -83,17 +85,33 @@ pub(crate) fn trans_constant<'tcx>( fx.layout_of(fx.monomorphize(&constant.literal.ty)), ).to_cvalue(fx); } - _ => fx.monomorphize(&constant.literal).eval(fx.tcx, ParamEnv::reveal_all()), + ConstKind::Unevaluated(def_id, ref substs, promoted) => { + match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def_id, substs, promoted, None) { + Ok(const_val) => const_val, + Err(_) => { + if promoted.is_none() { + fx.tcx.sess.span_err(constant.span, "erroneous constant encountered"); + } + return crate::trap::trap_unreachable_ret_value( + fx, + fx.layout_of(const_.ty), + "erroneous constant encountered", + ); + } + } + } + ConstKind::Param(_) | ConstKind::Infer(_) | ConstKind::Bound(_, _) + | ConstKind::Placeholder(_) | ConstKind::Error(_) => unreachable!("{:?}", const_), }; - trans_const_value(fx, const_) + trans_const_value(fx, const_val, const_.ty) } pub(crate) fn trans_const_value<'tcx>( fx: &mut FunctionCx<'_, 'tcx, impl Backend>, - const_: &'tcx Const<'tcx>, + const_val: ConstValue<'tcx>, + ty: Ty<'tcx> ) -> CValue<'tcx> { - let ty = fx.monomorphize(&const_.ty); let layout = fx.layout_of(ty); assert!(!layout.is_unsized(), "sized const value"); @@ -103,10 +121,6 @@ pub(crate) fn trans_const_value<'tcx>( layout, ); } - let const_val = match const_.val { - ConstKind::Value(const_val) => const_val, - _ => unreachable!("Const {:?} should have been evaluated", const_), - }; match const_val { ConstValue::Scalar(x) => { diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index aa950067f7b..a5aec52a7e4 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -822,7 +822,8 @@ pub(crate) fn codegen_intrinsic_call<'tcx>( fx.tcx.const_eval_instance(ParamEnv::reveal_all(), instance, None).unwrap(); let val = crate::constant::trans_const_value( fx, - ty::Const::from_value(fx.tcx, const_val, ret.layout().ty), + const_val, + ret.layout().ty, ); ret.write_cvalue(fx, val); };