Auto merge of #46743 - oli-obk:miri, r=eddyb
Some miri cleanups r? @eddyb
This commit is contained in:
commit
4f2ef415ba
|
@ -20,11 +20,32 @@ use rustc_const_math::ConstInt;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
||||||
|
|
||||||
|
pub fn mk_eval_cx<'a, 'tcx>(
|
||||||
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
|
instance: Instance<'tcx>,
|
||||||
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
|
) -> EvalResult<'tcx, EvalContext<'a, 'tcx, CompileTimeEvaluator>> {
|
||||||
|
debug!("mk_eval_cx: {:?}, {:?}", instance, param_env);
|
||||||
|
let limits = super::ResourceLimits::default();
|
||||||
|
let mut ecx = EvalContext::new(tcx, param_env, limits, CompileTimeEvaluator, ());
|
||||||
|
let mir = ecx.load_mir(instance.def)?;
|
||||||
|
// insert a stack frame so any queries have the correct substs
|
||||||
|
ecx.push_stack_frame(
|
||||||
|
instance,
|
||||||
|
mir.span,
|
||||||
|
mir,
|
||||||
|
Place::undef(),
|
||||||
|
StackPopCleanup::None,
|
||||||
|
)?;
|
||||||
|
Ok(ecx)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn eval_body<'a, 'tcx>(
|
pub fn eval_body<'a, 'tcx>(
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
instance: Instance<'tcx>,
|
instance: Instance<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
) -> (EvalResult<'tcx, (PtrAndAlign, Ty<'tcx>)>, EvalContext<'a, 'tcx, CompileTimeEvaluator>) {
|
) -> EvalResult<'tcx, (PtrAndAlign, Ty<'tcx>)> {
|
||||||
debug!("eval_body: {:?}, {:?}", instance, param_env);
|
debug!("eval_body: {:?}, {:?}", instance, param_env);
|
||||||
let limits = super::ResourceLimits::default();
|
let limits = super::ResourceLimits::default();
|
||||||
let mut ecx = EvalContext::new(tcx, param_env, limits, CompileTimeEvaluator, ());
|
let mut ecx = EvalContext::new(tcx, param_env, limits, CompileTimeEvaluator, ());
|
||||||
|
@ -33,55 +54,43 @@ pub fn eval_body<'a, 'tcx>(
|
||||||
promoted: None,
|
promoted: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let try = (|| {
|
if ecx.tcx.has_attr(instance.def_id(), "linkage") {
|
||||||
if ecx.tcx.has_attr(instance.def_id(), "linkage") {
|
return Err(ConstEvalError::NotConst("extern global".to_string()).into());
|
||||||
return Err(ConstEvalError::NotConst("extern global".to_string()).into());
|
}
|
||||||
}
|
// FIXME(eddyb) use `Instance::ty` when it becomes available.
|
||||||
// FIXME(eddyb) use `Instance::ty` when it becomes available.
|
let instance_ty =
|
||||||
let instance_ty =
|
ecx.monomorphize(instance.def.def_ty(tcx), instance.substs);
|
||||||
ecx.monomorphize(instance.def.def_ty(tcx), instance.substs);
|
if tcx.interpret_interner.borrow().get_cached(cid).is_none() {
|
||||||
if tcx.interpret_interner.borrow().get_cached(cid).is_none() {
|
let mir = ecx.load_mir(instance.def)?;
|
||||||
let mir = ecx.load_mir(instance.def)?;
|
let layout = ecx.layout_of(instance_ty)?;
|
||||||
let layout = ecx.layout_of(instance_ty)?;
|
assert!(!layout.is_unsized());
|
||||||
assert!(!layout.is_unsized());
|
let ptr = ecx.memory.allocate(
|
||||||
let ptr = ecx.memory.allocate(
|
layout.size.bytes(),
|
||||||
layout.size.bytes(),
|
layout.align.abi(),
|
||||||
layout.align.abi(),
|
None,
|
||||||
None,
|
)?;
|
||||||
)?;
|
tcx.interpret_interner.borrow_mut().cache(
|
||||||
tcx.interpret_interner.borrow_mut().cache(
|
cid,
|
||||||
cid,
|
PtrAndAlign {
|
||||||
PtrAndAlign {
|
ptr: ptr.into(),
|
||||||
ptr: ptr.into(),
|
aligned: !layout.is_packed(),
|
||||||
aligned: !layout.is_packed(),
|
},
|
||||||
},
|
);
|
||||||
);
|
let cleanup = StackPopCleanup::MarkStatic(Mutability::Immutable);
|
||||||
let cleanup = StackPopCleanup::MarkStatic(Mutability::Immutable);
|
let name = ty::tls::with(|tcx| tcx.item_path_str(instance.def_id()));
|
||||||
let name = ty::tls::with(|tcx| tcx.item_path_str(instance.def_id()));
|
trace!("const_eval: pushing stack frame for global: {}", name);
|
||||||
trace!("const_eval: pushing stack frame for global: {}", name);
|
ecx.push_stack_frame(
|
||||||
ecx.push_stack_frame(
|
instance,
|
||||||
instance,
|
mir.span,
|
||||||
mir.span,
|
mir,
|
||||||
mir,
|
Place::from_ptr(ptr),
|
||||||
Place::from_ptr(ptr),
|
cleanup.clone(),
|
||||||
cleanup.clone(),
|
)?;
|
||||||
)?;
|
|
||||||
|
|
||||||
while ecx.step()? {}
|
while ecx.step()? {}
|
||||||
|
}
|
||||||
// reinsert the stack frame so any future queries have the correct substs
|
let value = tcx.interpret_interner.borrow().get_cached(cid).expect("global not cached");
|
||||||
ecx.push_stack_frame(
|
Ok((value, instance_ty))
|
||||||
instance,
|
|
||||||
mir.span,
|
|
||||||
mir,
|
|
||||||
Place::from_ptr(ptr),
|
|
||||||
cleanup,
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
let value = tcx.interpret_interner.borrow().get_cached(cid).expect("global not cached");
|
|
||||||
Ok((value, instance_ty))
|
|
||||||
})();
|
|
||||||
(try, ecx)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eval_body_as_integer<'a, 'tcx>(
|
pub fn eval_body_as_integer<'a, 'tcx>(
|
||||||
|
@ -89,8 +98,9 @@ pub fn eval_body_as_integer<'a, 'tcx>(
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
instance: Instance<'tcx>,
|
instance: Instance<'tcx>,
|
||||||
) -> EvalResult<'tcx, ConstInt> {
|
) -> EvalResult<'tcx, ConstInt> {
|
||||||
let (ptr_ty, ecx) = eval_body(tcx, instance, param_env);
|
let ptr_ty = eval_body(tcx, instance, param_env);
|
||||||
let (ptr, ty) = ptr_ty?;
|
let (ptr, ty) = ptr_ty?;
|
||||||
|
let ecx = mk_eval_cx(tcx, instance, param_env)?;
|
||||||
let prim = match ecx.read_maybe_aligned(ptr.aligned, |ectx| ectx.try_read_value(ptr.ptr, ty))? {
|
let prim = match ecx.read_maybe_aligned(ptr.aligned, |ectx| ectx.try_read_value(ptr.ptr, ty))? {
|
||||||
Some(Value::ByVal(prim)) => prim.to_bytes()?,
|
Some(Value::ByVal(prim)) => prim.to_bytes()?,
|
||||||
_ => return err!(TypeNotPrimitive(ty)),
|
_ => return err!(TypeNotPrimitive(ty)),
|
||||||
|
@ -340,20 +350,19 @@ pub fn const_eval_provider<'a, 'tcx>(
|
||||||
trace!("const eval instance: {:?}, {:?}", instance, key.param_env);
|
trace!("const eval instance: {:?}, {:?}", instance, key.param_env);
|
||||||
let miri_result = ::interpret::eval_body(tcx, instance, key.param_env);
|
let miri_result = ::interpret::eval_body(tcx, instance, key.param_env);
|
||||||
match (miri_result, old_result) {
|
match (miri_result, old_result) {
|
||||||
((Err(err), ecx), Ok(ok)) => {
|
(Err(err), Ok(ok)) => {
|
||||||
trace!("miri failed, ctfe returned {:?}", ok);
|
trace!("miri failed, ctfe returned {:?}", ok);
|
||||||
tcx.sess.span_warn(
|
tcx.sess.span_warn(
|
||||||
tcx.def_span(key.value.0),
|
tcx.def_span(key.value.0),
|
||||||
"miri failed to eval, while ctfe succeeded",
|
"miri failed to eval, while ctfe succeeded",
|
||||||
);
|
);
|
||||||
|
let ecx = mk_eval_cx(tcx, instance, key.param_env).unwrap();
|
||||||
let () = unwrap_miri(&ecx, Err(err));
|
let () = unwrap_miri(&ecx, Err(err));
|
||||||
Ok(ok)
|
Ok(ok)
|
||||||
},
|
},
|
||||||
((Ok(_), _), Err(err)) => {
|
(_, Err(err)) => Err(err),
|
||||||
Err(err)
|
(Ok((miri_val, miri_ty)), Ok(ctfe)) => {
|
||||||
},
|
let mut ecx = mk_eval_cx(tcx, instance, key.param_env).unwrap();
|
||||||
((Err(_), _), Err(err)) => Err(err),
|
|
||||||
((Ok((miri_val, miri_ty)), mut ecx), Ok(ctfe)) => {
|
|
||||||
check_ctfe_against_miri(&mut ecx, miri_val, miri_ty, ctfe.val);
|
check_ctfe_against_miri(&mut ecx, miri_val, miri_ty, ctfe.val);
|
||||||
Ok(ctfe)
|
Ok(ctfe)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit bde093fa140cbf95023482a94b92b0b16af4b521
|
Subproject commit 2671cf34a58b11f995add8402e75c1cd94ed051e
|
Loading…
Reference in New Issue