Use options instead of errors if the errors are never needed

This commit is contained in:
Oli Scherer 2023-06-28 13:22:02 +00:00
parent 09b89efa70
commit 46cce98134
2 changed files with 11 additions and 13 deletions

View File

@ -1,9 +1,7 @@
// Not in interpret to make sure we do not use private implementation details // Not in interpret to make sure we do not use private implementation details
use crate::errors::MaxNumNodesInConstErr; use crate::errors::MaxNumNodesInConstErr;
use crate::interpret::{ use crate::interpret::{intern_const_alloc_recursive, ConstValue, InternKind, InterpCx, Scalar};
intern_const_alloc_recursive, ConstValue, InternKind, InterpCx, InterpResult, Scalar,
};
use rustc_middle::mir; use rustc_middle::mir;
use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId}; use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId};
use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{self, Ty, TyCtxt};
@ -91,20 +89,20 @@ pub(crate) fn try_destructure_mir_constant<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
val: ConstValue<'tcx>, val: ConstValue<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> InterpResult<'tcx, mir::DestructuredConstant<'tcx>> { ) -> Option<mir::DestructuredConstant<'tcx>> {
let param_env = ty::ParamEnv::reveal_all(); let param_env = ty::ParamEnv::reveal_all();
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, CanAccessStatics::No); let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, CanAccessStatics::No);
let op = ecx.const_val_to_op(val, ty, None)?; let op = ecx.const_val_to_op(val, ty, None).ok()?;
// 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 ty.kind() { let (field_count, variant, down) = match ty.kind() {
ty::Array(_, len) => (len.eval_target_usize(tcx, param_env) as usize, None, op), ty::Array(_, len) => (len.eval_target_usize(tcx, param_env) as usize, None, op),
ty::Adt(def, _) if def.variants().is_empty() => { ty::Adt(def, _) if def.variants().is_empty() => {
throw_ub!(Unreachable) return None;
} }
ty::Adt(def, _) => { ty::Adt(def, _) => {
let variant = ecx.read_discriminant(&op)?.1; let variant = ecx.read_discriminant(&op).ok()?.1;
let down = ecx.operand_downcast(&op, variant)?; let down = ecx.operand_downcast(&op, variant).ok()?;
(def.variants()[variant].fields.len(), Some(variant), down) (def.variants()[variant].fields.len(), Some(variant), down)
} }
ty::Tuple(substs) => (substs.len(), None, op), ty::Tuple(substs) => (substs.len(), None, op),
@ -113,12 +111,12 @@ pub(crate) fn try_destructure_mir_constant<'tcx>(
let fields_iter = (0..field_count) let fields_iter = (0..field_count)
.map(|i| { .map(|i| {
let field_op = ecx.operand_field(&down, i)?; let field_op = ecx.operand_field(&down, i).ok()?;
let val = op_to_const(&ecx, &field_op); let val = op_to_const(&ecx, &field_op);
Ok((val, field_op.layout.ty)) Some((val, field_op.layout.ty))
}) })
.collect::<InterpResult<'tcx, Vec<_>>>()?; .collect::<Option<Vec<_>>>()?;
let fields = tcx.arena.alloc_from_iter(fields_iter); let fields = tcx.arena.alloc_from_iter(fields_iter);
Ok(mir::DestructuredConstant { variant, fields }) Some(mir::DestructuredConstant { variant, fields })
} }

View File

@ -53,7 +53,7 @@ pub fn provide(providers: &mut Providers) {
const_eval::eval_to_valtree(tcx, param_env, raw) const_eval::eval_to_valtree(tcx, param_env, raw)
}; };
providers.try_destructure_mir_constant = providers.try_destructure_mir_constant =
|tcx, (cv, ty)| const_eval::try_destructure_mir_constant(tcx, cv, ty).ok(); |tcx, (cv, ty)| const_eval::try_destructure_mir_constant(tcx, cv, ty);
providers.valtree_to_const_val = |tcx, (ty, valtree)| { providers.valtree_to_const_val = |tcx, (ty, valtree)| {
const_eval::valtree_to_const_value(tcx, ty::ParamEnv::empty().and(ty), valtree) const_eval::valtree_to_const_value(tcx, ty::ParamEnv::empty().and(ty), valtree)
}; };