Do not call the const_eval
query in mir interpretation except for caching of nulary intrinsics
This commit is contained in:
parent
a6c60bbe5d
commit
dd9702a059
4 changed files with 8 additions and 34 deletions
|
@ -51,7 +51,7 @@ impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> {
|
||||||
|
|
||||||
let gid = GlobalId { instance, promoted: None };
|
let gid = GlobalId { instance, promoted: None };
|
||||||
|
|
||||||
let place = self.const_eval_raw(gid)?;
|
let place = self.const_eval(gid)?;
|
||||||
|
|
||||||
self.copy_op(place.into(), dest)?;
|
self.copy_op(place.into(), dest)?;
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ use rustc_span::{Pos, Span};
|
||||||
use rustc_target::abi::{Align, HasDataLayout, LayoutOf, Size, TargetDataLayout};
|
use rustc_target::abi::{Align, HasDataLayout, LayoutOf, Size, TargetDataLayout};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
Immediate, MPlaceTy, Machine, MemPlace, MemPlaceMeta, Memory, OpTy, Operand, Place, PlaceTy,
|
Immediate, MPlaceTy, Machine, MemPlace, MemPlaceMeta, Memory, Operand, Place, PlaceTy,
|
||||||
ScalarMaybeUninit, StackPopJump,
|
ScalarMaybeUninit, StackPopJump,
|
||||||
};
|
};
|
||||||
use crate::transform::validate::equal_up_to_regions;
|
use crate::transform::validate::equal_up_to_regions;
|
||||||
|
@ -875,32 +875,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn const_eval(
|
pub fn const_eval(
|
||||||
&self,
|
|
||||||
gid: GlobalId<'tcx>,
|
|
||||||
ty: Ty<'tcx>,
|
|
||||||
) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
|
|
||||||
// For statics we pick `ParamEnv::reveal_all`, because statics don't have generics
|
|
||||||
// and thus don't care about the parameter environment. While we could just use
|
|
||||||
// `self.param_env`, that would mean we invoke the query to evaluate the static
|
|
||||||
// with different parameter environments, thus causing the static to be evaluated
|
|
||||||
// multiple times.
|
|
||||||
let param_env = if self.tcx.is_static(gid.instance.def_id()) {
|
|
||||||
ty::ParamEnv::reveal_all()
|
|
||||||
} else {
|
|
||||||
self.param_env
|
|
||||||
};
|
|
||||||
let val = self.tcx.const_eval_global_id(param_env, gid, Some(self.tcx.span))?;
|
|
||||||
|
|
||||||
// Even though `ecx.const_eval` is called from `const_to_op` we can never have a
|
|
||||||
// recursion deeper than one level, because the `tcx.const_eval` above is guaranteed to not
|
|
||||||
// return `ConstValue::Unevaluated`, which is the only way that `const_to_op` will call
|
|
||||||
// `ecx.const_eval`.
|
|
||||||
let const_ = ty::Const { val: ty::ConstKind::Value(val), ty };
|
|
||||||
self.const_to_op(&const_, None)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn const_eval_raw(
|
|
||||||
&self,
|
&self,
|
||||||
gid: GlobalId<'tcx>,
|
gid: GlobalId<'tcx>,
|
||||||
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
|
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
|
||||||
|
|
|
@ -152,7 +152,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
sym::type_name => self.tcx.mk_static_str(),
|
sym::type_name => self.tcx.mk_static_str(),
|
||||||
_ => bug!("already checked for nullary intrinsics"),
|
_ => bug!("already checked for nullary intrinsics"),
|
||||||
};
|
};
|
||||||
let val = self.const_eval(gid, ty)?;
|
let val =
|
||||||
|
self.tcx.const_eval_global_id(self.param_env, gid, Some(self.tcx.span))?;
|
||||||
|
let const_ = ty::Const { val: ty::ConstKind::Value(val), ty };
|
||||||
|
let val = self.const_to_op(&const_, None)?;
|
||||||
self.copy_op(val, dest)?;
|
self.copy_op(val, dest)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -553,11 +553,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
ty::ConstKind::Error(_) => throw_inval!(TypeckError(ErrorReported)),
|
ty::ConstKind::Error(_) => throw_inval!(TypeckError(ErrorReported)),
|
||||||
ty::ConstKind::Unevaluated(def, substs, promoted) => {
|
ty::ConstKind::Unevaluated(def, substs, promoted) => {
|
||||||
let instance = self.resolve(def.did, substs)?;
|
let instance = self.resolve(def.did, substs)?;
|
||||||
// We use `const_eval` here and `const_eval_raw` elsewhere in mir interpretation.
|
return Ok(self.const_eval(GlobalId { instance, promoted })?.into());
|
||||||
// The reason we use `const_eval` here is that there can never be a `ty::ConstKind`
|
|
||||||
// that directly mentions the initializer of a static. Statics are always encoded
|
|
||||||
// as constants with vaule `&STATIC`.
|
|
||||||
return Ok(self.const_eval(GlobalId { instance, promoted }, val.ty)?);
|
|
||||||
}
|
}
|
||||||
ty::ConstKind::Infer(..)
|
ty::ConstKind::Infer(..)
|
||||||
| ty::ConstKind::Bound(..)
|
| ty::ConstKind::Bound(..)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue