From 21deb18bfd2d84c8230b906f455007957013766e Mon Sep 17 00:00:00 2001
From: Simonas Kazlauskas <git@kazlauskas.me>
Date: Tue, 10 Nov 2015 23:22:57 +0200
Subject: [PATCH 1/2] [MIR trans] Translate statics

Fixes #29578
---
 src/librustc_trans/trans/common.rs     | 10 ++++++++++
 src/librustc_trans/trans/consts.rs     | 16 ++--------------
 src/librustc_trans/trans/mir/lvalue.rs |  5 ++++-
 3 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs
index 8d6ba53dd222d..7dda864d1ed9c 100644
--- a/src/librustc_trans/trans/common.rs
+++ b/src/librustc_trans/trans/common.rs
@@ -1214,3 +1214,13 @@ pub fn shift_mask_val<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     }
 }
 
+pub fn get_static_val<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
+                            did: DefId,
+                            ty: Ty<'tcx>)
+                            -> ValueRef {
+    if let Some(node_id) = ccx.tcx().map.as_local_node_id(did) {
+        base::get_item_val(ccx, node_id)
+    } else {
+        base::trans_external_path(ccx, did, ty)
+    }
+}
diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs
index 90faef51c2c6c..b849888cf7cfb 100644
--- a/src/librustc_trans/trans/consts.rs
+++ b/src/librustc_trans/trans/consts.rs
@@ -29,8 +29,8 @@ use middle::const_eval::eval_const_expr_partial;
 use middle::def_id::DefId;
 use trans::{adt, closure, debuginfo, expr, inline, machine};
 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::{type_is_sized, ExprOrMethodCall, node_id_substs, C_nil, const_get_elt};
 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;
@@ -795,7 +795,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             }
             let opt_def = cx.tcx().def_map.borrow().get(&cur.id).map(|d| d.full_def());
             if let Some(def::DefStatic(def_id, _)) = opt_def {
-                get_static_val(cx, def_id, ety)
+                common::get_static_val(cx, def_id, ety)
             } else {
                 // If this isn't the address of a static, then keep going through
                 // normal constant evaluation.
@@ -1075,15 +1075,3 @@ pub fn trans_static(ccx: &CrateContext,
         Ok(g)
     }
 }
-
-
-fn get_static_val<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
-                            did: DefId,
-                            ty: Ty<'tcx>)
-                            -> ValueRef {
-    if let Some(node_id) = ccx.tcx().map.as_local_node_id(did) {
-        base::get_item_val(ccx, node_id)
-    } else {
-        base::trans_external_path(ccx, did, ty)
-    }
-}
diff --git a/src/librustc_trans/trans/mir/lvalue.rs b/src/librustc_trans/trans/mir/lvalue.rs
index 1ce7b55a9c686..98c1566997616 100644
--- a/src/librustc_trans/trans/mir/lvalue.rs
+++ b/src/librustc_trans/trans/mir/lvalue.rs
@@ -65,7 +65,10 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
                     tcx.sess.bug(&format!("using operand temp {:?} as lvalue", lvalue)),
             },
             mir::Lvalue::Arg(index) => self.args[index as usize],
-            mir::Lvalue::Static(_def_id) => unimplemented!(),
+            mir::Lvalue::Static(def_id) => {
+                let const_ty = self.mir.lvalue_ty(tcx, lvalue);
+                LvalueRef::new(common::get_static_val(ccx, def_id, const_ty.to_ty(tcx)), const_ty)
+            },
             mir::Lvalue::ReturnPointer => {
                 let return_ty = bcx.monomorphize(&self.mir.return_ty);
                 let llval = fcx.get_ret_slot(bcx, return_ty, "return");

From f1342ffb3ca3f5641b55ecdc6481f5cd80f338d6 Mon Sep 17 00:00:00 2001
From: Simonas Kazlauskas <git@kazlauskas.me>
Date: Wed, 11 Nov 2015 00:19:37 +0200
Subject: [PATCH 2/2] Simplify trans/exprs.rs DefStatic considerably

---
 src/librustc_trans/trans/common.rs |  2 +-
 src/librustc_trans/trans/expr.rs   | 23 +----------------------
 2 files changed, 2 insertions(+), 23 deletions(-)

diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs
index 7dda864d1ed9c..ac3e3beeac83c 100644
--- a/src/librustc_trans/trans/common.rs
+++ b/src/librustc_trans/trans/common.rs
@@ -1221,6 +1221,6 @@ pub fn get_static_val<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     if let Some(node_id) = ccx.tcx().map.as_local_node_id(did) {
         base::get_item_val(ccx, node_id)
     } else {
-        base::trans_external_path(ccx, did, ty)
+        base::get_extern_const(ccx, did, ty)
     }
 }
diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs
index 7648587e35268..f408bb595a2b7 100644
--- a/src/librustc_trans/trans/expr.rs
+++ b/src/librustc_trans/trans/expr.rs
@@ -941,29 +941,8 @@ fn trans_def<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             DatumBlock::new(bcx, datum.to_expr_datum())
         }
         def::DefStatic(did, _) => {
-            // There are two things that may happen here:
-            //  1) If the static item is defined in this crate, it will be
-            //     translated using `get_item_val`, and we return a pointer to
-            //     the result.
-            //  2) If the static item is defined in another crate then we add
-            //     (or reuse) a declaration of an external global, and return a
-            //     pointer to that.
             let const_ty = expr_ty(bcx, ref_expr);
-
-            // For external constants, we don't inline.
-            let val = if let Some(node_id) = bcx.tcx().map.as_local_node_id(did) {
-                // Case 1.
-
-                // The LLVM global has the type of its initializer,
-                // which may not be equal to the enum's type for
-                // non-C-like enums.
-                let val = base::get_item_val(bcx.ccx(), node_id);
-                let pty = type_of::type_of(bcx.ccx(), const_ty).ptr_to();
-                PointerCast(bcx, val, pty)
-            } else {
-                // Case 2.
-                base::get_extern_const(bcx.ccx(), did, const_ty)
-            };
+            let val = get_static_val(bcx.ccx(), did, const_ty);
             let lval = Lvalue::new("expr::trans_def");
             DatumBlock::new(bcx, Datum::new(val, const_ty, LvalueExpr(lval)))
         }