Allow for representing exported monomorphizations in crate metadata.
This commit is contained in:
parent
d3b5451991
commit
dad194a10d
8 changed files with 89 additions and 39 deletions
|
@ -9,8 +9,13 @@
|
|||
// except according to those terms.
|
||||
|
||||
use hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use ich::StableHashingContext;
|
||||
use rustc_data_structures::stable_hasher::{StableHasher, HashStable,
|
||||
StableHasherResult};
|
||||
use std::cmp;
|
||||
use std::mem;
|
||||
use ty;
|
||||
use ty::subst::Substs;
|
||||
|
||||
/// The SymbolExportLevel of a symbols specifies from which kinds of crates
|
||||
/// the symbol will be exported. `C` symbols will be exported from any
|
||||
|
@ -40,56 +45,89 @@ impl SymbolExportLevel {
|
|||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Debug, Copy, Clone, RustcEncodable, RustcDecodable)]
|
||||
pub enum ExportedSymbol {
|
||||
pub enum ExportedSymbol<'tcx> {
|
||||
NonGeneric(DefId),
|
||||
Generic(DefId, &'tcx Substs<'tcx>),
|
||||
NoDefId(ty::SymbolName),
|
||||
}
|
||||
|
||||
impl ExportedSymbol {
|
||||
pub fn symbol_name(&self, tcx: ty::TyCtxt) -> ty::SymbolName {
|
||||
impl<'tcx> ExportedSymbol<'tcx> {
|
||||
pub fn symbol_name(&self,
|
||||
tcx: ty::TyCtxt<'_, 'tcx, '_>)
|
||||
-> ty::SymbolName {
|
||||
match *self {
|
||||
ExportedSymbol::NonGeneric(def_id) => {
|
||||
tcx.symbol_name(ty::Instance::mono(tcx, def_id))
|
||||
}
|
||||
ExportedSymbol::Generic(def_id, substs) => {
|
||||
tcx.symbol_name(ty::Instance::new(def_id, substs))
|
||||
}
|
||||
ExportedSymbol::NoDefId(symbol_name) => {
|
||||
symbol_name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compare_stable(&self, tcx: ty::TyCtxt, other: &ExportedSymbol) -> cmp::Ordering {
|
||||
pub fn compare_stable(&self,
|
||||
tcx: ty::TyCtxt<'_, 'tcx, '_>,
|
||||
other: &ExportedSymbol<'tcx>)
|
||||
-> cmp::Ordering {
|
||||
match *self {
|
||||
ExportedSymbol::NonGeneric(self_def_id) => {
|
||||
match *other {
|
||||
ExportedSymbol::NonGeneric(other_def_id) => {
|
||||
tcx.def_path_hash(self_def_id).cmp(&tcx.def_path_hash(other_def_id))
|
||||
}
|
||||
ExportedSymbol::NoDefId(_) => {
|
||||
cmp::Ordering::Less
|
||||
}
|
||||
ExportedSymbol::NonGeneric(self_def_id) => match *other {
|
||||
ExportedSymbol::NonGeneric(other_def_id) => {
|
||||
tcx.def_path_hash(self_def_id).cmp(&tcx.def_path_hash(other_def_id))
|
||||
}
|
||||
ExportedSymbol::Generic(..) |
|
||||
ExportedSymbol::NoDefId(_) => {
|
||||
cmp::Ordering::Less
|
||||
}
|
||||
}
|
||||
ExportedSymbol::NoDefId(self_symbol_name) => {
|
||||
match *other {
|
||||
ExportedSymbol::NonGeneric(_) => {
|
||||
cmp::Ordering::Greater
|
||||
}
|
||||
ExportedSymbol::NoDefId(ref other_symbol_name) => {
|
||||
self_symbol_name.cmp(other_symbol_name)
|
||||
}
|
||||
ExportedSymbol::Generic(..) => match *other {
|
||||
ExportedSymbol::NonGeneric(_) => {
|
||||
cmp::Ordering::Greater
|
||||
}
|
||||
ExportedSymbol::Generic(..) => {
|
||||
self.symbol_name(tcx).cmp(&other.symbol_name(tcx))
|
||||
}
|
||||
ExportedSymbol::NoDefId(_) => {
|
||||
cmp::Ordering::Less
|
||||
}
|
||||
}
|
||||
ExportedSymbol::NoDefId(self_symbol_name) => match *other {
|
||||
ExportedSymbol::NonGeneric(_) |
|
||||
ExportedSymbol::Generic(..) => {
|
||||
cmp::Ordering::Greater
|
||||
}
|
||||
ExportedSymbol::NoDefId(ref other_symbol_name) => {
|
||||
self_symbol_name.cmp(other_symbol_name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_stable_hash_for!(enum self::ExportedSymbol {
|
||||
NonGeneric(def_id),
|
||||
NoDefId(symbol_name)
|
||||
});
|
||||
|
||||
pub fn metadata_symbol_name(tcx: ty::TyCtxt) -> String {
|
||||
format!("rust_metadata_{}_{}",
|
||||
tcx.original_crate_name(LOCAL_CRATE),
|
||||
tcx.crate_disambiguator(LOCAL_CRATE).to_fingerprint().to_hex())
|
||||
}
|
||||
|
||||
impl<'gcx> HashStable<StableHashingContext<'gcx>> for ExportedSymbol<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'gcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
mem::discriminant(self).hash_stable(hcx, hasher);
|
||||
match *self {
|
||||
ExportedSymbol::NonGeneric(def_id) => {
|
||||
def_id.hash_stable(hcx, hasher);
|
||||
}
|
||||
ExportedSymbol::Generic(def_id, substs) => {
|
||||
def_id.hash_stable(hcx, hasher);
|
||||
substs.hash_stable(hcx, hasher);
|
||||
}
|
||||
ExportedSymbol::NoDefId(symbol_name) => {
|
||||
symbol_name.hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -381,7 +381,7 @@ define_maps! { <'tcx>
|
|||
[] fn all_crate_nums: all_crate_nums_node(CrateNum) -> Lrc<Vec<CrateNum>>,
|
||||
|
||||
[] fn exported_symbols: ExportedSymbols(CrateNum)
|
||||
-> Arc<Vec<(ExportedSymbol, SymbolExportLevel)>>,
|
||||
-> Arc<Vec<(ExportedSymbol<'tcx>, SymbolExportLevel)>>,
|
||||
[] fn collect_and_partition_translation_items:
|
||||
collect_and_partition_translation_items_node(CrateNum)
|
||||
-> (Arc<DefIdSet>, Arc<Vec<Arc<CodegenUnit<'tcx>>>>),
|
||||
|
|
|
@ -268,7 +268,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
|
|||
return Arc::new(Vec::new())
|
||||
}
|
||||
|
||||
Arc::new(cdata.exported_symbols())
|
||||
Arc::new(cdata.exported_symbols(tcx))
|
||||
}
|
||||
|
||||
wasm_custom_sections => { Lrc::new(cdata.wasm_custom_sections()) }
|
||||
|
|
|
@ -1065,11 +1065,13 @@ impl<'a, 'tcx> CrateMetadata {
|
|||
arg_names.decode(self).collect()
|
||||
}
|
||||
|
||||
pub fn exported_symbols(&self) -> Vec<(ExportedSymbol, SymbolExportLevel)> {
|
||||
self.root
|
||||
.exported_symbols
|
||||
.decode(self)
|
||||
.collect()
|
||||
pub fn exported_symbols(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>)
|
||||
-> Vec<(ExportedSymbol<'tcx>, SymbolExportLevel)> {
|
||||
let lazy_seq: LazySeq<(ExportedSymbol<'tcx>, SymbolExportLevel)> =
|
||||
LazySeq::with_position_and_length(self.root.exported_symbols.position,
|
||||
self.root.exported_symbols.len);
|
||||
lazy_seq.decode((self, tcx)).collect()
|
||||
}
|
||||
|
||||
pub fn wasm_custom_sections(&self) -> Vec<DefId> {
|
||||
|
|
|
@ -1444,13 +1444,12 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
|||
// definition (as that's not defined in this crate).
|
||||
fn encode_exported_symbols(&mut self,
|
||||
exported_symbols: &[(ExportedSymbol, SymbolExportLevel)])
|
||||
-> LazySeq<(ExportedSymbol, SymbolExportLevel)> {
|
||||
|
||||
-> EncodedExportedSymbols {
|
||||
// The metadata symbol name is special. It should not show up in
|
||||
// downstream crates.
|
||||
let metadata_symbol_name = SymbolName::new(&metadata_symbol_name(self.tcx));
|
||||
|
||||
self.lazy_seq(exported_symbols
|
||||
let lazy_seq = self.lazy_seq(exported_symbols
|
||||
.iter()
|
||||
.filter(|&&(ref exported_symbol, _)| {
|
||||
match *exported_symbol {
|
||||
|
@ -1460,7 +1459,12 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
|||
_ => true,
|
||||
}
|
||||
})
|
||||
.cloned())
|
||||
.cloned());
|
||||
|
||||
EncodedExportedSymbols {
|
||||
len: lazy_seq.len,
|
||||
position: lazy_seq.position,
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_wasm_custom_sections(&mut self, statics: &[DefId]) -> LazySeq<DefIndex> {
|
||||
|
|
|
@ -15,7 +15,6 @@ use rustc::hir;
|
|||
use rustc::hir::def::{self, CtorKind};
|
||||
use rustc::hir::def_id::{DefIndex, DefId, CrateNum};
|
||||
use rustc::ich::StableHashingContext;
|
||||
use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
|
||||
use rustc::middle::cstore::{DepKind, LinkagePreference, NativeLibrary, ForeignModule};
|
||||
use rustc::middle::lang_items;
|
||||
use rustc::mir;
|
||||
|
@ -206,7 +205,7 @@ pub struct CrateRoot {
|
|||
pub codemap: LazySeq<syntax_pos::FileMap>,
|
||||
pub def_path_table: Lazy<hir::map::definitions::DefPathTable>,
|
||||
pub impls: LazySeq<TraitImpls>,
|
||||
pub exported_symbols: LazySeq<(ExportedSymbol, SymbolExportLevel)>,
|
||||
pub exported_symbols: EncodedExportedSymbols,
|
||||
pub wasm_custom_sections: LazySeq<DefIndex>,
|
||||
|
||||
pub index: LazySeq<index::Index>,
|
||||
|
@ -531,3 +530,9 @@ impl_stable_hash_for!(struct GeneratorData<'tcx> { layout });
|
|||
// Tags used for encoding Spans:
|
||||
pub const TAG_VALID_SPAN: u8 = 0;
|
||||
pub const TAG_INVALID_SPAN: u8 = 1;
|
||||
|
||||
#[derive(RustcEncodable, RustcDecodable)]
|
||||
pub struct EncodedExportedSymbols {
|
||||
pub position: usize,
|
||||
pub len: usize,
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ fn is_reachable_non_generic_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
|
||||
fn exported_symbols_provider_local<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
cnum: CrateNum)
|
||||
-> Arc<Vec<(ExportedSymbol,
|
||||
-> Arc<Vec<(ExportedSymbol<'tcx>,
|
||||
SymbolExportLevel)>>
|
||||
{
|
||||
assert_eq!(cnum, LOCAL_CRATE);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#![cfg_attr(stage0, feature(conservative_impl_trait))]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(inclusive_range_fields)]
|
||||
#![feature(underscore_lifetimes)]
|
||||
|
||||
use rustc::dep_graph::WorkProduct;
|
||||
use syntax_pos::symbol::Symbol;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue