From 25cf8001b1352fdaccdd1d71071c941f99acc2a1 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Wed, 17 Aug 2016 22:50:55 +0300 Subject: [PATCH] Remove AST from metadata except for consts and const fns. --- src/librustc/hir/map/mod.rs | 5 +- src/librustc/middle/cstore.rs | 7 +- src/librustc_metadata/astencode.rs | 8 +- src/librustc_metadata/csearch.rs | 5 - src/librustc_metadata/encoder.rs | 26 +-- src/librustc_trans/base.rs | 27 +-- src/librustc_trans/callee.rs | 197 +++++++-------------- src/librustc_trans/common.rs | 34 ---- src/librustc_trans/consts.rs | 12 +- src/librustc_trans/context.rs | 10 -- src/librustc_trans/debuginfo/metadata.rs | 22 +-- src/librustc_trans/debuginfo/mod.rs | 61 ++----- src/librustc_trans/debuginfo/source_loc.rs | 5 +- src/librustc_trans/glue.rs | 4 - src/librustc_trans/inline.rs | 52 ------ src/librustc_trans/intrinsic.rs | 2 +- src/librustc_trans/lib.rs | 1 - src/librustc_trans/monomorphize.rs | 150 +--------------- src/librustc_trans/trans_item.rs | 69 ++------ 19 files changed, 126 insertions(+), 571 deletions(-) delete mode 100644 src/librustc_trans/inline.rs diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 04031fabc5866..5e14bb51ce867 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -315,8 +315,7 @@ impl<'ast> Map<'ast> { RootInlinedParent(parent) => match *parent { InlinedItem::Item(def_id, _) | InlinedItem::TraitItem(def_id, _) | - InlinedItem::ImplItem(def_id, _) | - InlinedItem::Foreign(def_id, _) => + InlinedItem::ImplItem(def_id, _) => return DepNode::MetaData(def_id) }, @@ -940,8 +939,6 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, II::ImplItem(fld.fold_ops.new_def_id(d), ii.map(|ii| fld.fold_impl_item(ii))) } - II::Foreign(d, i) => II::Foreign(fld.fold_ops.new_def_id(d), - i.map(|i| fld.fold_foreign_item(i))) }; let ii = map.forest.inlined_items.alloc(ii); diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index abb22783ddc84..92e1b0681cc7e 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -96,8 +96,7 @@ pub enum DefLike { pub enum InlinedItem { Item(DefId /* def-id in source crate */, P), TraitItem(DefId /* impl id */, P), - ImplItem(DefId /* impl id */, P), - Foreign(DefId /* extern item */, P), + ImplItem(DefId /* impl id */, P) } /// A borrowed version of `hir::InlinedItem`. @@ -105,8 +104,7 @@ pub enum InlinedItem { pub enum InlinedItemRef<'a> { Item(DefId, &'a hir::Item), TraitItem(DefId, &'a hir::TraitItem), - ImplItem(DefId, &'a hir::ImplItem), - Foreign(DefId, &'a hir::ForeignItem) + ImplItem(DefId, &'a hir::ImplItem) } /// Item definitions in the currently-compiled crate would have the CrateNum @@ -286,7 +284,6 @@ impl InlinedItem { { match *self { InlinedItem::Item(_, ref i) => visitor.visit_item(&i), - InlinedItem::Foreign(_, ref i) => visitor.visit_foreign_item(&i), InlinedItem::TraitItem(_, ref ti) => visitor.visit_trait_item(ti), InlinedItem::ImplItem(_, ref ii) => visitor.visit_impl_item(ii), } diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index 1ef48e6d6565f..ad52d346857ff 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -79,7 +79,6 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext, ii: InlinedItemRef) { let id = match ii { InlinedItemRef::Item(_, i) => i.id, - InlinedItemRef::Foreign(_, i) => i.id, InlinedItemRef::TraitItem(_, ti) => ti.id, InlinedItemRef::ImplItem(_, ii) => ii.id, }; @@ -147,7 +146,6 @@ pub fn decode_inlined_item<'a, 'tcx>(cdata: &cstore::CrateMetadata, dcx); let name = match *ii { InlinedItem::Item(_, ref i) => i.name, - InlinedItem::Foreign(_, ref i) => i.name, InlinedItem::TraitItem(_, ref ti) => ti.name, InlinedItem::ImplItem(_, ref ii) => ii.name }; @@ -357,9 +355,6 @@ fn simplify_ast(ii: InlinedItemRef) -> (InlinedItem, IdRange) { InlinedItemRef::ImplItem(d, ii) => { InlinedItem::ImplItem(d, P(fold::noop_fold_impl_item(ii.clone(), &mut fld))) } - InlinedItemRef::Foreign(d, i) => { - InlinedItem::Foreign(d, P(fold::noop_fold_foreign_item(i.clone(), &mut fld))) - } }; (ii, fld.id_range) @@ -1208,8 +1203,7 @@ fn copy_item_types(dcx: &DecodeContext, ii: &InlinedItem, orig_did: DefId) { let item_node_id = match ii { &InlinedItem::Item(_, ref i) => i.id, &InlinedItem::TraitItem(_, ref ti) => ti.id, - &InlinedItem::ImplItem(_, ref ii) => ii.id, - &InlinedItem::Foreign(_, ref fi) => fi.id + &InlinedItem::ImplItem(_, ref ii) => ii.id }; copy_item_type(dcx, item_node_id, orig_did); diff --git a/src/librustc_metadata/csearch.rs b/src/librustc_metadata/csearch.rs index f6d698eb969d8..94426dcbf1d8d 100644 --- a/src/librustc_metadata/csearch.rs +++ b/src/librustc_metadata/csearch.rs @@ -562,11 +562,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { let inlined_root_node_id = find_inlined_item_root(item.id); cache_inlined_item(def_id, item.id, inlined_root_node_id); } - decoder::FoundAst::Found(&InlinedItem::Foreign(d, ref item)) => { - assert_eq!(d, def_id); - let inlined_root_node_id = find_inlined_item_root(item.id); - cache_inlined_item(def_id, item.id, inlined_root_node_id); - } decoder::FoundAst::FoundParent(parent_did, item) => { let inlined_root_node_id = find_inlined_item_root(item.id); cache_inlined_item(parent_did, item.id, inlined_root_node_id); diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 420dfbc58bf19..9a668b69b2eeb 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -40,7 +40,6 @@ use std::io::prelude::*; use std::io::{Cursor, SeekFrom}; use std::rc::Rc; use std::u32; -use syntax::abi::Abi; use syntax::ast::{self, NodeId, Name, CRATE_NODE_ID, CrateNum}; use syntax::attr::{self,AttrMetaMethods,AttributeMethods}; use errors::Handler; @@ -626,11 +625,6 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { if body.is_some() { encode_item_sort(self.rbml_w, 'p'); - encode_inlined_item(ecx, - self.rbml_w, - InlinedItemRef::TraitItem( - trait_def_id, - trait_item)); self.encode_mir(trait_item.id); } else { encode_item_sort(self.rbml_w, 'r'); @@ -728,12 +722,14 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { let types = generics.parent_types as usize + generics.types.len(); let needs_inline = types > 0 || is_default_impl || attr::requests_inline(&impl_item.attrs); - if needs_inline || sig.constness == hir::Constness::Const { + if sig.constness == hir::Constness::Const { encode_inlined_item( ecx, self.rbml_w, InlinedItemRef::ImplItem(ecx.tcx.map.local_def_id(parent_id), impl_item)); + } + if needs_inline || sig.constness == hir::Constness::Const { self.encode_mir(impl_item.id); } encode_constness(self.rbml_w, sig.constness); @@ -934,8 +930,10 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { encode_name(self.rbml_w, item.name); encode_attributes(self.rbml_w, &item.attrs); let needs_inline = tps_len > 0 || attr::requests_inline(&item.attrs); - if needs_inline || constness == hir::Constness::Const { + if constness == hir::Constness::Const { encode_inlined_item(ecx, self.rbml_w, InlinedItemRef::Item(def_id, item)); + } + if needs_inline || constness == hir::Constness::Const { self.encode_mir(item.id); } encode_constness(self.rbml_w, constness); @@ -982,8 +980,6 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { for v in &enum_definition.variants { encode_variant_id(self.rbml_w, ecx.tcx.map.local_def_id(v.node.data.id())); } - encode_inlined_item(ecx, self.rbml_w, InlinedItemRef::Item(def_id, item)); - self.encode_mir(item.id); // Encode inherent implementations for self enumeration. encode_inherent_implementations(ecx, self.rbml_w, def_id); @@ -1019,9 +1015,6 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { needs to know*/ self.encode_struct_fields(variant); - encode_inlined_item(ecx, self.rbml_w, InlinedItemRef::Item(def_id, item)); - self.encode_mir(item.id); - // Encode inherent implementations for self structure. encode_inherent_implementations(ecx, self.rbml_w, def_id); @@ -1265,7 +1258,6 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { let ecx = self.ecx(); debug!("writing foreign item {}", ecx.tcx.node_path_str(nitem.id)); - let abi = ecx.tcx.map.get_foreign_abi(nitem.id); encode_def_id_and_key(ecx, self.rbml_w, def_id); let parent_id = ecx.tcx.map.get_parent(nitem.id); @@ -1276,12 +1268,6 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { encode_family(self.rbml_w, FN_FAMILY); self.encode_bounds_and_type_for_item(nitem.id); encode_name(self.rbml_w, nitem.name); - if abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic { - encode_inlined_item(ecx, - self.rbml_w, - InlinedItemRef::Foreign(def_id, nitem)); - self.encode_mir(nitem.id); - } encode_attributes(self.rbml_w, &nitem.attrs); let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(nitem.id)); let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(nitem.id)); diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index e33c04f7e82ed..165884c8f55a2 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -66,7 +66,6 @@ use consts; use context::{SharedCrateContext, CrateContextList}; use debuginfo::{self, DebugLoc}; use declare; -use inline; use machine; use machine::{llalign_of_min, llsize_of}; use meth; @@ -949,14 +948,17 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> { false }; - let debug_context = if let (false, Some((instance, sig, abi))) = (no_debug, definition) { - debuginfo::create_function_debug_context(ccx, instance, sig, abi, llfndecl) + let mir = def_id.and_then(|id| ccx.get_mir(id)); + + let debug_context = if let (false, Some((instance, sig, abi)), &Some(ref mir)) = + (no_debug, definition, &mir) { + debuginfo::create_function_debug_context(ccx, instance, sig, abi, llfndecl, mir) } else { debuginfo::empty_function_debug_context(ccx) }; FunctionContext { - mir: def_id.and_then(|id| ccx.get_mir(id)), + mir: mir, llfn: llfndecl, llretslotptr: Cell::new(None), param_env: ccx.tcx().empty_parameter_environment(), @@ -1134,8 +1136,7 @@ pub fn trans_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, instance: Instance let sig = ccx.tcx().normalize_associated_type(&sig); let abi = fn_ty.fn_abi(); - let local_instance = inline::maybe_inline_instance(ccx, instance); - let lldecl = match ccx.instances().borrow().get(&local_instance) { + let lldecl = match ccx.instances().borrow().get(&instance) { Some(&val) => val, None => bug!("Instance `{:?}` not already declared", instance) }; @@ -1144,12 +1145,15 @@ pub fn trans_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, instance: Instance } pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, - ctor_id: ast::NodeId, + def_id: DefId, + substs: &'tcx Substs<'tcx>, disr: Disr, - param_substs: &'tcx Substs<'tcx>, llfndecl: ValueRef) { - let ctor_ty = ccx.tcx().node_id_to_type(ctor_id); - let ctor_ty = monomorphize::apply_param_substs(ccx.tcx(), param_substs, &ctor_ty); + attributes::inline(llfndecl, attributes::InlineAttr::Hint); + attributes::set_frame_pointer_elimination(ccx, llfndecl); + + let ctor_ty = ccx.tcx().lookup_item_type(def_id).ty; + let ctor_ty = monomorphize::apply_param_substs(ccx.tcx(), substs, &ctor_ty); let sig = ccx.tcx().erase_late_bound_regions(&ctor_ty.fn_sig()); let sig = ccx.tcx().normalize_associated_type(&sig); @@ -1742,10 +1746,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, println!("n_null_glues: {}", stats.n_null_glues.get()); println!("n_real_glues: {}", stats.n_real_glues.get()); - println!("n_fallback_instantiations: {}", stats.n_fallback_instantiations.get()); - println!("n_fns: {}", stats.n_fns.get()); - println!("n_monos: {}", stats.n_monos.get()); println!("n_inlines: {}", stats.n_inlines.get()); println!("n_closures: {}", stats.n_closures.get()); println!("fn stats:"); diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs index b661383d6060f..9aa486dc62811 100644 --- a/src/librustc_trans/callee.rs +++ b/src/librustc_trans/callee.rs @@ -18,12 +18,10 @@ pub use self::CalleeData::*; use arena::TypedArena; use back::symbol_names; -use llvm::{ValueRef, get_params}; -use middle::cstore::LOCAL_CRATE; +use llvm::{self, ValueRef, get_params}; use rustc::hir::def_id::DefId; use rustc::ty::subst::Substs; use rustc::traits; -use rustc::hir::map as hir_map; use abi::{Abi, FnType}; use attributes; use base; @@ -34,18 +32,15 @@ use common::{self, Block, Result, CrateContext, FunctionContext}; use consts; use debuginfo::DebugLoc; use declare; -use inline; use meth; use monomorphize::{self, Instance}; use trans_item::TransItem; use type_of; -use value::Value; use Disr; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc::hir; use syntax_pos::DUMMY_SP; -use errors; #[derive(Debug)] pub enum CalleeData { @@ -102,35 +97,28 @@ impl<'tcx> Callee<'tcx> { return Callee::trait_method(ccx, trait_id, def_id, substs); } - let maybe_node_id = inline::get_local_instance(ccx, def_id) - .and_then(|def_id| tcx.map.as_local_node_id(def_id)); - let maybe_ast_node = maybe_node_id.and_then(|node_id| { - tcx.map.find(node_id) - }); - - let data = match maybe_ast_node { - Some(hir_map::NodeStructCtor(_)) => { - NamedTupleConstructor(Disr(0)) - } - Some(hir_map::NodeVariant(_)) => { - let vinfo = common::inlined_variant_def(ccx, maybe_node_id.unwrap()); - NamedTupleConstructor(Disr::from(vinfo.disr_val)) - } - Some(hir_map::NodeForeignItem(fi)) if { - let abi = tcx.map.get_foreign_abi(fi.id); - abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic - } => Intrinsic, - - _ => { - let (llfn, ty) = get_fn(ccx, def_id, substs); - return Callee::ptr(llfn, ty); + let fn_ty = def_ty(tcx, def_id, substs); + if let ty::TyFnDef(_, _, f) = fn_ty.sty { + if f.abi == Abi::RustIntrinsic || f.abi == Abi::PlatformIntrinsic { + return Callee { + data: Intrinsic, + ty: fn_ty + }; } - }; + } - Callee { - data: data, - ty: def_ty(tcx, def_id, substs) + // FIXME(eddyb) Detect ADT constructors more efficiently. + if let Some(adt_def) = fn_ty.fn_ret().skip_binder().ty_adt_def() { + if let Some(v) = adt_def.variants.iter().find(|v| def_id == v.did) { + return Callee { + data: NamedTupleConstructor(Disr::from(v.disr_val)), + ty: fn_ty + }; + } } + + let (llfn, ty) = get_fn(ccx, def_id, substs); + Callee::ptr(llfn, ty) } /// Trait method, which has to be resolved to an impl method. @@ -168,24 +156,14 @@ impl<'tcx> Callee<'tcx> { trait_closure_kind); let method_ty = def_ty(tcx, def_id, substs); - let fn_ptr_ty = match method_ty.sty { - ty::TyFnDef(_, _, fty) => tcx.mk_fn_ptr(fty), - _ => bug!("expected fn item type, found {}", - method_ty) - }; - Callee::ptr(llfn, fn_ptr_ty) + Callee::ptr(llfn, method_ty) } traits::VtableFnPointer(vtable_fn_pointer) => { let trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_id).unwrap(); let llfn = trans_fn_pointer_shim(ccx, trait_closure_kind, vtable_fn_pointer.fn_ty); let method_ty = def_ty(tcx, def_id, substs); - let fn_ptr_ty = match method_ty.sty { - ty::TyFnDef(_, _, fty) => tcx.mk_fn_ptr(fty), - _ => bug!("expected fn item type, found {}", - method_ty) - }; - Callee::ptr(llfn, fn_ptr_ty) + Callee::ptr(llfn, method_ty) } traits::VtableObject(ref data) => { Callee { @@ -242,9 +220,21 @@ impl<'tcx> Callee<'tcx> { Virtual(idx) => { meth::trans_object_shim(ccx, self.ty, idx) } - NamedTupleConstructor(_) => match self.ty.sty { + NamedTupleConstructor(disr) => match self.ty.sty { ty::TyFnDef(def_id, substs, _) => { - return get_fn(ccx, def_id, substs).0; + let instance = Instance::new(def_id, substs); + if let Some(&llfn) = ccx.instances().borrow().get(&instance) { + return llfn; + } + + let sym = ccx.symbol_map().get_or_compute(ccx.shared(), + TransItem::Fn(instance)); + assert!(!ccx.codegen_unit().contains_item(&TransItem::Fn(instance))); + let lldecl = declare::define_internal_fn(ccx, &sym, self.ty); + base::trans_ctor_shim(ccx, def_id, substs, disr, lldecl); + ccx.instances().borrow_mut().insert(instance, lldecl); + + lldecl } _ => bug!("expected fn item type, found {}", self.ty) }, @@ -412,83 +402,20 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, assert!(!substs.types.needs_infer()); assert!(!substs.types.has_escaping_regions()); + assert!(!substs.types.has_param_types()); - // Check whether this fn has an inlined copy and, if so, redirect - // def_id to the local id of the inlined copy. - let def_id = inline::maybe_instantiate_inline(ccx, def_id); - - fn is_named_tuple_constructor(tcx: TyCtxt, def_id: DefId) -> bool { - let node_id = match tcx.map.as_local_node_id(def_id) { - Some(n) => n, - None => { return false; } - }; - let map_node = errors::expect( - &tcx.sess.diagnostic(), - tcx.map.find(node_id), - || "local item should be in ast map".to_string()); - - match map_node { - hir_map::NodeVariant(v) => { - v.node.data.is_tuple() - } - hir_map::NodeStructCtor(_) => true, - _ => false - } - } - let must_monomorphise = - !substs.types.is_empty() || is_named_tuple_constructor(tcx, def_id); - - debug!("get_fn({:?}) must_monomorphise: {}", - def_id, must_monomorphise); - - // Create a monomorphic version of generic functions - if must_monomorphise { - // Should be either intra-crate or inlined. - assert_eq!(def_id.krate, LOCAL_CRATE); - - let substs = tcx.normalize_associated_type(&substs); - let (val, fn_ty) = monomorphize::monomorphic_fn(ccx, def_id, substs); - let fn_ptr_ty = match fn_ty.sty { - ty::TyFnDef(_, _, fty) => { - // Create a fn pointer with the substituted signature. - tcx.mk_fn_ptr(fty) - } - _ => bug!("expected fn item type, found {}", fn_ty) - }; - assert_eq!(type_of::type_of(ccx, fn_ptr_ty), common::val_ty(val)); - return (val, fn_ptr_ty); - } - - // Find the actual function pointer. - let ty = ccx.tcx().lookup_item_type(def_id).ty; - let fn_ptr_ty = match ty.sty { - ty::TyFnDef(_, _, ref fty) => { - // Create a fn pointer with the normalized signature. - tcx.mk_fn_ptr(tcx.normalize_associated_type(fty)) - } - _ => bug!("expected fn item type, found {}", ty) - }; + let substs = tcx.normalize_associated_type(&substs); + let instance = Instance::new(def_id, substs); + let item_ty = ccx.tcx().lookup_item_type(def_id).ty; + let fn_ty = monomorphize::apply_param_substs(ccx.tcx(), substs, &item_ty); - let instance = Instance::mono(ccx.shared(), def_id); if let Some(&llfn) = ccx.instances().borrow().get(&instance) { - return (llfn, fn_ptr_ty); + return (llfn, fn_ty); } - let local_id = ccx.tcx().map.as_local_node_id(def_id); - let local_item = match local_id.and_then(|id| tcx.map.find(id)) { - Some(hir_map::NodeItem(&hir::Item { - span, node: hir::ItemFn(..), .. - })) | - Some(hir_map::NodeTraitItem(&hir::TraitItem { - span, node: hir::MethodTraitItem(_, Some(_)), .. - })) | - Some(hir_map::NodeImplItem(&hir::ImplItem { - span, node: hir::ImplItemKind::Method(..), .. - })) => { - Some(span) - } - _ => None - }; + let sym = ccx.symbol_map().get_or_compute(ccx.shared(), + TransItem::Fn(instance)); + debug!("get_fn({:?}: {:?}) => {}", instance, fn_ty, sym); // This is subtle and surprising, but sometimes we have to bitcast // the resulting fn pointer. The reason has to do with external @@ -514,23 +441,17 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // reference. It also occurs when testing libcore and in some // other weird situations. Annoying. - let sym = ccx.symbol_map().get_or_compute(ccx.shared(), - TransItem::Fn(instance)); - - let llptrty = type_of::type_of(ccx, fn_ptr_ty); - let llfn = if let Some(llfn) = declare::get_declared_value(ccx, &sym) { - if let Some(span) = local_item { - if declare::get_defined_value(ccx, &sym).is_some() { - ccx.sess().span_fatal(span, - &format!("symbol `{}` is already defined", &sym)); - } + let fn_ptr_ty = match fn_ty.sty { + ty::TyFnDef(_, _, fty) => { + // Create a fn pointer with the substituted signature. + tcx.mk_fn_ptr(fty) } + _ => bug!("expected fn item type, found {}", fn_ty) + }; + let llptrty = type_of::type_of(ccx, fn_ptr_ty); + let llfn = if let Some(llfn) = declare::get_declared_value(ccx, &sym) { if common::val_ty(llfn) != llptrty { - if local_item.is_some() { - bug!("symbol `{}` previously declared as {:?}, now wanted as {:?}", - sym, Value(llfn), llptrty); - } debug!("get_fn: casting {:?} to {:?}", llfn, llptrty); consts::ptrcast(llfn, llptrty) } else { @@ -538,15 +459,21 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, llfn } } else { - let llfn = declare::declare_fn(ccx, &sym, ty); + let llfn = declare::declare_fn(ccx, &sym, fn_ty); assert_eq!(common::val_ty(llfn), llptrty); debug!("get_fn: not casting pointer!"); let attrs = ccx.tcx().get_attrs(def_id); attributes::from_fn_attrs(ccx, &attrs, llfn); - if local_item.is_some() { + + let is_local_def = ccx.shared().translation_items().borrow() + .contains(&TransItem::Fn(instance)); + if is_local_def { // FIXME(eddyb) Doubt all extern fn should allow unwinding. attributes::unwind(llfn, true); + unsafe { + llvm::LLVMSetLinkage(llfn, llvm::ExternalLinkage); + } } llfn @@ -554,7 +481,7 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ccx.instances().borrow_mut().insert(instance, llfn); - (llfn, fn_ptr_ty) + (llfn, fn_ty) } // ______________________________________________________________________ diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index 3a456b1dd7968..c5053e4feee62 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -199,12 +199,6 @@ pub fn gensym_name(name: &str) -> ast::Name { use Disr; -#[derive(Copy, Clone)] -pub struct NodeIdAndSpan { - pub id: ast::NodeId, - pub span: Span, -} - /// The concrete version of ty::FieldDef. The name is the field index if /// the field is numeric. pub struct Field<'tcx>(pub ast::Name, pub Ty<'tcx>); @@ -1066,34 +1060,6 @@ pub fn langcall(tcx: TyCtxt, } } -/// Return the VariantDef corresponding to an inlined variant node -pub fn inlined_variant_def<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, - inlined_vid: ast::NodeId) - -> ty::VariantDef<'tcx> -{ - let ctor_ty = ccx.tcx().node_id_to_type(inlined_vid); - debug!("inlined_variant_def: ctor_ty={:?} inlined_vid={:?}", ctor_ty, - inlined_vid); - let adt_def = match ctor_ty.sty { - ty::TyFnDef(_, _, &ty::BareFnTy { sig: ty::Binder(ty::FnSig { - output, .. - }), ..}) => output, - _ => ctor_ty - }.ty_adt_def().unwrap(); - let variant_def_id = if ccx.tcx().map.is_inlined_node_id(inlined_vid) { - ccx.defid_for_inlined_node(inlined_vid).unwrap() - } else { - ccx.tcx().map.local_def_id(inlined_vid) - }; - - adt_def.variants - .iter() - .find(|v| variant_def_id == v.did) - .unwrap_or_else(|| { - bug!("no variant for {:?}::{}", adt_def, inlined_vid) - }) -} - // To avoid UB from LLVM, these two functions mask RHS with an // appropriate mask unconditionally (i.e. the fallback behavior for // all shifts). For 32- and 64-bit types, this matches the semantics diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs index c1d855649123a..fa1e008d496e4 100644 --- a/src/librustc_trans/consts.rs +++ b/src/librustc_trans/consts.rs @@ -105,14 +105,10 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef { let defined_in_current_codegen_unit = ccx.codegen_unit() .items() .contains_key(&TransItem::Static(id)); - if defined_in_current_codegen_unit { - if declare::get_declared_value(ccx, sym).is_none() { - span_bug!(span, "trans: Static not properly pre-defined?"); - } - } else { - if declare::get_declared_value(ccx, sym).is_some() { - span_bug!(span, "trans: Conflicting symbol names for static?"); - } + assert!(!defined_in_current_codegen_unit); + + if declare::get_declared_value(ccx, sym).is_some() { + span_bug!(span, "trans: Conflicting symbol names for static?"); } let g = declare::define_global(ccx, sym, llty).unwrap(); diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 8a836c692e1a8..0a295b251b31e 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -53,9 +53,7 @@ pub struct Stats { pub n_glues_created: Cell, pub n_null_glues: Cell, pub n_real_glues: Cell, - pub n_fallback_instantiations: Cell, pub n_fns: Cell, - pub n_monos: Cell, pub n_inlines: Cell, pub n_closures: Cell, pub n_llvm_insns: Cell, @@ -103,7 +101,6 @@ pub struct LocalCrateContext<'tcx> { drop_glues: RefCell, (ValueRef, FnType)>>, /// Cache instances of monomorphic and polymorphic items instances: RefCell, ValueRef>>, - monomorphizing: RefCell>, /// Cache generated vtables vtables: RefCell, ValueRef>>, /// Cache of constant strings, @@ -488,9 +485,7 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { n_glues_created: Cell::new(0), n_null_glues: Cell::new(0), n_real_glues: Cell::new(0), - n_fallback_instantiations: Cell::new(0), n_fns: Cell::new(0), - n_monos: Cell::new(0), n_inlines: Cell::new(0), n_closures: Cell::new(0), n_llvm_insns: Cell::new(0), @@ -626,7 +621,6 @@ impl<'tcx> LocalCrateContext<'tcx> { fn_pointer_shims: RefCell::new(FnvHashMap()), drop_glues: RefCell::new(FnvHashMap()), instances: RefCell::new(FnvHashMap()), - monomorphizing: RefCell::new(DefIdMap()), vtables: RefCell::new(FnvHashMap()), const_cstr_cache: RefCell::new(FnvHashMap()), const_unsized: RefCell::new(FnvHashMap()), @@ -830,10 +824,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { &self.local().instances } - pub fn monomorphizing<'a>(&'a self) -> &'a RefCell> { - &self.local().monomorphizing - } - pub fn vtables<'a>(&'a self) -> &'a RefCell, ValueRef>> { &self.local().vtables } diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index bd984a71badea..ba91b44343868 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -28,7 +28,7 @@ use rustc::hir::def_id::DefId; use rustc::ty::subst::Substs; use rustc::hir; use {type_of, adt, machine, monomorphize}; -use common::{CrateContext, FunctionContext}; +use common::CrateContext; use type_::Type; use rustc::ty::{self, Ty}; use session::config; @@ -882,26 +882,6 @@ fn file_metadata_(cx: &CrateContext, key: &str, file_name: &str, work_dir: &str) file_metadata } -/// Finds the scope metadata node for the given AST node. -pub fn scope_metadata(fcx: &FunctionContext, - node_id: ast::NodeId, - error_reporting_span: Span) - -> DIScope { - let scope_map = &fcx.debug_context - .get_ref(error_reporting_span) - .scope_map; - match scope_map.borrow().get(&node_id).cloned() { - Some(scope_metadata) => scope_metadata, - None => { - let node = fcx.ccx.tcx().map.get(node_id); - - span_bug!(error_reporting_span, - "debuginfo: Could not find scope info for node {:?}", - node); - } - } -} - fn basic_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> DIType { diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index a864f974c96fc..cbf423b0739a3 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -27,15 +27,14 @@ use llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilderRef, DISubprogram, DIArr use rustc::hir::def_id::DefId; use rustc::hir::map::DefPathData; use rustc::ty::subst::Substs; -use rustc::hir; use abi::Abi; -use common::{NodeIdAndSpan, CrateContext, FunctionContext, Block, BlockAndBuilder}; -use inline; +use common::{CrateContext, FunctionContext, Block, BlockAndBuilder}; use monomorphize::{self, Instance}; use rustc::ty::{self, Ty}; +use rustc::mir::repr as mir; use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo}; -use util::nodemap::{DefIdMap, NodeMap, FnvHashMap, FnvHashSet}; +use util::nodemap::{DefIdMap, FnvHashMap, FnvHashSet}; use libc::c_uint; use std::cell::{Cell, RefCell}; @@ -134,7 +133,6 @@ impl FunctionDebugContext { } pub struct FunctionDebugContextData { - scope_map: RefCell>, fn_metadata: DISubprogram, source_locations_enabled: Cell, source_location_override: Cell, @@ -222,7 +220,8 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, instance: Instance<'tcx>, sig: &ty::FnSig<'tcx>, abi: Abi, - llfn: ValueRef) -> FunctionDebugContext { + llfn: ValueRef, + mir: &mir::Mir) -> FunctionDebugContext { if cx.sess().opts.debuginfo == NoDebugInfo { return FunctionDebugContext::DebugInfoDisabled; } @@ -231,8 +230,8 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, // Do this here already, in case we do an early exit from this function. source_loc::set_debug_location(cx, None, UnknownLocation); - let instance = inline::maybe_inline_instance(cx, instance); - let (containing_scope, span) = get_containing_scope_and_span(cx, instance); + let containing_scope = get_containing_scope(cx, instance); + let span = mir.span; // This can be the case for functions inlined from another crate if span == syntax_pos::DUMMY_SP { @@ -298,7 +297,6 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, // Initialize fn debug context (including scope map and namespace map) let fn_debug_context = box FunctionDebugContextData { - scope_map: RefCell::new(NodeMap()), fn_metadata: fn_metadata, source_locations_enabled: Cell::new(false), source_location_override: Cell::new(false), @@ -406,9 +404,9 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, names } - fn get_containing_scope_and_span<'ccx, 'tcx>(cx: &CrateContext<'ccx, 'tcx>, - instance: Instance<'tcx>) - -> (DIScope, Span) { + fn get_containing_scope<'ccx, 'tcx>(cx: &CrateContext<'ccx, 'tcx>, + instance: Instance<'tcx>) + -> DIScope { // First, let's see if this is a method within an inherent impl. Because // if yes, we want to make the result subroutine DIE a child of the // subroutine's self-type. @@ -428,22 +426,15 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } }); - let containing_scope = self_type.unwrap_or_else(|| { + self_type.unwrap_or_else(|| { namespace::item_namespace(cx, DefId { krate: instance.def.krate, index: cx.tcx() .def_key(instance.def) .parent - .expect("get_containing_scope_and_span: missing parent?") + .expect("get_containing_scope: missing parent?") }) - }); - - // Try to get some span information, if we have an inlined item. - let definition_span = cx.tcx() - .map - .def_id_span(instance.def, syntax_pos::DUMMY_SP); - - (containing_scope, definition_span) + }) } } @@ -521,7 +512,6 @@ pub fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum DebugLoc { - At(ast::NodeId, Span), ScopeAt(DIScope, Span), None } @@ -535,28 +525,3 @@ impl DebugLoc { source_loc::set_source_location(bcx.fcx(), Some(bcx), self); } } - -pub trait ToDebugLoc { - fn debug_loc(&self) -> DebugLoc; -} - -impl ToDebugLoc for hir::Expr { - fn debug_loc(&self) -> DebugLoc { - DebugLoc::At(self.id, self.span) - } -} - -impl ToDebugLoc for NodeIdAndSpan { - fn debug_loc(&self) -> DebugLoc { - DebugLoc::At(self.id, self.span) - } -} - -impl ToDebugLoc for Option { - fn debug_loc(&self) -> DebugLoc { - match *self { - Some(NodeIdAndSpan { id, span }) => DebugLoc::At(id, span), - None => DebugLoc::None - } - } -} diff --git a/src/librustc_trans/debuginfo/source_loc.rs b/src/librustc_trans/debuginfo/source_loc.rs index 32b414d279628..1aee27c144a36 100644 --- a/src/librustc_trans/debuginfo/source_loc.rs +++ b/src/librustc_trans/debuginfo/source_loc.rs @@ -11,7 +11,7 @@ use self::InternalDebugLocation::*; use super::utils::{debug_context, span_start}; -use super::metadata::{scope_metadata,UNKNOWN_COLUMN_NUMBER}; +use super::metadata::{UNKNOWN_COLUMN_NUMBER}; use super::{FunctionDebugContext, DebugLoc}; use llvm; @@ -47,9 +47,6 @@ pub fn set_source_location(fcx: &FunctionContext, let dbg_loc = if function_debug_context.source_locations_enabled.get() { let (scope, span) = match debug_loc { - DebugLoc::At(node_id, span) => { - (scope_metadata(fcx, node_id, span), span) - } DebugLoc::ScopeAt(scope, span) => (scope, span), DebugLoc::None => { set_debug_location(fcx.ccx, builder, UnknownLocation); diff --git a/src/librustc_trans/glue.rs b/src/librustc_trans/glue.rs index ed61f1f589a03..6a072c84dd9b3 100644 --- a/src/librustc_trans/glue.rs +++ b/src/librustc_trans/glue.rs @@ -221,10 +221,6 @@ fn get_drop_glue_core<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, g, TransItem::DropGlue(g).to_raw_string(), ccx.codegen_unit().name()); - - ccx.stats().n_fallback_instantiations.set(ccx.stats() - .n_fallback_instantiations - .get() + 1); } } diff --git a/src/librustc_trans/inline.rs b/src/librustc_trans/inline.rs deleted file mode 100644 index 8581fccf10ab5..0000000000000 --- a/src/librustc_trans/inline.rs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use rustc::hir::def_id::DefId; -use base::push_ctxt; -use common::*; -use monomorphize::Instance; - -use rustc::dep_graph::DepNode; - -fn instantiate_inline(ccx: &CrateContext, fn_id: DefId) -> Option { - debug!("instantiate_inline({:?})", fn_id); - let _icx = push_ctxt("instantiate_inline"); - let tcx = ccx.tcx(); - let _task = tcx.dep_graph.in_task(DepNode::TransInlinedItem(fn_id)); - - tcx.sess - .cstore - .maybe_get_item_ast(tcx, fn_id) - .map(|(_, inline_id)| { - tcx.map.local_def_id(inline_id) - }) -} - -pub fn get_local_instance(ccx: &CrateContext, fn_id: DefId) - -> Option { - if let Some(_) = ccx.tcx().map.as_local_node_id(fn_id) { - Some(fn_id) - } else { - instantiate_inline(ccx, fn_id) - } -} - -pub fn maybe_instantiate_inline(ccx: &CrateContext, fn_id: DefId) -> DefId { - get_local_instance(ccx, fn_id).unwrap_or(fn_id) -} - -pub fn maybe_inline_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, - instance: Instance<'tcx>) -> Instance<'tcx> { - let def_id = maybe_instantiate_inline(ccx, instance.def); - Instance { - def: def_id, - substs: instance.substs - } -} diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index afe258f68e49f..7faff98aea442 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -111,7 +111,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, let name = tcx.item_name(def_id).as_str(); let span = match call_debug_location { - DebugLoc::At(_, span) | DebugLoc::ScopeAt(_, span) => span, + DebugLoc::ScopeAt(_, span) => span, DebugLoc::None => { span_bug!(fcx.span.unwrap_or(DUMMY_SP), "intrinsic `{}` called with missing span", name); diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index d989acc27effd..1286df7b97e67 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -114,7 +114,6 @@ mod debuginfo; mod declare; mod disr; mod glue; -mod inline; mod intrinsic; mod machine; mod meth; diff --git a/src/librustc_trans/monomorphize.rs b/src/librustc_trans/monomorphize.rs index d1837883aaeb0..020ac8d643b86 100644 --- a/src/librustc_trans/monomorphize.rs +++ b/src/librustc_trans/monomorphize.rs @@ -8,162 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use llvm::ValueRef; -use llvm; use rustc::hir::def_id::DefId; use rustc::infer::TransNormalize; use rustc::ty::subst::{Subst, Substs}; -use rustc::ty::{self, Ty, TypeFoldable, TyCtxt}; -use attributes; -use base::{push_ctxt}; -use base; +use rustc::ty::{self, Ty, TyCtxt}; use common::*; -use declare; -use Disr; -use rustc::hir::map as hir_map; use rustc::util::ppaux; -use rustc::hir; - -use errors; - use std::fmt; -use trans_item::TransItem; - -pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, - fn_id: DefId, - psubsts: &'tcx Substs<'tcx>) - -> (ValueRef, Ty<'tcx>) { - debug!("monomorphic_fn(fn_id={:?}, real_substs={:?})", fn_id, psubsts); - assert!(!psubsts.types.needs_infer() && !psubsts.types.has_param_types()); - - let _icx = push_ctxt("monomorphic_fn"); - - let instance = Instance::new(fn_id, psubsts); - - let item_ty = ccx.tcx().lookup_item_type(fn_id).ty; - - debug!("monomorphic_fn about to subst into {:?}", item_ty); - let mono_ty = apply_param_substs(ccx.tcx(), psubsts, &item_ty); - debug!("mono_ty = {:?} (post-substitution)", mono_ty); - - if let Some(&val) = ccx.instances().borrow().get(&instance) { - debug!("leaving monomorphic fn {:?}", instance); - return (val, mono_ty); - } else { - assert!(!ccx.codegen_unit().contains_item(&TransItem::Fn(instance))); - } - - debug!("monomorphic_fn({:?})", instance); - - ccx.stats().n_monos.set(ccx.stats().n_monos.get() + 1); - - let depth; - { - let mut monomorphizing = ccx.monomorphizing().borrow_mut(); - depth = match monomorphizing.get(&fn_id) { - Some(&d) => d, None => 0 - }; - - debug!("monomorphic_fn: depth for fn_id={:?} is {:?}", fn_id, depth+1); - - // Random cut-off -- code that needs to instantiate the same function - // recursively more than thirty times can probably safely be assumed - // to be causing an infinite expansion. - if depth > ccx.sess().recursion_limit.get() { - let error = format!("reached the recursion limit while instantiating `{}`", - instance); - if let Some(id) = ccx.tcx().map.as_local_node_id(fn_id) { - ccx.sess().span_fatal(ccx.tcx().map.span(id), &error); - } else { - ccx.sess().fatal(&error); - } - } - - monomorphizing.insert(fn_id, depth + 1); - } - - let symbol = ccx.symbol_map().get_or_compute(ccx.shared(), - TransItem::Fn(instance)); - - debug!("monomorphize_fn mangled to {}", &symbol); - assert!(declare::get_defined_value(ccx, &symbol).is_none()); - - // FIXME(nagisa): perhaps needs a more fine grained selection? - let lldecl = declare::define_internal_fn(ccx, &symbol, mono_ty); - // FIXME(eddyb) Doubt all extern fn should allow unwinding. - attributes::unwind(lldecl, true); - - ccx.instances().borrow_mut().insert(instance, lldecl); - - // we can only monomorphize things in this crate (or inlined into it) - let fn_node_id = ccx.tcx().map.as_local_node_id(fn_id).unwrap(); - let map_node = errors::expect( - ccx.sess().diagnostic(), - ccx.tcx().map.find(fn_node_id), - || { - format!("while instantiating `{}`, couldn't find it in \ - the item map (may have attempted to monomorphize \ - an item defined in a different crate?)", - instance) - }); - match map_node { - hir_map::NodeItem(&hir::Item { - ref attrs, - node: hir::ItemFn(..), .. - }) | - hir_map::NodeImplItem(&hir::ImplItem { - ref attrs, node: hir::ImplItemKind::Method( - hir::MethodSig { .. }, _), .. - }) | - hir_map::NodeTraitItem(&hir::TraitItem { - ref attrs, node: hir::MethodTraitItem( - hir::MethodSig { .. }, Some(_)), .. - }) => { - let trans_item = TransItem::Fn(instance); - - if ccx.shared().translation_items().borrow().contains(&trans_item) { - attributes::from_fn_attrs(ccx, attrs, lldecl); - unsafe { - llvm::LLVMSetLinkage(lldecl, llvm::ExternalLinkage); - } - } else { - // FIXME: #34151 - // Normally, getting here would indicate a bug in trans::collector, - // since it seems to have missed a translation item. When we are - // translating with non-MIR based trans, however, the results of - // the collector are not entirely reliable since it bases its - // analysis on MIR. Thus, we'll instantiate the missing function - // privately in this codegen unit, so that things keep working. - ccx.stats().n_fallback_instantiations.set(ccx.stats() - .n_fallback_instantiations - .get() + 1); - trans_item.predefine(ccx, llvm::InternalLinkage); - trans_item.define(ccx); - } - } - - hir_map::NodeVariant(_) | hir_map::NodeStructCtor(_) => { - let disr = match map_node { - hir_map::NodeVariant(_) => { - Disr::from(inlined_variant_def(ccx, fn_node_id).disr_val) - } - hir_map::NodeStructCtor(_) => Disr(0), - _ => bug!() - }; - attributes::inline(lldecl, attributes::InlineAttr::Hint); - attributes::set_frame_pointer_elimination(ccx, lldecl); - base::trans_ctor_shim(ccx, fn_node_id, disr, psubsts, lldecl); - } - - _ => bug!("can't monomorphize a {:?}", map_node) - }; - - ccx.monomorphizing().borrow_mut().insert(fn_id, depth); - - debug!("leaving monomorphic fn {}", ccx.tcx().item_path_str(fn_id)); - (lldecl, mono_ty) -} #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct Instance<'tcx> { diff --git a/src/librustc_trans/trans_item.rs b/src/librustc_trans/trans_item.rs index 66ea5264dd28e..90dcc3a61fd7e 100644 --- a/src/librustc_trans/trans_item.rs +++ b/src/librustc_trans/trans_item.rs @@ -22,17 +22,15 @@ use declare; use glue::DropGlueKind; use llvm; use monomorphize::{self, Instance}; -use inline; use rustc::dep_graph::DepNode; use rustc::hir; -use rustc::hir::map as hir_map; use rustc::hir::def_id::DefId; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc::ty::subst::Substs; use rustc_const_eval::fatal_const_eval_err; use std::hash::{Hash, Hasher}; use syntax::ast::{self, NodeId}; -use syntax::{attr,errors}; +use syntax::attr; use type_of; use glue; use abi::{Abi, FnType}; @@ -157,20 +155,16 @@ impl<'a, 'tcx> TransItem<'tcx> { let ty = ccx.tcx().lookup_item_type(def_id).ty; let llty = type_of::type_of(ccx, ty); - match ccx.tcx().map.get(node_id) { - hir::map::NodeItem(&hir::Item { - span, node: hir::ItemStatic(..), .. - }) => { - let g = declare::define_global(ccx, symbol_name, llty).unwrap_or_else(|| { - ccx.sess().span_fatal(span, - &format!("symbol `{}` is already defined", symbol_name)) - }); + let g = declare::define_global(ccx, symbol_name, llty).unwrap_or_else(|| { + ccx.sess().span_fatal(ccx.tcx().map.span(node_id), + &format!("symbol `{}` is already defined", symbol_name)) + }); - unsafe { llvm::LLVMSetLinkage(g, linkage) }; - } + unsafe { llvm::LLVMSetLinkage(g, linkage) }; - item => bug!("predefine_static: expected static, found {:?}", item) - } + let instance = Instance::mono(ccx.shared(), def_id); + ccx.instances().borrow_mut().insert(instance, g); + ccx.statics().borrow_mut().insert(g, def_id); } fn predefine_fn(ccx: &CrateContext<'a, 'tcx>, @@ -180,47 +174,22 @@ impl<'a, 'tcx> TransItem<'tcx> { assert!(!instance.substs.types.needs_infer() && !instance.substs.types.has_param_types()); - let instance = inline::maybe_inline_instance(ccx, instance); - let item_ty = ccx.tcx().lookup_item_type(instance.def).ty; let item_ty = ccx.tcx().erase_regions(&item_ty); let mono_ty = monomorphize::apply_param_substs(ccx.tcx(), instance.substs, &item_ty); - let fn_node_id = ccx.tcx().map.as_local_node_id(instance.def).unwrap(); - let map_node = errors::expect( - ccx.sess().diagnostic(), - ccx.tcx().map.find(fn_node_id), - || { - format!("while instantiating `{}`, couldn't find it in \ - the item map (may have attempted to monomorphize \ - an item defined in a different crate?)", - instance) - }); - - match map_node { - hir_map::NodeItem(&hir::Item { - ref attrs, node: hir::ItemFn(..), .. - }) | - hir_map::NodeTraitItem(&hir::TraitItem { - ref attrs, node: hir::MethodTraitItem(..), .. - }) | - hir_map::NodeImplItem(&hir::ImplItem { - ref attrs, node: hir::ImplItemKind::Method(..), .. - }) => { - let lldecl = declare::declare_fn(ccx, symbol_name, mono_ty); - unsafe { llvm::LLVMSetLinkage(lldecl, linkage) }; - base::set_link_section(ccx, lldecl, attrs); - if linkage == llvm::LinkOnceODRLinkage || - linkage == llvm::WeakODRLinkage { - llvm::SetUniqueComdat(ccx.llmod(), lldecl); - } + let attrs = ccx.tcx().get_attrs(instance.def); + let lldecl = declare::declare_fn(ccx, symbol_name, mono_ty); + unsafe { llvm::LLVMSetLinkage(lldecl, linkage) }; + base::set_link_section(ccx, lldecl, &attrs); + if linkage == llvm::LinkOnceODRLinkage || + linkage == llvm::WeakODRLinkage { + llvm::SetUniqueComdat(ccx.llmod(), lldecl); + } - attributes::from_fn_attrs(ccx, attrs, lldecl); - ccx.instances().borrow_mut().insert(instance, lldecl); - } - _ => bug!("Invalid item for TransItem::Fn: `{:?}`", map_node) - }; + attributes::from_fn_attrs(ccx, &attrs, lldecl); + ccx.instances().borrow_mut().insert(instance, lldecl); } fn predefine_drop_glue(ccx: &CrateContext<'a, 'tcx>,