ctfe, const_to_op only for mir constants

This commit is contained in:
lcnr 2022-09-19 16:17:33 +02:00
parent 638b612154
commit 526856768d
6 changed files with 40 additions and 49 deletions

View file

@ -103,7 +103,7 @@ pub(crate) fn try_destructure_mir_constant<'tcx>(
) -> InterpResult<'tcx, mir::DestructuredMirConstant<'tcx>> { ) -> InterpResult<'tcx, mir::DestructuredMirConstant<'tcx>> {
trace!("destructure_mir_constant: {:?}", val); trace!("destructure_mir_constant: {:?}", val);
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false); 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. // We go to `usize` as we cannot allocate anything bigger anyway.
let (field_count, variant, down) = match val.ty().kind() { let (field_count, variant, down) = match val.ty().kind() {
@ -139,7 +139,7 @@ pub(crate) fn deref_mir_constant<'tcx>(
val: mir::ConstantKind<'tcx>, val: mir::ConstantKind<'tcx>,
) -> mir::ConstantKind<'tcx> { ) -> mir::ConstantKind<'tcx> {
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false); 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(); let mplace = ecx.deref_operand(&op).unwrap();
if let Some(alloc_id) = mplace.ptr.provenance { if let Some(alloc_id) = mplace.ptr.provenance {
assert_eq!( assert_eq!(

View file

@ -683,11 +683,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
self.stack_mut().push(frame); self.stack_mut().push(frame);
// Make sure all the constants required by this frame evaluate successfully (post-monomorphization check). // Make sure all the constants required by this frame evaluate successfully (post-monomorphization check).
for const_ in &body.required_consts { for ct in &body.required_consts {
let span = const_.span; let span = ct.span;
let const_ = let ct = self.subst_from_current_frame_and_normalize_erasing_regions(ct.literal)?;
self.subst_from_current_frame_and_normalize_erasing_regions(const_.literal)?; self.const_to_op(&ct, None).map_err(|err| {
self.mir_const_to_op(&const_, None).map_err(|err| {
// If there was an error, set the span of the current frame to this constant. // If there was an error, set the span of the current frame to this constant.
// Avoiding doing this when evaluation succeeds. // Avoiding doing this when evaluation succeeds.
self.frame_mut().loc = Err(span); self.frame_mut().loc = Err(span);

View file

@ -534,7 +534,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// * During ConstProp, with `TooGeneric` or since the `required_consts` were not all // * During ConstProp, with `TooGeneric` or since the `required_consts` were not all
// checked yet. // checked yet.
// * During CTFE, since promoteds in `const`/`static` initializer bodies can fail. // * 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); trace!("{:?}: {:?}", mir_op, *op);
@ -549,17 +549,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
ops.iter().map(|op| self.eval_operand(op, None)).collect() 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( pub fn const_to_op(
&self, &self,
c: ty::Const<'tcx>, val: &mir::ConstantKind<'tcx>,
layout: Option<TyAndLayout<'tcx>>, layout: Option<TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
match c.kind() { match val {
ty::ConstKind::Param(_) | ty::ConstKind::Placeholder(..) => throw_inval!(TooGeneric), mir::ConstantKind::Ty(ct) => {
match ct.kind() {
ty::ConstKind::Param(_) | ty::ConstKind::Placeholder(..) => {
throw_inval!(TooGeneric)
}
ty::ConstKind::Error(DelaySpanBugEmitted { reported, .. }) => { ty::ConstKind::Error(DelaySpanBugEmitted { reported, .. }) => {
throw_inval!(AlreadyReported(reported)) throw_inval!(AlreadyReported(reported))
} }
@ -571,28 +571,20 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let _valtree = self let _valtree = self
.tcx .tcx
.eval_to_valtree(self.param_env.and(cid))? .eval_to_valtree(self.param_env.and(cid))?
.unwrap_or_else(|| bug!("unable to create ValTree for {:?}", uv)); .unwrap_or_else(|| bug!("unable to create ValTree for {uv:?}"));
Ok(self.eval_to_allocation(cid)?.into()) Ok(self.eval_to_allocation(cid)?.into())
} }
ty::ConstKind::Bound(..) | ty::ConstKind::Infer(..) => { ty::ConstKind::Bound(..) | ty::ConstKind::Infer(..) => {
span_bug!(self.cur_span(), "const_to_op: Unexpected ConstKind {:?}", c) span_bug!(self.cur_span(), "unexpected ConstKind in ctfe: {ct:?}")
} }
ty::ConstKind::Value(valtree) => { ty::ConstKind::Value(valtree) => {
let ty = c.ty(); let ty = ct.ty();
let const_val = self.tcx.valtree_to_const_val((ty, valtree)); let const_val = self.tcx.valtree_to_const_val((ty, valtree));
self.const_val_to_op(const_val, ty, layout) 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::Val(val, ty) => self.const_val_to_op(*val, *ty, layout), mir::ConstantKind::Val(val, ty) => self.const_val_to_op(*val, *ty, layout),
mir::ConstantKind::Unevaluated(uv, _) => { mir::ConstantKind::Unevaluated(uv, _) => {
let instance = self.resolve(uv.def, uv.substs)?; let instance = self.resolve(uv.def, uv.substs)?;

View file

@ -679,7 +679,7 @@ macro_rules! ClonePatternFoldableImpls {
} }
ClonePatternFoldableImpls! { <'tcx> ClonePatternFoldableImpls! { <'tcx>
Span, Field, Mutability, Symbol, LocalVarId, usize, ty::Const<'tcx>, Span, Field, Mutability, Symbol, LocalVarId, usize,
Region<'tcx>, Ty<'tcx>, BindingMode, AdtDef<'tcx>, Region<'tcx>, Ty<'tcx>, BindingMode, AdtDef<'tcx>,
SubstsRef<'tcx>, &'tcx GenericArg<'tcx>, UserType<'tcx>, SubstsRef<'tcx>, &'tcx GenericArg<'tcx>, UserType<'tcx>,
UserTypeProjection, CanonicalUserTypeAnnotation<'tcx> UserTypeProjection, CanonicalUserTypeAnnotation<'tcx>

View file

@ -471,7 +471,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
return None; 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`. /// Returns the value, if any, of evaluating `place`.

View file

@ -292,7 +292,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
return None; 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), Ok(op) => Some(op),
Err(error) => { Err(error) => {
let tcx = self.ecx.tcx.at(c.span); let tcx = self.ecx.tcx.at(c.span);