1 use rustc::mir::interpret::ErrorHandled;
2 use rustc_mir::const_eval::const_field;
4 use rustc_data_structures::indexed_vec::Idx;
5 use rustc::mir::interpret::GlobalId;
6 use rustc::ty::{self, Ty};
8 use syntax::source_map::Span;
11 use super::FunctionCx;
13 impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
17 constant: &'tcx ty::LazyConst<'tcx>,
18 ) -> Result<ty::Const<'tcx>, ErrorHandled> {
20 ty::LazyConst::Unevaluated(def_id, ref substs) => {
22 let param_env = ty::ParamEnv::reveal_all();
23 let instance = ty::Instance::resolve(tcx, param_env, def_id, substs).unwrap();
28 tcx.const_eval(param_env.and(cid))
30 ty::LazyConst::Evaluated(constant) => Ok(constant),
34 pub fn eval_mir_constant(
37 constant: &mir::Constant<'tcx>,
38 ) -> Result<ty::Const<'tcx>, ErrorHandled> {
39 let c = self.monomorphize(&constant.literal);
40 self.fully_evaluate(bx, c)
43 /// process constant containing SIMD shuffle indices
44 pub fn simd_shuffle_indices(
49 constant: Result<ty::Const<'tcx>, ErrorHandled>,
50 ) -> (Bx::Value, Ty<'tcx>) {
53 let field_ty = c.ty.builtin_index().unwrap();
54 let fields = match c.ty.sty {
55 ty::Array(_, n) => n.unwrap_usize(bx.tcx()),
56 ref other => bug!("invalid simd shuffle type: {}", other),
58 let values: Result<Vec<_>, ErrorHandled> = (0..fields).map(|field| {
59 let field = const_field(
61 ty::ParamEnv::reveal_all(),
63 mir::Field::new(field as usize),
66 if let Some(prim) = field.val.try_to_scalar() {
67 let layout = bx.layout_of(field_ty);
68 let scalar = match layout.abi {
69 layout::Abi::Scalar(ref x) => x,
70 _ => bug!("from_const: invalid ByVal layout: {:#?}", layout)
72 Ok(bx.scalar_to_backend(
74 bx.immediate_backend_type(layout),
77 bug!("simd shuffle field {:?}", field)
80 let llval = bx.const_struct(&values?, false);
84 bx.tcx().sess.span_err(
86 "could not evaluate shuffle_indices at compile time",
88 // We've errored, so we don't have to produce working code.
89 let ty = self.monomorphize(&ty);
90 let llty = bx.backend_type(bx.layout_of(ty));
91 (bx.const_undef(llty), ty)