Skip to content

Commit 89b3ef3

Browse files
Allow for instantiating statics from upstream crates.
1 parent 1be7f96 commit 89b3ef3

File tree

2 files changed

+27
-28
lines changed

2 files changed

+27
-28
lines changed

src/librustc_trans/consts.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,15 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
226226
// statically in the final application, we always mark such symbols as 'dllimport'.
227227
// If final linkage happens to be static, we rely on compiler-emitted __imp_ stubs to
228228
// make things work.
229-
unsafe {
230-
llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport);
229+
//
230+
// However, in some scenarios we defer emission of statics to downstream
231+
// crates, so there are cases where a static with an upstream DefId
232+
// is actually present in the current crate. We can find out via the
233+
// is_translated_item query.
234+
if !cx.tcx.is_translated_item(def_id) {
235+
unsafe {
236+
llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport);
237+
}
231238
}
232239
}
233240
g
@@ -246,8 +253,8 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
246253
}
247254

248255
pub fn trans_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
249-
m: hir::Mutability,
250256
def_id: DefId,
257+
is_mutable: bool,
251258
attrs: &[ast::Attribute])
252259
-> Result<ValueRef, ConstEvalErr<'tcx>> {
253260
unsafe {
@@ -298,7 +305,7 @@ pub fn trans_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
298305

299306
// As an optimization, all shared statics which do not have interior
300307
// mutability are placed into read-only memory.
301-
if m != hir::MutMutable {
308+
if !is_mutable {
302309
if cx.type_is_freeze(ty) {
303310
llvm::LLVMSetGlobalConstant(g, llvm::True);
304311
}

src/librustc_trans/trans_item.rs

+16-24
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use llvm;
2424
use monomorphize::Instance;
2525
use type_of::LayoutLlvmExt;
2626
use rustc::hir;
27+
use rustc::hir::def::Def;
2728
use rustc::hir::def_id::DefId;
2829
use rustc::mir::mono::{Linkage, Visibility};
2930
use rustc::ty::TypeFoldable;
@@ -46,24 +47,23 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
4647
match *self.as_mono_item() {
4748
MonoItem::Static(def_id) => {
4849
let tcx = cx.tcx;
49-
let node_id = match tcx.hir.as_local_node_id(def_id) {
50-
Some(node_id) => node_id,
50+
let is_mutable = match tcx.describe_def(def_id) {
51+
Some(Def::Static(_, is_mutable)) => is_mutable,
52+
Some(other) => {
53+
bug!("Expected Def::Static, found {:?}", other)
54+
}
5155
None => {
52-
bug!("MonoItemExt::define() called for non-local \
53-
static `{:?}`.", def_id)
56+
bug!("Expected Def::Static for {:?}, found nothing", def_id)
57+
}
58+
};
59+
let attrs = tcx.get_attrs(def_id);
60+
61+
match consts::trans_static(&cx, def_id, is_mutable, &attrs) {
62+
Ok(_) => { /* Cool, everything's alright. */ },
63+
Err(err) => {
64+
err.report(tcx, tcx.def_span(def_id), "static");
5465
}
5566
};
56-
let item = tcx.hir.expect_item(node_id);
57-
if let hir::ItemStatic(_, m, _) = item.node {
58-
match consts::trans_static(&cx, m, def_id, &item.attrs) {
59-
Ok(_) => { /* Cool, everything's alright. */ },
60-
Err(err) => {
61-
err.report(tcx, item.span, "static");
62-
}
63-
};
64-
} else {
65-
span_bug!(item.span, "Mismatch between hir::Item type and TransItem type")
66-
}
6767
}
6868
MonoItem::GlobalAsm(node_id) => {
6969
let item = cx.tcx.hir.expect_item(node_id);
@@ -137,20 +137,12 @@ fn predefine_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
137137
linkage: Linkage,
138138
visibility: Visibility,
139139
symbol_name: &str) {
140-
let node_id = match cx.tcx.hir.as_local_node_id(def_id) {
141-
Some(node_id) => node_id,
142-
None => {
143-
bug!("MonoItemExt::predefine() called for non-local static `{:?}`.",
144-
def_id)
145-
}
146-
};
147-
148140
let instance = Instance::mono(cx.tcx, def_id);
149141
let ty = instance.ty(cx.tcx);
150142
let llty = cx.layout_of(ty).llvm_type(cx);
151143

152144
let g = declare::define_global(cx, symbol_name, llty).unwrap_or_else(|| {
153-
cx.sess().span_fatal(cx.tcx.hir.span(node_id),
145+
cx.sess().span_fatal(cx.tcx.def_span(def_id),
154146
&format!("symbol `{}` is already defined", symbol_name))
155147
});
156148

0 commit comments

Comments
 (0)