]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_trans/trans/consts.rs
Auto merge of #30457 - Manishearth:rollup, r=Manishearth
[rust.git] / src / librustc_trans / trans / consts.rs
index 6f40283064bd05011a3bfb4c659649f963d8f8da..038e699a043ab4d755c17484959defab7227ed98 100644 (file)
@@ -31,6 +31,7 @@
 use trans::base::{self, push_ctxt};
 use trans::common::{self, type_is_sized, ExprOrMethodCall, node_id_substs, C_nil, const_get_elt};
 use trans::common::{CrateContext, C_integral, C_floating, C_bool, C_str_slice, C_bytes, val_ty};
+use trans::common::C_floating_f64;
 use trans::common::{C_struct, C_undef, const_to_opt_int, const_to_opt_uint, VariantInfo, C_uint};
 use trans::common::{type_is_fat_ptr, Field, C_vector, C_array, C_null, ExprId, MethodCallKey};
 use trans::declare;
@@ -107,6 +108,38 @@ pub fn const_lit(cx: &CrateContext, e: &hir::Expr, lit: &ast::Lit)
     }
 }
 
+pub fn trans_constval<'blk, 'tcx>(bcx: common::Block<'blk, 'tcx>,
+                                cv: &ConstVal,
+                                ty: Ty<'tcx>,
+                                param_substs: &'tcx Substs<'tcx>)
+                                -> ValueRef
+{
+    let ccx = bcx.ccx();
+    let llty = type_of::type_of(ccx, ty);
+    match *cv {
+        ConstVal::Float(v) => C_floating_f64(v, llty),
+        ConstVal::Bool(v) => C_bool(ccx, v),
+        ConstVal::Int(v) => C_integral(llty, v as u64, true),
+        ConstVal::Uint(v) => C_integral(llty, v, false),
+        ConstVal::Str(ref v) => C_str_slice(ccx, v.clone()),
+        ConstVal::ByteStr(ref v) => addr_of(ccx, C_bytes(ccx, v), 1, "byte_str"),
+        ConstVal::Struct(id) | ConstVal::Tuple(id) => {
+            let expr = bcx.tcx().map.expect_expr(id);
+            match const_expr(ccx, expr, param_substs, None, TrueConst::Yes) {
+                Ok((val, _)) => val,
+                Err(e) => panic!("const eval failure: {}", e.description()),
+            }
+        },
+        ConstVal::Array(id, _) | ConstVal::Repeat(id, _) => {
+            let expr = bcx.tcx().map.expect_expr(id);
+            expr::trans(bcx, expr).datum.val
+        },
+        ConstVal::Function(_) => {
+            unimplemented!()
+        },
+    }
+}
+
 pub fn ptrcast(val: ValueRef, ty: Type) -> ValueRef {
     unsafe {
         llvm::LLVMConstPointerCast(val, ty.to_ref())
@@ -287,27 +320,26 @@ pub fn get_const_expr_as_global<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                           -> Result<ValueRef, ConstEvalFailure> {
     debug!("get_const_expr_as_global: {:?}", expr.id);
     // Special-case constants to cache a common global for all uses.
-    match expr.node {
-        hir::ExprPath(..) => {
-            let def = ccx.tcx().def_map.borrow().get(&expr.id).unwrap().full_def();
-            match def {
-                def::DefConst(def_id) | def::DefAssociatedConst(def_id) => {
-                    if !ccx.tcx().tables.borrow().adjustments.contains_key(&expr.id) {
-                        debug!("get_const_expr_as_global ({:?}): found const {:?}",
-                               expr.id, def_id);
-                        return get_const_val(ccx, def_id, expr);
-                    }
+    if let hir::ExprPath(..) = expr.node {
+        // `def` must be its own statement and cannot be in the `match`
+        // otherwise the `def_map` will be borrowed for the entire match instead
+        // of just to get the `def` value
+        let def = ccx.tcx().def_map.borrow().get(&expr.id).unwrap().full_def();
+        match def {
+            def::DefConst(def_id) | def::DefAssociatedConst(def_id) => {
+                if !ccx.tcx().tables.borrow().adjustments.contains_key(&expr.id) {
+                    debug!("get_const_expr_as_global ({:?}): found const {:?}",
+                           expr.id, def_id);
+                    return get_const_val(ccx, def_id, expr);
                 }
-                _ => {}
-            }
+            },
+            _ => {},
         }
-        _ => {}
     }
 
     let key = (expr.id, param_substs);
-    match ccx.const_values().borrow().get(&key) {
-        Some(&val) => return Ok(val),
-        None => {}
+    if let Some(&val) = ccx.const_values().borrow().get(&key) {
+        return Ok(val);
     }
     let ty = monomorphize::apply_param_substs(ccx.tcx(), param_substs,
                                               &ccx.tcx().expr_ty(expr));
@@ -316,10 +348,7 @@ pub fn get_const_expr_as_global<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         // references, even when only the latter are correct.
         try!(const_expr_unadjusted(ccx, expr, ty, param_substs, None, trueconst))
     } else {
-        match const_expr(ccx, expr, param_substs, None, trueconst) {
-            Err(err) => return Err(err),
-            Ok((ok, _)) => ok,
-        }
+        try!(const_expr(ccx, expr, param_substs, None, trueconst)).0
     };
 
     // boolean SSA values are i1, but they have to be stored in i8 slots,
@@ -577,9 +606,7 @@ 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. */
@@ -1010,7 +1037,7 @@ pub fn trans_static(ccx: &CrateContext,
                     m: hir::Mutability,
                     expr: &hir::Expr,
                     id: ast::NodeId,
-                    attrs: &Vec<ast::Attribute>)
+                    attrs: &[ast::Attribute])
                     -> Result<ValueRef, ConstEvalErr> {
     unsafe {
         let _icx = push_ctxt("trans_static");