diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index f23cb905c23..38b03f66e03 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -1,9 +1,7 @@ // Not in interpret to make sure we do not use private implementation details use crate::errors::MaxNumNodesInConstErr; -use crate::interpret::{ - intern_const_alloc_recursive, ConstValue, InternKind, InterpCx, InterpResult, Scalar, -}; +use crate::interpret::{intern_const_alloc_recursive, ConstValue, InternKind, InterpCx, Scalar}; use rustc_middle::mir; use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId}; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -91,20 +89,20 @@ pub(crate) fn try_destructure_mir_constant<'tcx>( tcx: TyCtxt<'tcx>, val: ConstValue<'tcx>, ty: Ty<'tcx>, -) -> InterpResult<'tcx, mir::DestructuredConstant<'tcx>> { +) -> Option> { let param_env = ty::ParamEnv::reveal_all(); 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. let (field_count, variant, down) = match ty.kind() { ty::Array(_, len) => (len.eval_target_usize(tcx, param_env) as usize, None, op), ty::Adt(def, _) if def.variants().is_empty() => { - throw_ub!(Unreachable) + return None; } ty::Adt(def, _) => { - let variant = ecx.read_discriminant(&op)?.1; - let down = ecx.operand_downcast(&op, variant)?; + let variant = ecx.read_discriminant(&op).ok()?.1; + let down = ecx.operand_downcast(&op, variant).ok()?; (def.variants()[variant].fields.len(), Some(variant), down) } 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) .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); - Ok((val, field_op.layout.ty)) + Some((val, field_op.layout.ty)) }) - .collect::>>()?; + .collect::>>()?; let fields = tcx.arena.alloc_from_iter(fields_iter); - Ok(mir::DestructuredConstant { variant, fields }) + Some(mir::DestructuredConstant { variant, fields }) } diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 826d2a15721..d82f03b8639 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -53,7 +53,7 @@ pub fn provide(providers: &mut Providers) { const_eval::eval_to_valtree(tcx, param_env, raw) }; 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)| { const_eval::valtree_to_const_value(tcx, ty::ParamEnv::empty().and(ty), valtree) };