mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
use RawConst in miri
This commit is contained in:
parent
b50c1b243e
commit
ba82f54b04
@ -99,8 +99,7 @@ pub(crate) fn eval_promoted<'a, 'mir, 'tcx>(
|
||||
eval_body_using_ecx(&mut ecx, cid, Some(mir), param_env)
|
||||
}
|
||||
|
||||
// FIXME: This thing is a bad hack. We should get rid of it. Ideally constants are always
|
||||
// in an allocation.
|
||||
// FIXME: These two conversion functions are bad hacks. We should just always use allocations.
|
||||
pub fn op_to_const<'tcx>(
|
||||
ecx: &CompileTimeEvalContext<'_, '_, 'tcx>,
|
||||
op: OpTy<'tcx>,
|
||||
@ -146,6 +145,13 @@ pub fn op_to_const<'tcx>(
|
||||
};
|
||||
Ok(ty::Const::from_const_value(ecx.tcx.tcx, val, op.layout.ty))
|
||||
}
|
||||
pub fn const_to_op<'tcx>(
|
||||
ecx: &CompileTimeEvalContext<'_, '_, 'tcx>,
|
||||
cnst: &ty::Const<'tcx>,
|
||||
) -> EvalResult<'tcx, OpTy<'tcx>> {
|
||||
let op = ecx.const_value_to_op(cnst.val)?;
|
||||
Ok(OpTy { op, layout: ecx.layout_of(cnst.ty)? })
|
||||
}
|
||||
|
||||
fn eval_body_and_ecx<'a, 'mir, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
@ -496,7 +502,7 @@ pub fn const_field<'a, 'tcx>(
|
||||
let ecx = mk_eval_cx(tcx, instance, param_env).unwrap();
|
||||
let result = (|| {
|
||||
// get the operand again
|
||||
let op = ecx.const_to_op(value)?;
|
||||
let op = const_to_op(&ecx, value)?;
|
||||
// downcast
|
||||
let down = match variant {
|
||||
None => op,
|
||||
@ -523,7 +529,7 @@ pub fn const_variant_index<'a, 'tcx>(
|
||||
) -> EvalResult<'tcx, VariantIdx> {
|
||||
trace!("const_variant_index: {:?}, {:?}", instance, val);
|
||||
let ecx = mk_eval_cx(tcx, instance, param_env).unwrap();
|
||||
let op = ecx.const_to_op(val)?;
|
||||
let op = const_to_op(&ecx, val)?;
|
||||
Ok(ecx.read_discriminant(op)?.1)
|
||||
}
|
||||
|
||||
|
@ -588,18 +588,22 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn const_eval(&self, gid: GlobalId<'tcx>) -> EvalResult<'tcx, &'tcx ty::Const<'tcx>> {
|
||||
pub fn const_eval_raw(
|
||||
&self,
|
||||
gid: GlobalId<'tcx>,
|
||||
) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
|
||||
let param_env = if self.tcx.is_static(gid.instance.def_id()).is_some() {
|
||||
ty::ParamEnv::reveal_all()
|
||||
} else {
|
||||
self.param_env
|
||||
};
|
||||
self.tcx.const_eval(param_env.and(gid)).map_err(|err| {
|
||||
let val = self.tcx.const_eval_raw(param_env.and(gid)).map_err(|err| {
|
||||
match err {
|
||||
ErrorHandled::Reported => EvalErrorKind::ReferencedConstant.into(),
|
||||
ErrorHandled::TooGeneric => EvalErrorKind::TooGeneric.into(),
|
||||
ErrorHandled::Reported => EvalErrorKind::ReferencedConstant,
|
||||
ErrorHandled::TooGeneric => EvalErrorKind::TooGeneric,
|
||||
}
|
||||
})
|
||||
})?;
|
||||
self.raw_const_to_mplace(val)
|
||||
}
|
||||
|
||||
pub fn dump_place(&self, place: Place<M::PointerTag>) {
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
use std::convert::TryInto;
|
||||
|
||||
use rustc::{mir, ty};
|
||||
use rustc::mir;
|
||||
use rustc::ty::layout::{self, Size, LayoutOf, TyLayout, HasDataLayout, IntegerExt, VariantIdx};
|
||||
|
||||
use rustc::mir::interpret::{
|
||||
@ -535,9 +535,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
||||
.collect()
|
||||
}
|
||||
|
||||
// Also used e.g. when miri runs into a constant.
|
||||
// FIXME: Can we avoid converting with ConstValue and Const? We should be using RawConst.
|
||||
fn const_value_to_op(
|
||||
// Used when miri runs into a constant, and by CTFE.
|
||||
// FIXME: CTFE should use allocations, then we can make this private (embed it into
|
||||
// `eval_operand`, ideally).
|
||||
pub(crate) fn const_value_to_op(
|
||||
&self,
|
||||
val: ConstValue<'tcx>,
|
||||
) -> EvalResult<'tcx, Operand<M::PointerTag>> {
|
||||
@ -545,10 +546,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
||||
match val {
|
||||
ConstValue::Unevaluated(def_id, substs) => {
|
||||
let instance = self.resolve(def_id, substs)?;
|
||||
self.global_to_op(GlobalId {
|
||||
Ok(*OpTy::from(self.const_eval_raw(GlobalId {
|
||||
instance,
|
||||
promoted: None,
|
||||
})
|
||||
})?))
|
||||
}
|
||||
ConstValue::ByRef(id, alloc, offset) => {
|
||||
// We rely on mutability being set correctly in that allocation to prevent writes
|
||||
@ -566,21 +567,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
||||
Ok(Operand::Immediate(Immediate::Scalar(x.into())).with_default_tag()),
|
||||
}
|
||||
}
|
||||
pub fn const_to_op(
|
||||
&self,
|
||||
cnst: &ty::Const<'tcx>,
|
||||
) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
|
||||
let op = self.const_value_to_op(cnst.val)?;
|
||||
Ok(OpTy { op, layout: self.layout_of(cnst.ty)? })
|
||||
}
|
||||
|
||||
pub(super) fn global_to_op(
|
||||
&self,
|
||||
gid: GlobalId<'tcx>
|
||||
) -> EvalResult<'tcx, Operand<M::PointerTag>> {
|
||||
let cv = self.const_eval(gid)?;
|
||||
self.const_value_to_op(cv.val)
|
||||
}
|
||||
|
||||
/// Read discriminant, return the runtime value as well as the variant index.
|
||||
pub fn read_discriminant(
|
||||
|
@ -553,16 +553,10 @@ where
|
||||
Ok(match *mir_place {
|
||||
Promoted(ref promoted) => {
|
||||
let instance = self.frame().instance;
|
||||
let op = self.global_to_op(GlobalId {
|
||||
self.const_eval_raw(GlobalId {
|
||||
instance,
|
||||
promoted: Some(promoted.0),
|
||||
})?;
|
||||
let mplace = op.to_mem_place(); // these are always in memory
|
||||
let ty = self.monomorphize(promoted.1, self.substs());
|
||||
MPlaceTy {
|
||||
mplace,
|
||||
layout: self.layout_of(ty)?,
|
||||
}
|
||||
})?
|
||||
}
|
||||
|
||||
Static(ref static_) => {
|
||||
|
@ -29,7 +29,9 @@ use rustc::ty::layout::{
|
||||
};
|
||||
|
||||
use interpret::{self, EvalContext, ScalarMaybeUndef, Immediate, OpTy, MemoryKind};
|
||||
use const_eval::{CompileTimeInterpreter, error_to_const_error, eval_promoted, mk_borrowck_eval_cx};
|
||||
use const_eval::{
|
||||
CompileTimeInterpreter, const_to_op, error_to_const_error, eval_promoted, mk_borrowck_eval_cx
|
||||
};
|
||||
use transform::{MirPass, MirSource};
|
||||
|
||||
pub struct ConstProp;
|
||||
@ -262,7 +264,7 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
|
||||
source_info: SourceInfo,
|
||||
) -> Option<Const<'tcx>> {
|
||||
self.ecx.tcx.span = source_info.span;
|
||||
match self.ecx.const_to_op(c.literal) {
|
||||
match const_to_op(&self.ecx, c.literal) {
|
||||
Ok(op) => {
|
||||
Some((op, c.span))
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user