ctfe, const_to_op
only for mir constants
This commit is contained in:
parent
638b612154
commit
526856768d
@ -103,7 +103,7 @@ pub(crate) fn try_destructure_mir_constant<'tcx>(
|
||||
) -> InterpResult<'tcx, mir::DestructuredMirConstant<'tcx>> {
|
||||
trace!("destructure_mir_constant: {:?}", val);
|
||||
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false);
|
||||
let op = ecx.mir_const_to_op(&val, None)?;
|
||||
let op = ecx.const_to_op(&val, None)?;
|
||||
|
||||
// We go to `usize` as we cannot allocate anything bigger anyway.
|
||||
let (field_count, variant, down) = match val.ty().kind() {
|
||||
@ -139,7 +139,7 @@ pub(crate) fn deref_mir_constant<'tcx>(
|
||||
val: mir::ConstantKind<'tcx>,
|
||||
) -> mir::ConstantKind<'tcx> {
|
||||
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false);
|
||||
let op = ecx.mir_const_to_op(&val, None).unwrap();
|
||||
let op = ecx.const_to_op(&val, None).unwrap();
|
||||
let mplace = ecx.deref_operand(&op).unwrap();
|
||||
if let Some(alloc_id) = mplace.ptr.provenance {
|
||||
assert_eq!(
|
||||
|
@ -683,11 +683,10 @@ pub fn push_stack_frame(
|
||||
self.stack_mut().push(frame);
|
||||
|
||||
// Make sure all the constants required by this frame evaluate successfully (post-monomorphization check).
|
||||
for const_ in &body.required_consts {
|
||||
let span = const_.span;
|
||||
let const_ =
|
||||
self.subst_from_current_frame_and_normalize_erasing_regions(const_.literal)?;
|
||||
self.mir_const_to_op(&const_, None).map_err(|err| {
|
||||
for ct in &body.required_consts {
|
||||
let span = ct.span;
|
||||
let ct = self.subst_from_current_frame_and_normalize_erasing_regions(ct.literal)?;
|
||||
self.const_to_op(&ct, None).map_err(|err| {
|
||||
// If there was an error, set the span of the current frame to this constant.
|
||||
// Avoiding doing this when evaluation succeeds.
|
||||
self.frame_mut().loc = Err(span);
|
||||
|
@ -534,7 +534,7 @@ pub fn eval_operand(
|
||||
// * During ConstProp, with `TooGeneric` or since the `required_consts` were not all
|
||||
// checked yet.
|
||||
// * During CTFE, since promoteds in `const`/`static` initializer bodies can fail.
|
||||
self.mir_const_to_op(&val, layout)?
|
||||
self.const_to_op(&val, layout)?
|
||||
}
|
||||
};
|
||||
trace!("{:?}: {:?}", mir_op, *op);
|
||||
@ -549,50 +549,42 @@ pub(super) fn eval_operands(
|
||||
ops.iter().map(|op| self.eval_operand(op, None)).collect()
|
||||
}
|
||||
|
||||
// Used when the miri-engine runs into a constant and for extracting information from constants
|
||||
// in patterns via the `const_eval` module
|
||||
/// The `val` and `layout` are assumed to already be in our interpreter
|
||||
/// "universe" (param_env).
|
||||
pub fn const_to_op(
|
||||
&self,
|
||||
c: ty::Const<'tcx>,
|
||||
layout: Option<TyAndLayout<'tcx>>,
|
||||
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
|
||||
match c.kind() {
|
||||
ty::ConstKind::Param(_) | ty::ConstKind::Placeholder(..) => throw_inval!(TooGeneric),
|
||||
ty::ConstKind::Error(DelaySpanBugEmitted { reported, .. }) => {
|
||||
throw_inval!(AlreadyReported(reported))
|
||||
}
|
||||
ty::ConstKind::Unevaluated(uv) => {
|
||||
// NOTE: We evaluate to a `ValTree` here as a check to ensure
|
||||
// we're working with valid constants, even though we never need it.
|
||||
let instance = self.resolve(uv.def, uv.substs)?;
|
||||
let cid = GlobalId { instance, promoted: None };
|
||||
let _valtree = self
|
||||
.tcx
|
||||
.eval_to_valtree(self.param_env.and(cid))?
|
||||
.unwrap_or_else(|| bug!("unable to create ValTree for {:?}", uv));
|
||||
|
||||
Ok(self.eval_to_allocation(cid)?.into())
|
||||
}
|
||||
ty::ConstKind::Bound(..) | ty::ConstKind::Infer(..) => {
|
||||
span_bug!(self.cur_span(), "const_to_op: Unexpected ConstKind {:?}", c)
|
||||
}
|
||||
ty::ConstKind::Value(valtree) => {
|
||||
let ty = c.ty();
|
||||
let const_val = self.tcx.valtree_to_const_val((ty, valtree));
|
||||
self.const_val_to_op(const_val, ty, layout)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mir_const_to_op(
|
||||
&self,
|
||||
val: &mir::ConstantKind<'tcx>,
|
||||
layout: Option<TyAndLayout<'tcx>>,
|
||||
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
|
||||
match val {
|
||||
mir::ConstantKind::Ty(ct) => self.const_to_op(*ct, layout),
|
||||
mir::ConstantKind::Ty(ct) => {
|
||||
match ct.kind() {
|
||||
ty::ConstKind::Param(_) | ty::ConstKind::Placeholder(..) => {
|
||||
throw_inval!(TooGeneric)
|
||||
}
|
||||
ty::ConstKind::Error(DelaySpanBugEmitted { reported, .. }) => {
|
||||
throw_inval!(AlreadyReported(reported))
|
||||
}
|
||||
ty::ConstKind::Unevaluated(uv) => {
|
||||
// NOTE: We evaluate to a `ValTree` here as a check to ensure
|
||||
// we're working with valid constants, even though we never need it.
|
||||
let instance = self.resolve(uv.def, uv.substs)?;
|
||||
let cid = GlobalId { instance, promoted: None };
|
||||
let _valtree = self
|
||||
.tcx
|
||||
.eval_to_valtree(self.param_env.and(cid))?
|
||||
.unwrap_or_else(|| bug!("unable to create ValTree for {uv:?}"));
|
||||
|
||||
Ok(self.eval_to_allocation(cid)?.into())
|
||||
}
|
||||
ty::ConstKind::Bound(..) | ty::ConstKind::Infer(..) => {
|
||||
span_bug!(self.cur_span(), "unexpected ConstKind in ctfe: {ct:?}")
|
||||
}
|
||||
ty::ConstKind::Value(valtree) => {
|
||||
let ty = ct.ty();
|
||||
let const_val = self.tcx.valtree_to_const_val((ty, valtree));
|
||||
self.const_val_to_op(const_val, ty, layout)
|
||||
}
|
||||
}
|
||||
}
|
||||
mir::ConstantKind::Val(val, ty) => self.const_val_to_op(*val, *ty, layout),
|
||||
mir::ConstantKind::Unevaluated(uv, _) => {
|
||||
let instance = self.resolve(uv.def, uv.substs)?;
|
||||
|
@ -679,7 +679,7 @@ fn super_fold_with<F: PatternFolder<$lt_tcx>>(&self, _: &mut F) -> Self {
|
||||
}
|
||||
|
||||
ClonePatternFoldableImpls! { <'tcx>
|
||||
Span, Field, Mutability, Symbol, LocalVarId, usize, ty::Const<'tcx>,
|
||||
Span, Field, Mutability, Symbol, LocalVarId, usize,
|
||||
Region<'tcx>, Ty<'tcx>, BindingMode, AdtDef<'tcx>,
|
||||
SubstsRef<'tcx>, &'tcx GenericArg<'tcx>, UserType<'tcx>,
|
||||
UserTypeProjection, CanonicalUserTypeAnnotation<'tcx>
|
||||
|
@ -471,7 +471,7 @@ fn eval_constant(&mut self, c: &Constant<'tcx>) -> Option<OpTy<'tcx>> {
|
||||
return None;
|
||||
}
|
||||
|
||||
self.ecx.mir_const_to_op(&c.literal, None).ok()
|
||||
self.ecx.const_to_op(&c.literal, None).ok()
|
||||
}
|
||||
|
||||
/// Returns the value, if any, of evaluating `place`.
|
||||
|
@ -292,7 +292,7 @@ fn eval_constant(&mut self, c: &Constant<'tcx>, source_info: SourceInfo) -> Opti
|
||||
return None;
|
||||
}
|
||||
|
||||
match self.ecx.mir_const_to_op(&c.literal, None) {
|
||||
match self.ecx.const_to_op(&c.literal, None) {
|
||||
Ok(op) => Some(op),
|
||||
Err(error) => {
|
||||
let tcx = self.ecx.tcx.at(c.span);
|
||||
|
Loading…
Reference in New Issue
Block a user