diff options
| -rw-r--r-- | src/librustc_trans/consts.rs | 15 | ||||
| -rw-r--r-- | src/librustc_trans/trans_item.rs | 40 |
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)) }); |
