about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_trans/consts.rs15
-rw-r--r--src/librustc_trans/trans_item.rs40
2 files changed, 27 insertions, 28 deletions
diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs
index f9f185dfa51..1608c4a87bf 100644
--- a/src/librustc_trans/consts.rs
+++ b/src/librustc_trans/consts.rs
@@ -226,8 +226,15 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
             // statically in the final application, we always mark such symbols as 'dllimport'.
             // If final linkage happens to be static, we rely on compiler-emitted __imp_ stubs to
             // make things work.
-            unsafe {
-                llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport);
+            //
+            // However, in some scenarios we defer emission of statics to downstream
+            // crates, so there are cases where a static with an upstream DefId
+            // is actually present in the current crate. We can find out via the
+            // is_translated_item query.
+            if !cx.tcx.is_translated_item(def_id) {
+                unsafe {
+                    llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport);
+                }
             }
         }
         g
@@ -246,8 +253,8 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
 }
 
 pub fn trans_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
-                              m: hir::Mutability,
                               def_id: DefId,
+                              is_mutable: bool,
                               attrs: &[ast::Attribute])
                               -> Result<ValueRef, ConstEvalErr<'tcx>> {
     unsafe {
@@ -298,7 +305,7 @@ pub fn trans_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
 
         // As an optimization, all shared statics which do not have interior
         // mutability are placed into read-only memory.
-        if m != hir::MutMutable {
+        if !is_mutable {
             if cx.type_is_freeze(ty) {
                 llvm::LLVMSetGlobalConstant(g, llvm::True);
             }
diff --git a/src/librustc_trans/trans_item.rs b/src/librustc_trans/trans_item.rs
index 2751e329259..91c1097fc7f 100644
--- a/src/librustc_trans/trans_item.rs
+++ b/src/librustc_trans/trans_item.rs
@@ -24,6 +24,7 @@ use llvm;
 use monomorphize::Instance;
 use type_of::LayoutLlvmExt;
 use rustc::hir;
+use rustc::hir::def::Def;
 use rustc::hir::def_id::DefId;
 use rustc::mir::mono::{Linkage, Visibility};
 use rustc::ty::TypeFoldable;
@@ -46,24 +47,23 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
         match *self.as_mono_item() {
             MonoItem::Static(def_id) => {
                 let tcx = cx.tcx;
-                let node_id = match tcx.hir.as_local_node_id(def_id) {
-                    Some(node_id) => node_id,
+                let is_mutable = match tcx.describe_def(def_id) {
+                    Some(Def::Static(_, is_mutable)) => is_mutable,
+                    Some(other) => {
+                        bug!("Expected Def::Static, found {:?}", other)
+                    }
                     None => {
-                        bug!("MonoItemExt::define() called for non-local \
-                              static `{:?}`.", def_id)
+                        bug!("Expected Def::Static for {:?}, found nothing", def_id)
+                    }
+                };
+                let attrs = tcx.get_attrs(def_id);
+
+                match consts::trans_static(&cx, def_id, is_mutable, &attrs) {
+                    Ok(_) => { /* Cool, everything's alright. */ },
+                    Err(err) => {
+                        err.report(tcx, tcx.def_span(def_id), "static");
                     }
                 };
-                let item = tcx.hir.expect_item(node_id);
-                if let hir::ItemStatic(_, m, _) = item.node {
-                    match consts::trans_static(&cx, m, def_id, &item.attrs) {
-                        Ok(_) => { /* Cool, everything's alright. */ },
-                        Err(err) => {
-                            err.report(tcx, item.span, "static");
-                        }
-                    };
-                } else {
-                    span_bug!(item.span, "Mismatch between hir::Item type and TransItem type")
-                }
             }
             MonoItem::GlobalAsm(node_id) => {
                 let item = cx.tcx.hir.expect_item(node_id);
@@ -137,20 +137,12 @@ fn predefine_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
                               linkage: Linkage,
                               visibility: Visibility,
                               symbol_name: &str) {
-    let node_id = match cx.tcx.hir.as_local_node_id(def_id) {
-        Some(node_id) => node_id,
-        None => {
-            bug!("MonoItemExt::predefine() called for non-local static `{:?}`.",
-                 def_id)
-        }
-    };
-
     let instance = Instance::mono(cx.tcx, def_id);
     let ty = instance.ty(cx.tcx);
     let llty = cx.layout_of(ty).llvm_type(cx);
 
     let g = declare::define_global(cx, symbol_name, llty).unwrap_or_else(|| {
-        cx.sess().span_fatal(cx.tcx.hir.span(node_id),
+        cx.sess().span_fatal(cx.tcx.def_span(def_id),
             &format!("symbol `{}` is already defined", symbol_name))
     });