From 5c0615b89c399ce6a431ba660f9457c24bc69964 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sat, 16 Feb 2019 20:51:43 +0100 Subject: [PATCH] Use early unwraps instead of bubbling up errors just to unwrap in the end --- src/librustc_codegen_ssa/mir/constant.rs | 14 ++++---- src/librustc_mir/const_eval.rs | 43 +++++++++++------------- src/librustc_mir/hair/pattern/_match.rs | 8 +---- src/librustc_mir/hair/pattern/mod.rs | 9 ++--- 4 files changed, 30 insertions(+), 44 deletions(-) diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs index 6bc69efa4a7d5..349c9132842b8 100644 --- a/src/librustc_codegen_ssa/mir/constant.rs +++ b/src/librustc_codegen_ssa/mir/constant.rs @@ -49,36 +49,36 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { constant: Result, ErrorHandled>, ) -> (Bx::Value, Ty<'tcx>) { constant - .and_then(|c| { + .map(|c| { let field_ty = c.ty.builtin_index().unwrap(); let fields = match c.ty.sty { ty::Array(_, n) => n.unwrap_usize(bx.tcx()), ref other => bug!("invalid simd shuffle type: {}", other), }; - let values: Result, ErrorHandled> = (0..fields).map(|field| { + let values: Vec<_> = (0..fields).map(|field| { let field = const_field( bx.tcx(), ty::ParamEnv::reveal_all(), None, mir::Field::new(field as usize), c, - )?; + ); if let Some(prim) = field.val.try_to_scalar() { let layout = bx.layout_of(field_ty); let scalar = match layout.abi { layout::Abi::Scalar(ref x) => x, _ => bug!("from_const: invalid ByVal layout: {:#?}", layout) }; - Ok(bx.scalar_to_backend( + bx.scalar_to_backend( prim, scalar, bx.immediate_backend_type(layout), - )) + ) } else { bug!("simd shuffle field {:?}", field) } }).collect(); - let llval = bx.const_struct(&values?, false); - Ok((llval, c.ty)) + let llval = bx.const_struct(&values, false); + (llval, c.ty) }) .unwrap_or_else(|_| { bx.tcx().sess.span_err( diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 35ca13891876c..ee522570b3634 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -466,45 +466,42 @@ impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx> } /// Projects to a field of a (variant of a) const. +// this function uses `unwrap` copiously, because an already validated constant must have valid +// fields and can thus never fail outside of compiler bugs pub fn const_field<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, param_env: ty::ParamEnv<'tcx>, variant: Option, field: mir::Field, value: ty::Const<'tcx>, -) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> { +) -> ty::Const<'tcx> { trace!("const_field: {:?}, {:?}", field, value); let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env); - let result = (|| { - // get the operand again - let op = ecx.const_to_op(value, None)?; - // downcast - let down = match variant { - None => op, - Some(variant) => ecx.operand_downcast(op, variant)? - }; - // then project - let field = ecx.operand_field(down, field.index() as u64)?; - // and finally move back to the const world, always normalizing because - // this is not called for statics. - op_to_const(&ecx, field) - })(); - result.map_err(|error| { - let err = error_to_const_error(&ecx, error); - err.report_as_error(ecx.tcx, "could not access field of constant"); - ErrorHandled::Reported - }) + // get the operand again + let op = ecx.const_to_op(value, None).unwrap(); + // downcast + let down = match variant { + None => op, + Some(variant) => ecx.operand_downcast(op, variant).unwrap(), + }; + // then project + let field = ecx.operand_field(down, field.index() as u64).unwrap(); + // and finally move back to the const world, always normalizing because + // this is not called for statics. + op_to_const(&ecx, field).unwrap() } +// this function uses `unwrap` copiously, because an already validated constant must have valid +// fields and can thus never fail outside of compiler bugs pub fn const_variant_index<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, param_env: ty::ParamEnv<'tcx>, val: ty::Const<'tcx>, -) -> EvalResult<'tcx, VariantIdx> { +) -> VariantIdx { trace!("const_variant_index: {:?}", val); let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env); - let op = ecx.const_to_op(val, None)?; - Ok(ecx.read_discriminant(op)?.1) + let op = ecx.const_to_op(val, None).unwrap(); + ecx.read_discriminant(op).unwrap().1 } pub fn error_to_const_error<'a, 'mir, 'tcx>( diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 60eb30e075339..586a3fdb907ee 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -440,13 +440,7 @@ impl<'tcx> Constructor<'tcx> { assert!(!adt.is_enum()); VariantIdx::new(0) } - &ConstantValue(c) => { - crate::const_eval::const_variant_index( - cx.tcx, - cx.param_env, - c, - ).unwrap() - }, + &ConstantValue(c) => crate::const_eval::const_variant_index(cx.tcx, cx.param_env, c), _ => bug!("bad constructor {:?} for adt {:?}", self, adt) } } diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index d5f2e7a7275e8..ab54d4c50b5ee 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -937,10 +937,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { debug!("const_to_pat: cv={:#?} id={:?}", cv, id); let adt_subpattern = |i, variant_opt| { let field = Field::new(i); - let val = const_field( - self.tcx, self.param_env, - variant_opt, field, cv, - ).expect("field access failed"); + let val = const_field(self.tcx, self.param_env, variant_opt, field, cv); self.const_to_pat(instance, val, id, span) }; let adt_subpatterns = |n, variant_opt| { @@ -979,9 +976,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { PatternKind::Wild } ty::Adt(adt_def, substs) if adt_def.is_enum() => { - let variant_index = const_variant_index( - self.tcx, self.param_env, cv - ).expect("const_variant_index failed"); + let variant_index = const_variant_index(self.tcx, self.param_env, cv); let subpatterns = adt_subpatterns( adt_def.variants[variant_index].fields.len(), Some(variant_index),