diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs index 49e5c0dc21f9..7f8f2e9b9060 100644 --- a/src/librustc/mir/mono.rs +++ b/src/librustc/mir/mono.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use hir::def_id::DefId; use syntax::ast::NodeId; use syntax::symbol::InternedString; use ty::{Instance, TyCtxt}; @@ -21,7 +22,7 @@ use std::hash::Hash; #[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)] pub enum MonoItem<'tcx> { Fn(Instance<'tcx>), - Static(NodeId), + Static(DefId), GlobalAsm(NodeId), } @@ -50,7 +51,9 @@ impl<'tcx> HashStable> for MonoItem<'tcx> { MonoItem::Fn(ref instance) => { instance.hash_stable(hcx, hasher); } - MonoItem::Static(node_id) | + MonoItem::Static(def_id) => { + def_id.hash_stable(hcx, hasher); + } MonoItem::GlobalAsm(node_id) => { hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { node_id.hash_stable(hcx, hasher); diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index a80dfaef0dab..eb4ba21489c3 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -368,8 +368,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let recursion_depth_reset; match starting_point { - MonoItem::Static(node_id) => { - let def_id = tcx.hir.local_def_id(node_id); + MonoItem::Static(def_id) => { let instance = Instance::mono(tcx, def_id); // Sanity check whether this ended up being collected accidentally @@ -652,8 +651,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { let tcx = self.tcx; let instance = Instance::mono(tcx, static_.def_id); if should_monomorphize_locally(tcx, &instance) { - let node_id = tcx.hir.as_local_node_id(static_.def_id).unwrap(); - self.output.push(MonoItem::Static(node_id)); + self.output.push(MonoItem::Static(static_.def_id)); } self.super_static(static_, context, location); @@ -946,10 +944,10 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> { self.output.push(MonoItem::GlobalAsm(item.id)); } hir::ItemStatic(..) => { + let def_id = self.tcx.hir.local_def_id(item.id); debug!("RootCollector: ItemStatic({})", - def_id_to_string(self.tcx, - self.tcx.hir.local_def_id(item.id))); - self.output.push(MonoItem::Static(item.id)); + def_id_to_string(self.tcx, def_id)); + self.output.push(MonoItem::Static(def_id)); } hir::ItemConst(..) => { // const items only generate mono items if they are diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index a5078187a57e..549919a2c891 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -97,8 +97,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug { fn symbol_name(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::SymbolName { match *self.as_mono_item() { MonoItem::Fn(instance) => tcx.symbol_name(instance), - MonoItem::Static(node_id) => { - let def_id = tcx.hir.local_def_id(node_id); + MonoItem::Static(def_id) => { tcx.symbol_name(Instance::mono(tcx, def_id)) } MonoItem::GlobalAsm(node_id) => { @@ -159,7 +158,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug { fn explicit_linkage(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option { let def_id = match *self.as_mono_item() { MonoItem::Fn(ref instance) => instance.def_id(), - MonoItem::Static(node_id) => tcx.hir.local_def_id(node_id), + MonoItem::Static(def_id) => def_id, MonoItem::GlobalAsm(..) => return None, }; @@ -209,7 +208,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug { debug!("is_instantiable({:?})", self); let (def_id, substs) = match *self.as_mono_item() { MonoItem::Fn(ref instance) => (instance.def_id(), instance.substs), - MonoItem::Static(node_id) => (tcx.hir.local_def_id(node_id), Substs::empty()), + MonoItem::Static(def_id) => (def_id, Substs::empty()), // global asm never has predicates MonoItem::GlobalAsm(..) => return true }; @@ -218,14 +217,11 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug { } fn to_string(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> String { - let hir_map = &tcx.hir; - return match *self.as_mono_item() { MonoItem::Fn(instance) => { to_string_internal(tcx, "fn ", instance) }, - MonoItem::Static(node_id) => { - let def_id = hir_map.local_def_id(node_id); + MonoItem::Static(def_id) => { let instance = Instance::new(def_id, tcx.intern_substs(&[])); to_string_internal(tcx, "static ", instance) }, @@ -251,7 +247,9 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug { MonoItem::Fn(Instance { def, .. }) => { tcx.hir.as_local_node_id(def.def_id()) } - MonoItem::Static(node_id) | + MonoItem::Static(def_id) => { + tcx.hir.as_local_node_id(def_id) + } MonoItem::GlobalAsm(node_id) => { Some(node_id) } diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index e9471cdb4f94..2b558e71483c 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -180,7 +180,9 @@ pub trait CodegenUnitExt<'tcx> { } } } - MonoItem::Static(node_id) | + MonoItem::Static(def_id) => { + tcx.hir.as_local_node_id(def_id) + } MonoItem::GlobalAsm(node_id) => { Some(node_id) } @@ -382,7 +384,15 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }; (Linkage::External, visibility) } - MonoItem::Static(node_id) | + MonoItem::Static(def_id) => { + let visibility = if tcx.is_exported_symbol(def_id) { + can_be_internalized = false; + default_visibility(def_id) + } else { + Visibility::Hidden + }; + (Linkage::External, visibility) + } MonoItem::GlobalAsm(node_id) => { let def_id = tcx.hir.local_def_id(node_id); let visibility = if tcx.is_exported_symbol(def_id) { @@ -643,7 +653,7 @@ fn characteristic_def_id_of_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, Some(def_id) } - MonoItem::Static(node_id) | + MonoItem::Static(def_id) => Some(def_id), MonoItem::GlobalAsm(node_id) => Some(tcx.hir.local_def_id(node_id)), } } diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs index 82e59bf4f5d1..f9f185dfa516 100644 --- a/src/librustc_trans/consts.rs +++ b/src/librustc_trans/consts.rs @@ -16,7 +16,7 @@ use rustc::hir::map as hir_map; use rustc::middle::const_val::ConstEvalErr; use debuginfo; use base; -use monomorphize::{MonoItem, MonoItemExt}; +use monomorphize::MonoItem; use common::{CodegenCx, val_ty}; use declare; use monomorphize::Instance; @@ -110,7 +110,17 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef { return g; } + let defined_in_current_codegen_unit = cx.codegen_unit + .items() + .contains_key(&MonoItem::Static(def_id)); + assert!(!defined_in_current_codegen_unit, + "consts::get_static() should always hit the cache for \ + statics defined in the same CGU, but did not for `{:?}`", + def_id); + let ty = instance.ty(cx.tcx); + let sym = cx.tcx.symbol_name(instance); + let g = if let Some(id) = cx.tcx.hir.as_local_node_id(def_id) { let llty = cx.layout_of(ty).llvm_type(cx); @@ -118,13 +128,6 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef { hir_map::NodeItem(&hir::Item { ref attrs, span, node: hir::ItemStatic(..), .. }) => { - let sym = MonoItem::Static(id).symbol_name(cx.tcx); - - let defined_in_current_codegen_unit = cx.codegen_unit - .items() - .contains_key(&MonoItem::Static(id)); - assert!(!defined_in_current_codegen_unit); - if declare::get_declared_value(cx, &sym[..]).is_some() { span_bug!(span, "trans: Conflicting symbol names for static?"); } @@ -143,7 +146,7 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef { hir_map::NodeForeignItem(&hir::ForeignItem { ref attrs, span, node: hir::ForeignItemStatic(..), .. }) => { - let sym = cx.tcx.symbol_name(instance); + let g = if let Some(name) = attr::first_attr_value_str_by_name(&attrs, "linkage") { // If this is a static with a linkage specified, then we need to handle @@ -203,8 +206,6 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef { g } else { - let sym = cx.tcx.symbol_name(instance); - // FIXME(nagisa): perhaps the map of externs could be offloaded to llvm somehow? // FIXME(nagisa): investigate whether it can be changed into define_global let g = declare::declare_global(cx, &sym, cx.layout_of(ty).llvm_type(cx)); @@ -246,11 +247,10 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef { pub fn trans_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, m: hir::Mutability, - id: ast::NodeId, + def_id: DefId, attrs: &[ast::Attribute]) -> Result> { unsafe { - let def_id = cx.tcx.hir.local_def_id(id); let g = get_static(cx, def_id); let v = ::mir::trans_static_initializer(cx, def_id)?; diff --git a/src/librustc_trans/trans_item.rs b/src/librustc_trans/trans_item.rs index 5eb6679fe252..2751e3292593 100644 --- a/src/librustc_trans/trans_item.rs +++ b/src/librustc_trans/trans_item.rs @@ -24,10 +24,10 @@ use llvm; use monomorphize::Instance; use type_of::LayoutLlvmExt; use rustc::hir; +use rustc::hir::def_id::DefId; use rustc::mir::mono::{Linkage, Visibility}; use rustc::ty::TypeFoldable; use rustc::ty::layout::LayoutOf; -use syntax::ast; use syntax::attr; use std::fmt; @@ -44,11 +44,18 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { cx.codegen_unit.name()); match *self.as_mono_item() { - MonoItem::Static(node_id) => { + 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, + None => { + bug!("MonoItemExt::define() called for non-local \ + static `{:?}`.", def_id) + } + }; let item = tcx.hir.expect_item(node_id); if let hir::ItemStatic(_, m, _) = item.node { - match consts::trans_static(&cx, m, item.id, &item.attrs) { + match consts::trans_static(&cx, m, def_id, &item.attrs) { Ok(_) => { /* Cool, everything's alright. */ }, Err(err) => { err.report(tcx, item.span, "static"); @@ -91,8 +98,8 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { debug!("symbol {}", &symbol_name); match *self.as_mono_item() { - MonoItem::Static(node_id) => { - predefine_static(cx, node_id, linkage, visibility, &symbol_name); + MonoItem::Static(def_id) => { + predefine_static(cx, def_id, linkage, visibility, &symbol_name); } MonoItem::Fn(instance) => { predefine_fn(cx, instance, linkage, visibility, &symbol_name); @@ -126,11 +133,18 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { impl<'a, 'tcx> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {} fn predefine_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - node_id: ast::NodeId, + def_id: DefId, linkage: Linkage, visibility: Visibility, symbol_name: &str) { - let def_id = cx.tcx.hir.local_def_id(node_id); + 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);