From 33d5da1ee400e4b1b85a6a3f0c552ce68c665500 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 23 Feb 2018 16:25:03 +0100 Subject: [PATCH] Clean up handling of symbol export information. --- src/librustc/middle/cstore.rs | 7 +- src/librustc/ty/context.rs | 6 +- src/librustc_metadata/cstore_impl.rs | 7 +- src/librustc_metadata/encoder.rs | 19 +- src/librustc_trans/back/symbol_export.rs | 331 ++++++++++++++--------- src/librustc_trans/base.rs | 12 +- src/librustc_trans_utils/lib.rs | 55 +--- src/librustc_trans_utils/trans_crate.rs | 3 +- 8 files changed, 231 insertions(+), 209 deletions(-) diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index bdb5ad525a75c..5dbe2ef516cf7 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -32,7 +32,6 @@ use ich; use ty::{self, TyCtxt}; use session::{Session, CrateDisambiguator}; use session::search_paths::PathKind; -use util::nodemap::NodeSet; use std::any::Any; use std::collections::BTreeMap; @@ -258,8 +257,7 @@ pub trait CrateStore { // utility functions fn encode_metadata<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - link_meta: &LinkMeta, - reachable: &NodeSet) + link_meta: &LinkMeta) -> EncodedMetadata; fn metadata_encoding_version(&self) -> &[u8]; } @@ -342,8 +340,7 @@ impl CrateStore for DummyCrateStore { fn extern_mod_stmt_cnum_untracked(&self, emod_id: ast::NodeId) -> Option { None } fn encode_metadata<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - link_meta: &LinkMeta, - reachable: &NodeSet) + link_meta: &LinkMeta) -> EncodedMetadata { bug!("encode_metadata") } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index a7f065d57aeed..aac6b3dc08a78 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -46,7 +46,7 @@ use ty::layout::{LayoutDetails, TargetDataLayout}; use ty::maps; use ty::steal::Steal; use ty::BindingMode; -use util::nodemap::{NodeMap, NodeSet, DefIdSet, ItemLocalMap}; +use util::nodemap::{NodeMap, DefIdSet, ItemLocalMap}; use util::nodemap::{FxHashMap, FxHashSet}; use rustc_data_structures::accumulate_vec::AccumulateVec; use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap, @@ -1417,10 +1417,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { - pub fn encode_metadata(self, link_meta: &LinkMeta, reachable: &NodeSet) + pub fn encode_metadata(self, link_meta: &LinkMeta) -> EncodedMetadata { - self.cstore.encode_metadata(self, link_meta, reachable) + self.cstore.encode_metadata(self, link_meta) } } diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 20fc45696a95b..00862816d57b4 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -27,7 +27,7 @@ use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE, CRATE_DEF_INDEX}; use rustc::hir::map::{DefKey, DefPath, DefPathHash}; use rustc::hir::map::blocks::FnLikeNode; use rustc::hir::map::definitions::DefPathTable; -use rustc::util::nodemap::{NodeSet, DefIdMap}; +use rustc::util::nodemap::DefIdMap; use std::any::Any; use rustc_data_structures::sync::Lrc; @@ -517,11 +517,10 @@ impl CrateStore for cstore::CStore { fn encode_metadata<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - link_meta: &LinkMeta, - reachable: &NodeSet) + link_meta: &LinkMeta) -> EncodedMetadata { - encoder::encode_metadata(tcx, link_meta, reachable) + encoder::encode_metadata(tcx, link_meta) } fn metadata_encoding_version(&self) -> &[u8] diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 7198f7ccf35e5..c649cf62dc5d3 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -27,7 +27,7 @@ use rustc::ty::{self, Ty, TyCtxt, ReprOptions}; use rustc::ty::codec::{self as ty_codec, TyEncoder}; use rustc::session::config::{self, CrateTypeProcMacro}; -use rustc::util::nodemap::{FxHashMap, NodeSet}; +use rustc::util::nodemap::{FxHashMap, DefIdSet}; use rustc_data_structures::stable_hasher::StableHasher; use rustc_serialize::{Encodable, Encoder, SpecializedEncoder, opaque}; @@ -53,7 +53,6 @@ pub struct EncodeContext<'a, 'tcx: 'a> { opaque: opaque::Encoder<'a>, pub tcx: TyCtxt<'a, 'tcx, 'tcx>, link_meta: &'a LinkMeta, - reachable_non_generics: &'a NodeSet, lazy_state: LazyState, type_shorthands: FxHashMap, usize>, @@ -395,9 +394,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // Encode exported symbols info. i = self.position(); + let reachable_non_generics = self.tcx.reachable_non_generics(LOCAL_CRATE); let reachable_non_generics = self.tracked( IsolatedEncoder::encode_reachable_non_generics, - self.reachable_non_generics); + &reachable_non_generics); let reachable_non_generics_bytes = self.position() - i; // Encode and index the items. @@ -1389,11 +1389,12 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { // symbol associated with them (they weren't translated) or if they're an FFI // definition (as that's not defined in this crate). fn encode_reachable_non_generics(&mut self, - reachable_non_generics: &NodeSet) + reachable_non_generics: &DefIdSet) -> LazySeq { - let tcx = self.tcx; - self.lazy_seq(reachable_non_generics.iter() - .map(|&id| tcx.hir.local_def_id(id).index)) + self.lazy_seq(reachable_non_generics.iter().map(|def_id| { + debug_assert!(def_id.is_local()); + def_id.index + })) } fn encode_dylib_dependency_formats(&mut self, _: ()) -> LazySeq> { @@ -1666,8 +1667,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'a, 'tcx> { // generated regardless of trailing bytes that end up in it. pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - link_meta: &LinkMeta, - reachable_non_generics: &NodeSet) + link_meta: &LinkMeta) -> EncodedMetadata { let mut cursor = Cursor::new(vec![]); @@ -1681,7 +1681,6 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, opaque: opaque::Encoder::new(&mut cursor), tcx, link_meta, - reachable_non_generics, lazy_state: LazyState::NoNode, type_shorthands: Default::default(), predicate_shorthands: Default::default(), diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs index 57da02eaa5232..74f7a6e8d9cdd 100644 --- a/src/librustc_trans/back/symbol_export.rs +++ b/src/librustc_trans/back/symbol_export.rs @@ -11,15 +11,15 @@ use rustc_data_structures::sync::Lrc; use std::sync::Arc; -use base; use monomorphize::Instance; +use rustc::hir; use rustc::hir::def_id::CrateNum; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::middle::exported_symbols::SymbolExportLevel; use rustc::session::config; use rustc::ty::TyCtxt; use rustc::ty::maps::Providers; -use rustc::util::nodemap::FxHashMap; +use rustc::util::nodemap::{FxHashMap, DefIdSet}; use rustc_allocator::ALLOCATOR_METHODS; use syntax::attr; @@ -60,145 +60,228 @@ pub fn crates_export_threshold(crate_types: &[config::CrateType]) } } -pub fn provide(providers: &mut Providers) { - providers.reachable_non_generics = |tcx, cnum| { - let export_threshold = threshold(tcx); - Lrc::new(tcx.exported_symbols(cnum) - .iter() - .filter_map(|&(_, id, level)| { - id.and_then(|id| { - if level.is_below_threshold(export_threshold) { - Some(id) +fn reachable_non_generics_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + cnum: CrateNum) + -> Lrc +{ + assert_eq!(cnum, LOCAL_CRATE); + + if !tcx.sess.opts.output_types.should_trans() { + return Lrc::new(DefIdSet()) + } + + let export_threshold = threshold(tcx); + + // We already collect all potentially reachable non-generic items for + // `exported_symbols`. Now we just filter them down to what is actually + // exported for the given crate we are compiling. + let reachable_non_generics = tcx + .exported_symbols(LOCAL_CRATE) + .iter() + .filter_map(|&(_, opt_def_id, level)| { + if let Some(def_id) = opt_def_id { + if level.is_below_threshold(export_threshold) { + return Some(def_id) + } + } + + None + }) + .collect(); + + Lrc::new(reachable_non_generics) +} + +fn is_reachable_non_generic_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + def_id: DefId) + -> bool { + tcx.reachable_non_generics(def_id.krate).contains(&def_id) +} + +fn exported_symbols_provider_local<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + cnum: CrateNum) + -> Arc, + SymbolExportLevel)>> +{ + assert_eq!(cnum, LOCAL_CRATE); + + if !tcx.sess.opts.output_types.should_trans() { + return Arc::new(vec![]) + } + + let mut reachable_non_generics: DefIdSet = tcx.reachable_set(LOCAL_CRATE).0 + .iter() + .filter_map(|&node_id| { + // We want to ignore some FFI functions that are not exposed from + // this crate. Reachable FFI functions can be lumped into two + // categories: + // + // 1. Those that are included statically via a static library + // 2. Those included otherwise (e.g. dynamically or via a framework) + // + // Although our LLVM module is not literally emitting code for the + // statically included symbols, it's an export of our library which + // needs to be passed on to the linker and encoded in the metadata. + // + // As a result, if this id is an FFI item (foreign item) then we only + // let it through if it's included statically. + match tcx.hir.get(node_id) { + hir::map::NodeForeignItem(..) => { + let def_id = tcx.hir.local_def_id(node_id); + if tcx.is_statically_included_foreign_item(def_id) { + Some(def_id) } else { None } - }) - }) - .collect()) - }; - - providers.is_reachable_non_generic = |tcx, id| { - tcx.reachable_non_generics(id.krate).contains(&id) - }; - - providers.exported_symbols = |tcx, cnum| { - assert_eq!(cnum, LOCAL_CRATE); - let local_exported_symbols = base::find_exported_symbols(tcx); - - let mut local_crate: Vec<_> = local_exported_symbols - .iter() - .map(|&node_id| { - tcx.hir.local_def_id(node_id) - }) - .map(|def_id| { - let name = tcx.symbol_name(Instance::mono(tcx, def_id)); - let export_level = export_level(tcx, def_id); - debug!("EXPORTED SYMBOL (local): {} ({:?})", name, export_level); - (str::to_owned(&name), Some(def_id), export_level) - }) - .collect(); - - if let Some(_) = *tcx.sess.entry_fn.borrow() { - local_crate.push(("main".to_string(), - None, - SymbolExportLevel::C)); - } + } - if tcx.sess.allocator_kind.get().is_some() { - for method in ALLOCATOR_METHODS { - local_crate.push((format!("__rust_{}", method.name), - None, - SymbolExportLevel::Rust)); + // Only consider nodes that actually have exported symbols. + hir::map::NodeItem(&hir::Item { + node: hir::ItemStatic(..), + .. + }) | + hir::map::NodeItem(&hir::Item { + node: hir::ItemFn(..), .. + }) | + hir::map::NodeImplItem(&hir::ImplItem { + node: hir::ImplItemKind::Method(..), + .. + }) => { + let def_id = tcx.hir.local_def_id(node_id); + let generics = tcx.generics_of(def_id); + if (generics.parent_types == 0 && generics.types.is_empty()) && + // Functions marked with #[inline] are only ever translated + // with "internal" linkage and are never exported. + !Instance::mono(tcx, def_id).def.requires_local(tcx) { + Some(def_id) + } else { + None + } + } + + _ => None } - } + }) + .collect(); - if let Some(id) = tcx.sess.derive_registrar_fn.get() { - let def_id = tcx.hir.local_def_id(id); - let disambiguator = tcx.sess.local_crate_disambiguator(); - let registrar = tcx.sess.generate_derive_registrar_symbol(disambiguator); - local_crate.push((registrar, Some(def_id), SymbolExportLevel::C)); - } + if let Some(id) = tcx.sess.derive_registrar_fn.get() { + reachable_non_generics.insert(tcx.hir.local_def_id(id)); + } + + if let Some(id) = tcx.sess.plugin_registrar_fn.get() { + reachable_non_generics.insert(tcx.hir.local_def_id(id)); + } + + let mut symbols: Vec<_> = reachable_non_generics + .iter() + .map(|&def_id| { + let name = tcx.symbol_name(Instance::mono(tcx, def_id)); + let export_level = tcx.symbol_export_level(def_id); + debug!("EXPORTED SYMBOL (local): {} ({:?})", name, export_level); + (str::to_owned(&name), Some(def_id), export_level) + }) + .collect(); + + if let Some(_) = *tcx.sess.entry_fn.borrow() { + symbols.push(("main".to_string(), None, SymbolExportLevel::C)); + } - if tcx.sess.crate_types.borrow().contains(&config::CrateTypeDylib) { - local_crate.push((metadata_symbol_name(tcx), - None, - SymbolExportLevel::Rust)); + if tcx.sess.allocator_kind.get().is_some() { + for method in ALLOCATOR_METHODS { + symbols.push((format!("__rust_{}", method.name), + None, + SymbolExportLevel::Rust)); } + } - // Sort so we get a stable incr. comp. hash. - local_crate.sort_unstable_by(|&(ref name1, ..), &(ref name2, ..)| { - name1.cmp(name2) - }); + if tcx.sess.crate_types.borrow().contains(&config::CrateTypeDylib) { + symbols.push((metadata_symbol_name(tcx), + None, + SymbolExportLevel::Rust)); + } - Arc::new(local_crate) - }; + // Sort so we get a stable incr. comp. hash. + symbols.sort_unstable_by(|&(ref name1, ..), &(ref name2, ..)| { + name1.cmp(name2) + }); - providers.symbol_export_level = export_level; + Arc::new(symbols) } -pub fn provide_extern(providers: &mut Providers) { - providers.exported_symbols = |tcx, cnum| { - // If this crate is a plugin and/or a custom derive crate, then - // we're not even going to link those in so we skip those crates. - if tcx.plugin_registrar_fn(cnum).is_some() || - tcx.derive_registrar_fn(cnum).is_some() { - return Arc::new(Vec::new()) - } +pub fn provide(providers: &mut Providers) { + providers.reachable_non_generics = reachable_non_generics_provider; + providers.is_reachable_non_generic = is_reachable_non_generic_provider; + providers.exported_symbols = exported_symbols_provider_local; + providers.symbol_export_level = symbol_export_level_provider; +} - // Check to see if this crate is a "special runtime crate". These - // crates, implementation details of the standard library, typically - // have a bunch of `pub extern` and `#[no_mangle]` functions as the - // ABI between them. We don't want their symbols to have a `C` - // export level, however, as they're just implementation details. - // Down below we'll hardwire all of the symbols to the `Rust` export - // level instead. - let special_runtime_crate = - tcx.is_panic_runtime(cnum) || tcx.is_compiler_builtins(cnum); - - let mut crate_exports: Vec<_> = tcx - .reachable_non_generics(cnum) - .iter() - .map(|&def_id| { - let name = tcx.symbol_name(Instance::mono(tcx, def_id)); - let export_level = if special_runtime_crate { - // We can probably do better here by just ensuring that - // it has hidden visibility rather than public - // visibility, as this is primarily here to ensure it's - // not stripped during LTO. - // - // In general though we won't link right if these - // symbols are stripped, and LTO currently strips them. - if &*name == "rust_eh_personality" || - &*name == "rust_eh_register_frames" || - &*name == "rust_eh_unregister_frames" { - SymbolExportLevel::C - } else { - SymbolExportLevel::Rust - } +fn exported_symbols_provider_extern<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + cnum: CrateNum) + -> Arc, + SymbolExportLevel)>> +{ + // If this crate is a plugin and/or a custom derive crate, then + // we're not even going to link those in so we skip those crates. + if tcx.plugin_registrar_fn(cnum).is_some() || + tcx.derive_registrar_fn(cnum).is_some() { + return Arc::new(Vec::new()) + } + + // Check to see if this crate is a "special runtime crate". These + // crates, implementation details of the standard library, typically + // have a bunch of `pub extern` and `#[no_mangle]` functions as the + // ABI between them. We don't want their symbols to have a `C` + // export level, however, as they're just implementation details. + // Down below we'll hardwire all of the symbols to the `Rust` export + // level instead. + let special_runtime_crate = + tcx.is_panic_runtime(cnum) || tcx.is_compiler_builtins(cnum); + + let mut crate_exports: Vec<_> = tcx + .reachable_non_generics(cnum) + .iter() + .map(|&def_id| { + let name = tcx.symbol_name(Instance::mono(tcx, def_id)); + let export_level = if special_runtime_crate { + // We can probably do better here by just ensuring that + // it has hidden visibility rather than public + // visibility, as this is primarily here to ensure it's + // not stripped during LTO. + // + // In general though we won't link right if these + // symbols are stripped, and LTO currently strips them. + if &*name == "rust_eh_personality" || + &*name == "rust_eh_register_frames" || + &*name == "rust_eh_unregister_frames" { + SymbolExportLevel::C } else { - export_level(tcx, def_id) - }; - debug!("EXPORTED SYMBOL (re-export): {} ({:?})", name, export_level); - (str::to_owned(&name), Some(def_id), export_level) - }) - .collect(); - - // Sort so we get a stable incr. comp. hash. - crate_exports.sort_unstable_by(|&(ref name1, ..), &(ref name2, ..)| { - name1.cmp(name2) - }); - - Arc::new(crate_exports) - }; - - providers.is_reachable_non_generic = |tcx, id| { - tcx.reachable_non_generics(id.krate).contains(&id) - }; - - providers.symbol_export_level = export_level; + SymbolExportLevel::Rust + } + } else { + tcx.symbol_export_level(def_id) + }; + debug!("EXPORTED SYMBOL (re-export): {} ({:?})", name, export_level); + (str::to_owned(&name), Some(def_id), export_level) + }) + .collect(); + + // Sort so we get a stable incr. comp. hash. + crate_exports.sort_unstable_by(|&(ref name1, ..), &(ref name2, ..)| { + name1.cmp(name2) + }); + + Arc::new(crate_exports) +} + +pub fn provide_extern(providers: &mut Providers) { + providers.exported_symbols = exported_symbols_provider_extern; + providers.is_reachable_non_generic = is_reachable_non_generic_provider; + providers.symbol_export_level = symbol_export_level_provider; } -fn export_level(tcx: TyCtxt, sym_def_id: DefId) -> SymbolExportLevel { +fn symbol_export_level_provider(tcx: TyCtxt, sym_def_id: DefId) -> SymbolExportLevel { // We export anything that's not mangled at the "C" layer as it probably has // to do with ABI concerns. We do not, however, apply such treatment to // special symbols in the standard library for various plumbing between diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index c0785f5393716..b559cc9632571 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -70,7 +70,7 @@ use time_graph; use trans_item::{MonoItem, BaseMonoItemExt, MonoItemExt, DefPathBasedNames}; use type_::Type; use type_of::LayoutLlvmExt; -use rustc::util::nodemap::{NodeSet, FxHashMap, FxHashSet, DefIdSet}; +use rustc::util::nodemap::{FxHashMap, FxHashSet, DefIdSet}; use CrateInfo; use std::any::Any; @@ -89,7 +89,7 @@ use syntax::ast; use mir::operand::OperandValue; -pub use rustc_trans_utils::{find_exported_symbols, check_for_rustc_errors_attr}; +pub use rustc_trans_utils::check_for_rustc_errors_attr; pub use rustc_mir::monomorphize::item::linkage_by_name; pub struct StatRecorder<'a, 'tcx: 'a> { @@ -606,8 +606,7 @@ fn contains_null(s: &str) -> bool { fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, llmod_id: &str, - link_meta: &LinkMeta, - exported_symbols: &NodeSet) + link_meta: &LinkMeta) -> (ContextRef, ModuleRef, EncodedMetadata) { use std::io::Write; use flate2::Compression; @@ -643,7 +642,7 @@ fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, EncodedMetadata::new()); } - let metadata = tcx.encode_metadata(link_meta, exported_symbols); + let metadata = tcx.encode_metadata(link_meta); if kind == MetadataKind::Uncompressed { return (metadata_llcx, metadata_llmod, metadata); } @@ -718,13 +717,12 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let crate_hash = tcx.crate_hash(LOCAL_CRATE); let link_meta = link::build_link_meta(crate_hash); - let exported_symbol_node_ids = find_exported_symbols(tcx); // Translate the metadata. let llmod_id = "metadata"; let (metadata_llcx, metadata_llmod, metadata) = time(tcx.sess.time_passes(), "write metadata", || { - write_metadata(tcx, llmod_id, &link_meta, &exported_symbol_node_ids) + write_metadata(tcx, llmod_id, &link_meta) }); let metadata_module = ModuleTranslation { diff --git a/src/librustc_trans_utils/lib.rs b/src/librustc_trans_utils/lib.rs index bfecb20198366..d636a5f2e64b7 100644 --- a/src/librustc_trans_utils/lib.rs +++ b/src/librustc_trans_utils/lib.rs @@ -44,11 +44,7 @@ extern crate rustc_data_structures; pub extern crate rustc as __rustc; -use rustc::ty::{TyCtxt, Instance}; -use rustc::hir; -use rustc::hir::def_id::LOCAL_CRATE; -use rustc::hir::map as hir_map; -use rustc::util::nodemap::NodeSet; +use rustc::ty::TyCtxt; pub mod diagnostics; pub mod link; @@ -70,53 +66,4 @@ pub fn check_for_rustc_errors_attr(tcx: TyCtxt) { } } -/// The context provided lists a set of reachable ids as calculated by -/// middle::reachable, but this contains far more ids and symbols than we're -/// actually exposing from the object file. This function will filter the set in -/// the context to the set of ids which correspond to symbols that are exposed -/// from the object file being generated. -/// -/// This list is later used by linkers to determine the set of symbols needed to -/// be exposed from a dynamic library and it's also encoded into the metadata. -pub fn find_exported_symbols<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> NodeSet { - tcx.reachable_set(LOCAL_CRATE).0.iter().cloned().filter(|&id| { - // Next, we want to ignore some FFI functions that are not exposed from - // this crate. Reachable FFI functions can be lumped into two - // categories: - // - // 1. Those that are included statically via a static library - // 2. Those included otherwise (e.g. dynamically or via a framework) - // - // Although our LLVM module is not literally emitting code for the - // statically included symbols, it's an export of our library which - // needs to be passed on to the linker and encoded in the metadata. - // - // As a result, if this id is an FFI item (foreign item) then we only - // let it through if it's included statically. - match tcx.hir.get(id) { - hir_map::NodeForeignItem(..) => { - let def_id = tcx.hir.local_def_id(id); - tcx.is_statically_included_foreign_item(def_id) - } - - // Only consider nodes that actually have exported symbols. - hir_map::NodeItem(&hir::Item { - node: hir::ItemStatic(..), .. }) | - hir_map::NodeItem(&hir::Item { - node: hir::ItemFn(..), .. }) | - hir_map::NodeImplItem(&hir::ImplItem { - node: hir::ImplItemKind::Method(..), .. }) => { - let def_id = tcx.hir.local_def_id(id); - let generics = tcx.generics_of(def_id); - (generics.parent_types == 0 && generics.types.is_empty()) && - // Functions marked with #[inline] are only ever translated - // with "internal" linkage and are never exported. - !Instance::mono(tcx, def_id).def.requires_local(tcx) - } - - _ => false - } - }).collect() -} - __build_diagnostic_array! { librustc_trans_utils, DIAGNOSTICS } diff --git a/src/librustc_trans_utils/trans_crate.rs b/src/librustc_trans_utils/trans_crate.rs index 419371ba3e339..7b2cbe140aebf 100644 --- a/src/librustc_trans_utils/trans_crate.rs +++ b/src/librustc_trans_utils/trans_crate.rs @@ -247,8 +247,7 @@ impl TransCrate for MetadataOnlyTransCrate { tcx.sess.abort_if_errors(); let link_meta = build_link_meta(tcx.crate_hash(LOCAL_CRATE)); - let exported_symbols = ::find_exported_symbols(tcx); - let metadata = tcx.encode_metadata(&link_meta, &exported_symbols); + let metadata = tcx.encode_metadata(&link_meta); box OngoingCrateTranslation { metadata: metadata,