Use early unwraps instead of bubbling up errors just to unwrap in the end
This commit is contained in:
parent
a9da8fc9c2
commit
5c0615b89c
@ -49,36 +49,36 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
constant: Result<ty::Const<'tcx>, 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<Vec<_>, 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(
|
||||
|
@ -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<VariantIdx>,
|
||||
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>(
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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),
|
||||
|
Loading…
x
Reference in New Issue
Block a user