]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_trans/trans/consts.rs
Auto merge of #31684 - tmiasko:alternate-stack, r=alexcrichton
[rust.git] / src / librustc_trans / trans / consts.rs
index 0d6324f3e899aba5fd49b838599022ad270a918e..e8c90fa31eac22bf30b9c189b58b1e989a90205c 100644 (file)
@@ -24,8 +24,6 @@
 use middle::const_eval::{const_int_checked_rem, const_uint_checked_rem};
 use middle::const_eval::{const_int_checked_shl, const_uint_checked_shl};
 use middle::const_eval::{const_int_checked_shr, const_uint_checked_shr};
-use middle::const_eval::EvalHint::ExprTypeChecked;
-use middle::const_eval::eval_const_expr_partial;
 use middle::def::Def;
 use middle::def_id::DefId;
 use trans::{adt, closure, debuginfo, expr, inline, machine};
@@ -52,7 +50,7 @@
 use std::ffi::{CStr, CString};
 use std::borrow::Cow;
 use libc::c_uint;
-use syntax::ast;
+use syntax::ast::{self, LitKind};
 use syntax::attr;
 use syntax::parse::token;
 use syntax::ptr::P;
@@ -64,15 +62,15 @@ pub fn const_lit(cx: &CrateContext, e: &hir::Expr, lit: &ast::Lit)
     let _icx = push_ctxt("trans_lit");
     debug!("const_lit: {:?}", lit);
     match lit.node {
-        ast::LitByte(b) => C_integral(Type::uint_from_ty(cx, ast::TyU8), b as u64, false),
-        ast::LitChar(i) => C_integral(Type::char(cx), i as u64, false),
-        ast::LitInt(i, ast::SignedIntLit(t, _)) => {
+        LitKind::Byte(b) => C_integral(Type::uint_from_ty(cx, ast::UintTy::U8), b as u64, false),
+        LitKind::Char(i) => C_integral(Type::char(cx), i as u64, false),
+        LitKind::Int(i, ast::LitIntType::Signed(t)) => {
             C_integral(Type::int_from_ty(cx, t), i, true)
         }
-        ast::LitInt(u, ast::UnsignedIntLit(t)) => {
+        LitKind::Int(u, ast::LitIntType::Unsigned(t)) => {
             C_integral(Type::uint_from_ty(cx, t), u, false)
         }
-        ast::LitInt(i, ast::UnsuffixedIntLit(_)) => {
+        LitKind::Int(i, ast::LitIntType::Unsuffixed) => {
             let lit_int_ty = cx.tcx().node_id_to_type(e.id);
             match lit_int_ty.sty {
                 ty::TyInt(t) => {
@@ -87,10 +85,10 @@ pub fn const_lit(cx: &CrateContext, e: &hir::Expr, lit: &ast::Lit)
                                 lit_int_ty))
             }
         }
-        ast::LitFloat(ref fs, t) => {
+        LitKind::Float(ref fs, t) => {
             C_floating(&fs, Type::float_from_ty(cx, t))
         }
-        ast::LitFloatUnsuffixed(ref fs) => {
+        LitKind::FloatUnsuffixed(ref fs) => {
             let lit_float_ty = cx.tcx().node_id_to_type(e.id);
             match lit_float_ty.sty {
                 ty::TyFloat(t) => {
@@ -102,9 +100,9 @@ pub fn const_lit(cx: &CrateContext, e: &hir::Expr, lit: &ast::Lit)
                 }
             }
         }
-        ast::LitBool(b) => C_bool(cx, b),
-        ast::LitStr(ref s, _) => C_str_slice(cx, (*s).clone()),
-        ast::LitByteStr(ref data) => {
+        LitKind::Bool(b) => C_bool(cx, b),
+        LitKind::Str(ref s, _) => C_str_slice(cx, (*s).clone()),
+        LitKind::ByteStr(ref data) => {
             addr_of(cx, C_bytes(cx, &data[..]), 1, "byte_str")
         }
     }
@@ -212,7 +210,7 @@ fn const_fn_call<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     let substs = ccx.tcx().mk_substs(node_id_substs(ccx, node, param_substs));
     match fn_like.body().expr {
         Some(ref expr) => {
-            const_expr(ccx, &**expr, substs, Some(&fn_args), trueconst).map(|(res, _)| res)
+            const_expr(ccx, &expr, substs, Some(&fn_args), trueconst).map(|(res, _)| res)
         },
         None => Ok(C_nil(ccx)),
     }
@@ -261,7 +259,7 @@ pub fn description(&self) -> Cow<str> {
     }
 }
 
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
 pub enum TrueConst {
     Yes, No
 }
@@ -570,7 +568,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
     let map_list = |exprs: &[P<hir::Expr>]| -> Result<Vec<ValueRef>, ConstEvalFailure> {
         exprs.iter()
-             .map(|e| const_expr(cx, &**e, param_substs, fn_args, trueconst).map(|(l, _)| l))
+             .map(|e| const_expr(cx, &e, param_substs, fn_args, trueconst).map(|(l, _)| l))
              .collect::<Vec<Result<ValueRef, ConstEvalFailure>>>()
              .into_iter()
              .collect()
@@ -578,11 +576,11 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     };
     let _icx = push_ctxt("const_expr");
     Ok(match e.node {
-        hir::ExprLit(ref lit) => const_lit(cx, e, &**lit),
+        hir::ExprLit(ref lit) => const_lit(cx, e, &lit),
         hir::ExprBinary(b, ref e1, ref e2) => {
             /* Neither type is bottom, and we expect them to be unified
              * already, so the following is safe. */
-            let (te1, ty) = try!(const_expr(cx, &**e1, param_substs, fn_args, trueconst));
+            let (te1, ty) = try!(const_expr(cx, &e1, param_substs, fn_args, trueconst));
             debug!("const_expr_unadjusted: te1={}, ty={:?}",
                    cx.tn().val_to_string(te1),
                    ty);
@@ -590,7 +588,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             let is_float = ty.is_fp();
             let signed = ty.is_signed();
 
-            let (te2, _) = try!(const_expr(cx, &**e2, param_substs, fn_args, trueconst));
+            let (te2, _) = try!(const_expr(cx, &e2, param_substs, fn_args, trueconst));
 
             try!(check_binary_expr_validity(cx, e, ty, te1, te2, trueconst));
 
@@ -638,7 +636,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             } } // unsafe { match b.node {
         },
         hir::ExprUnary(u, ref inner_e) => {
-            let (te, ty) = try!(const_expr(cx, &**inner_e, param_substs, fn_args, trueconst));
+            let (te, ty) = try!(const_expr(cx, &inner_e, param_substs, fn_args, trueconst));
 
             try!(check_unary_expr_validity(cx, e, ty, te, trueconst));
 
@@ -651,25 +649,25 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             } }
         },
         hir::ExprField(ref base, field) => {
-            let (bv, bt) = try!(const_expr(cx, &**base, param_substs, fn_args, trueconst));
+            let (bv, bt) = try!(const_expr(cx, &base, param_substs, fn_args, trueconst));
             let brepr = adt::represent_type(cx, bt);
             let vinfo = VariantInfo::from_ty(cx.tcx(), bt, None);
             let ix = vinfo.field_index(field.node);
-            adt::const_get_field(cx, &*brepr, bv, vinfo.discr, ix)
+            adt::const_get_field(cx, &brepr, bv, vinfo.discr, ix)
         },
         hir::ExprTupField(ref base, idx) => {
-            let (bv, bt) = try!(const_expr(cx, &**base, param_substs, fn_args, trueconst));
+            let (bv, bt) = try!(const_expr(cx, &base, param_substs, fn_args, trueconst));
             let brepr = adt::represent_type(cx, bt);
             let vinfo = VariantInfo::from_ty(cx.tcx(), bt, None);
-            adt::const_get_field(cx, &*brepr, bv, vinfo.discr, idx.node)
+            adt::const_get_field(cx, &brepr, bv, vinfo.discr, idx.node)
         },
         hir::ExprIndex(ref base, ref index) => {
-            let (bv, bt) = try!(const_expr(cx, &**base, param_substs, fn_args, trueconst));
-            let iv = match eval_const_expr_partial(cx.tcx(), &index, ExprTypeChecked, None) {
-                Ok(ConstVal::Int(i)) => i as u64,
-                Ok(ConstVal::Uint(u)) => u,
-                _ => cx.sess().span_bug(index.span,
-                                        "index is not an integer-constant expression")
+            let (bv, bt) = try!(const_expr(cx, &base, param_substs, fn_args, trueconst));
+            let iv = try!(const_expr(cx, &index, param_substs, fn_args, TrueConst::Yes)).0;
+            let iv = if let Some(iv) = const_to_opt_uint(iv) {
+                iv
+            } else {
+                cx.sess().span_bug(index.span, "index is not an integer-constant expression");
             };
             let (arr, len) = match bt.sty {
                 ty::TyArray(_, u) => (bv, C_uint(cx, u)),
@@ -716,7 +714,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         hir::ExprCast(ref base, _) => {
             let t_cast = ety;
             let llty = type_of::type_of(cx, t_cast);
-            let (v, t_expr) = try!(const_expr(cx, &**base, param_substs, fn_args, trueconst));
+            let (v, t_expr) = try!(const_expr(cx, &base, param_substs, fn_args, trueconst));
             debug!("trans_const_cast({:?} as {:?})", t_expr, t_cast);
             if expr::cast_is_noop(cx.tcx(), base, t_expr, t_cast) {
                 return Ok(v);
@@ -741,9 +739,9 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             ) {
                 (CastTy::Int(IntTy::CEnum), CastTy::Int(_)) => {
                     let repr = adt::represent_type(cx, t_expr);
-                    let discr = adt::const_get_discrim(cx, &*repr, v);
+                    let discr = adt::const_get_discrim(cx, &repr, v);
                     let iv = C_integral(cx.int_type(), discr.0, false);
-                    let s = adt::is_discr_signed(&*repr) as Bool;
+                    let s = adt::is_discr_signed(&repr) as Bool;
                     llvm::LLVMConstIntCast(iv, llty.to_ref(), s)
                 },
                 (CastTy::Int(_), CastTy::Int(_)) => {
@@ -798,18 +796,18 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             } else {
                 // If this isn't the address of a static, then keep going through
                 // normal constant evaluation.
-                let (v, ty) = try!(const_expr(cx, &**sub, param_substs, fn_args, trueconst));
+                let (v, ty) = try!(const_expr(cx, &sub, param_substs, fn_args, trueconst));
                 addr_of(cx, v, type_of::align_of(cx, ty), "ref")
             }
         },
         hir::ExprAddrOf(hir::MutMutable, ref sub) => {
-            let (v, ty) = try!(const_expr(cx, &**sub, param_substs, fn_args, trueconst));
+            let (v, ty) = try!(const_expr(cx, &sub, param_substs, fn_args, trueconst));
             addr_of_mut(cx, v, type_of::align_of(cx, ty), "ref_mut_slice")
         },
         hir::ExprTup(ref es) => {
             let repr = adt::represent_type(cx, ety);
             let vals = try!(map_list(&es[..]));
-            adt::trans_const(cx, &*repr, Disr(0), &vals[..])
+            adt::trans_const(cx, &repr, Disr(0), &vals[..])
         },
         hir::ExprStruct(_, ref fs, ref base_opt) => {
             let repr = adt::represent_type(cx, ety);
@@ -817,7 +815,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             let base_val = match *base_opt {
                 Some(ref base) => Some(try!(const_expr(
                     cx,
-                    &**base,
+                    &base,
                     param_substs,
                     fn_args,
                     trueconst,
@@ -829,9 +827,9 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             let cs = fields.iter().enumerate().map(|(ix, &Field(f_name, _))| {
                 match (fs.iter().find(|f| f_name == f.name.node), base_val) {
                     (Some(ref f), _) => {
-                        const_expr(cx, &*f.expr, param_substs, fn_args, trueconst).map(|(l, _)| l)
+                        const_expr(cx, &f.expr, param_substs, fn_args, trueconst).map(|(l, _)| l)
                     },
-                    (_, Some((bv, _))) => Ok(adt::const_get_field(cx, &*repr, bv, discr, ix)),
+                    (_, Some((bv, _))) => Ok(adt::const_get_field(cx, &repr, bv, discr, ix)),
                     (_, None) => cx.sess().span_bug(e.span, "missing struct field"),
                 }
             })
@@ -842,7 +840,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             if ety.is_simd() {
                 C_vector(&cs[..])
             } else {
-                adt::trans_const(cx, &*repr, discr, &cs[..])
+                adt::trans_const(cx, &repr, discr, &cs[..])
             }
         },
         hir::ExprVec(ref es) => {
@@ -851,7 +849,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             let vs = es.iter()
                        .map(|e| const_expr(
                            cx,
-                           &**e,
+                           &e,
                            param_substs,
                            fn_args,
                            trueconst,
@@ -871,7 +869,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             let unit_ty = ety.sequence_element_type(cx.tcx());
             let llunitty = type_of::type_of(cx, unit_ty);
             let n = cx.tcx().eval_repeat_count(count);
-            let unit_val = try!(const_expr(cx, &**elem, param_substs, fn_args, trueconst)).0;
+            let unit_val = try!(const_expr(cx, &elem, param_substs, fn_args, trueconst)).0;
             let vs = vec![unit_val; n];
             if val_ty(unit_val) != llunitty {
                 C_struct(cx, &vs[..], false)
@@ -900,7 +898,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                     match vinfo.kind() {
                         ty::VariantKind::Unit => {
                             let repr = adt::represent_type(cx, ety);
-                            adt::trans_const(cx, &*repr, Disr::from(vinfo.disr_val), &[])
+                            adt::trans_const(cx, &repr, Disr::from(vinfo.disr_val), &[])
                         }
                         ty::VariantKind::Tuple => {
                             expr::trans_def_fn_unadjusted(cx, e, def, param_substs).val
@@ -930,7 +928,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             loop {
                 callee = match callee.node {
                     hir::ExprBlock(ref block) => match block.expr {
-                        Some(ref tail) => &**tail,
+                        Some(ref tail) => &tail,
                         None => break,
                     },
                     _ => break,
@@ -954,14 +952,14 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                         C_vector(&arg_vals[..])
                     } else {
                         let repr = adt::represent_type(cx, ety);
-                        adt::trans_const(cx, &*repr, Disr(0), &arg_vals[..])
+                        adt::trans_const(cx, &repr, Disr(0), &arg_vals[..])
                     }
                 }
                 Def::Variant(enum_did, variant_did) => {
                     let repr = adt::represent_type(cx, ety);
                     let vinfo = cx.tcx().lookup_adt_def(enum_did).variant_with_id(variant_did);
                     adt::trans_const(cx,
-                                     &*repr,
+                                     &repr,
                                      Disr::from(vinfo.disr_val),
                                      &arg_vals[..])
                 }
@@ -975,12 +973,12 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             try!(const_fn_call(cx, MethodCallKey(method_call),
                                method_did, &arg_vals, param_substs, trueconst))
         },
-        hir::ExprType(ref e, _) => try!(const_expr(cx, &**e, param_substs, fn_args, trueconst)).0,
+        hir::ExprType(ref e, _) => try!(const_expr(cx, &e, param_substs, fn_args, trueconst)).0,
         hir::ExprBlock(ref block) => {
             match block.expr {
                 Some(ref expr) => try!(const_expr(
                     cx,
-                    &**expr,
+                    &expr,
                     param_substs,
                     fn_args,
                     trueconst,