rustc_metadata: Move CrateMetadata into decoder.rs

It allows to make most of its fields private
This commit is contained in:
Vadim Petrochenkov 2019-11-17 16:50:46 +03:00
parent 41ee980f9f
commit c1570238b8
5 changed files with 135 additions and 142 deletions

View File

@ -1,8 +1,8 @@
//! Validates all used crates and extern libraries and loads their metadata
use crate::cstore::{self, CStore};
use crate::cstore::CStore;
use crate::locator::{CrateLocator, CratePaths};
use crate::rmeta::{CrateRoot, CrateDep, MetadataBlob};
use crate::rmeta::{CrateMetadata, CrateNumMap, CrateRoot, CrateDep, MetadataBlob};
use rustc::hir::def_id::CrateNum;
use rustc_data_structures::svh::Svh;
@ -46,9 +46,9 @@ pub struct CrateLoader<'a> {
fn dump_crates(cstore: &CStore) {
info!("resolved crates:");
cstore.iter_crate_data(|_, data| {
cstore.iter_crate_data(|cnum, data| {
info!(" name: {}", data.root.name);
info!(" cnum: {}", data.cnum);
info!(" cnum: {}", cnum);
info!(" hash: {}", data.root.hash);
info!(" reqd: {:?}", *data.dep_kind.lock());
let CrateSource { dylib, rlib, rmeta } = data.source.clone();
@ -224,7 +224,7 @@ fn register_crate(
self.dlsym_proc_macros(&dlsym_dylib.0, dlsym_root.disambiguator, span)
});
self.cstore.set_crate_data(cnum, cstore::CrateMetadata::new(
self.cstore.set_crate_data(cnum, CrateMetadata::new(
self.sess,
metadata,
crate_root,
@ -439,10 +439,10 @@ fn resolve_crate_deps(&mut self,
krate: CrateNum,
span: Span,
dep_kind: DepKind)
-> cstore::CrateNumMap {
-> CrateNumMap {
debug!("resolving deps of external crate");
if crate_root.proc_macro_data.is_some() {
return cstore::CrateNumMap::new();
return CrateNumMap::new();
}
// The map from crate numbers in the crate we're resolving to local crate numbers.
@ -792,7 +792,7 @@ fn inject_allocator_crate(&mut self, krate: &ast::Crate) {
fn inject_dependency_if(&self,
krate: CrateNum,
what: &str,
needs_dep: &dyn Fn(&cstore::CrateMetadata) -> bool) {
needs_dep: &dyn Fn(&CrateMetadata) -> bool) {
// don't perform this validation if the session has errors, as one of
// those errors may indicate a circular dependency which could cause
// this to stack overflow.

View File

@ -1,92 +1,18 @@
// The crate store - a central repo for information collected about external
// crates and libraries
use crate::rmeta::{CrateRoot, ImportedSourceFile, Lazy, MetadataBlob};
use rustc::dep_graph::DepNodeIndex;
use rustc::hir::def_id::{CrateNum, DefIndex};
use rustc::hir::map::definitions::DefPathTable;
use rustc::middle::cstore::{CrateSource, DepKind, ExternCrate};
use rustc::mir::interpret::AllocDecodingState;
use rustc::session::Session;
use crate::rmeta::CrateMetadata;
use rustc_data_structures::sync::Lrc;
use rustc_index::vec::IndexVec;
use rustc::util::common::record_time;
use rustc::util::nodemap::FxHashMap;
use rustc_data_structures::sync::{Lrc, Lock, Once, AtomicCell};
use rustc_data_structures::svh::Svh;
use rustc::hir::def_id::CrateNum;
use syntax::ast;
use syntax::edition::Edition;
use syntax_expand::base::SyntaxExtension;
use syntax::expand::allocator::AllocatorKind;
use proc_macro::bridge::client::ProcMacro;
use syntax_expand::base::SyntaxExtension;
pub use crate::rmeta::{provide, provide_extern};
// A map from external crate numbers (as decoded from some crate file) to
// local crate numbers (as generated during this session). Each external
// crate may refer to types in other external crates, and each has their
// own crate numbers.
crate type CrateNumMap = IndexVec<CrateNum, CrateNum>;
crate struct CrateMetadata {
/// The primary crate data - binary metadata blob.
crate blob: MetadataBlob,
// --- Some data pre-decoded from the metadata blob, usually for performance ---
/// Properties of the whole crate.
/// NOTE(eddyb) we pass `'static` to a `'tcx` parameter because this
/// lifetime is only used behind `Lazy`, and therefore acts like an
/// universal (`for<'tcx>`), that is paired up with whichever `TyCtxt`
/// is being used to decode those values.
crate root: CrateRoot<'static>,
/// For each definition in this crate, we encode a key. When the
/// crate is loaded, we read all the keys and put them in this
/// hashmap, which gives the reverse mapping. This allows us to
/// quickly retrace a `DefPath`, which is needed for incremental
/// compilation support.
crate def_path_table: DefPathTable,
/// Trait impl data.
/// FIXME: Used only from queries and can use query cache,
/// so pre-decoding can probably be avoided.
crate trait_impls: FxHashMap<(u32, DefIndex), Lazy<[DefIndex]>>,
/// Proc macro descriptions for this crate, if it's a proc macro crate.
crate raw_proc_macros: Option<&'static [ProcMacro]>,
/// Source maps for code from the crate.
crate source_map_import_info: Once<Vec<ImportedSourceFile>>,
/// Used for decoding interpret::AllocIds in a cached & thread-safe manner.
crate alloc_decoding_state: AllocDecodingState,
/// The `DepNodeIndex` of the `DepNode` representing this upstream crate.
/// It is initialized on the first access in `get_crate_dep_node_index()`.
/// Do not access the value directly, as it might not have been initialized yet.
/// The field must always be initialized to `DepNodeIndex::INVALID`.
crate dep_node_index: AtomicCell<DepNodeIndex>,
// --- Other significant crate properties ---
/// ID of this crate, from the current compilation session's point of view.
crate cnum: CrateNum,
/// Maps crate IDs as they are were seen from this crate's compilation sessions into
/// IDs as they are seen from the current compilation session.
crate cnum_map: CrateNumMap,
/// Same ID set as `cnum_map` plus maybe some injected crates like panic runtime.
crate dependencies: Lock<Vec<CrateNum>>,
/// How to link (or not link) this crate to the currently compiled crate.
crate dep_kind: Lock<DepKind>,
/// Filesystem location of this crate.
crate source: CrateSource,
/// Whether or not this crate should be consider a private dependency
/// for purposes of the 'exported_private_dependencies' lint
crate private_dep: bool,
/// The hash for the host proc macro. Used to support `-Z dual-proc-macro`.
crate host_hash: Option<Svh>,
// --- Data used only for improving diagnostics ---
/// Information about the `extern crate` item or path that caused this crate to be loaded.
/// If this is `None`, then the crate was injected (e.g., by the allocator).
crate extern_crate: Lock<Option<ExternCrate>>,
}
#[derive(Clone)]
pub struct CStore {
metas: IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>,
@ -99,48 +25,6 @@ pub enum LoadedMacro {
ProcMacro(SyntaxExtension),
}
impl CrateMetadata {
crate fn new(
sess: &Session,
blob: MetadataBlob,
root: CrateRoot<'static>,
raw_proc_macros: Option<&'static [ProcMacro]>,
cnum: CrateNum,
cnum_map: CrateNumMap,
dep_kind: DepKind,
source: CrateSource,
private_dep: bool,
host_hash: Option<Svh>,
) -> CrateMetadata {
let def_path_table = record_time(&sess.perf_stats.decode_def_path_tables_time, || {
root.def_path_table.decode((&blob, sess))
});
let trait_impls = root.impls.decode((&blob, sess))
.map(|trait_impls| (trait_impls.trait_id, trait_impls.impls)).collect();
let alloc_decoding_state =
AllocDecodingState::new(root.interpret_alloc_index.decode(&blob).collect());
let dependencies = Lock::new(cnum_map.iter().cloned().collect());
CrateMetadata {
blob,
root,
def_path_table,
trait_impls,
raw_proc_macros,
source_map_import_info: Once::new(),
alloc_decoding_state,
dep_node_index: AtomicCell::new(DepNodeIndex::INVALID),
cnum,
cnum_map,
dependencies,
dep_kind: Lock::new(dep_kind),
source,
private_dep,
host_hash,
extern_crate: Lock::new(None),
}
}
}
impl Default for CStore {
fn default() -> Self {
CStore {

View File

@ -1,27 +1,30 @@
// Decoding metadata from a single crate's metadata
use crate::cstore::CrateMetadata;
use crate::rmeta::*;
use crate::rmeta::table::{FixedSizeEncoding, PerDefTable};
use rustc_index::vec::IndexVec;
use rustc_data_structures::sync::Lrc;
use rustc_data_structures::sync::{Lrc, Lock, Once, AtomicCell};
use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash};
use rustc::hir::map::definitions::DefPathTable;
use rustc::hir;
use rustc::middle::cstore::{CrateSource, ExternCrate};
use rustc::middle::cstore::{LinkagePreference, NativeLibrary, ForeignModule};
use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
use rustc::hir::def::{self, Res, DefKind, CtorOf, CtorKind};
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::FxHashMap;
use rustc::dep_graph::{DepNodeIndex, DepKind};
use rustc_data_structures::svh::Svh;
use rustc::dep_graph::{self, DepNodeIndex};
use rustc::middle::lang_items;
use rustc::mir::{self, interpret};
use rustc::mir::interpret::AllocDecodingSession;
use rustc::mir::interpret::{AllocDecodingSession, AllocDecodingState};
use rustc::session::Session;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::codec::TyDecoder;
use rustc::mir::{Body, Promoted};
use rustc::util::common::record_time;
use rustc::util::captures::Captures;
use std::io;
@ -46,9 +49,75 @@
crate struct MetadataBlob(MetadataRef);
// A map from external crate numbers (as decoded from some crate file) to
// local crate numbers (as generated during this session). Each external
// crate may refer to types in other external crates, and each has their
// own crate numbers.
crate type CrateNumMap = IndexVec<CrateNum, CrateNum>;
crate struct CrateMetadata {
/// The primary crate data - binary metadata blob.
blob: MetadataBlob,
// --- Some data pre-decoded from the metadata blob, usually for performance ---
/// Properties of the whole crate.
/// NOTE(eddyb) we pass `'static` to a `'tcx` parameter because this
/// lifetime is only used behind `Lazy`, and therefore acts like an
/// universal (`for<'tcx>`), that is paired up with whichever `TyCtxt`
/// is being used to decode those values.
crate root: CrateRoot<'static>,
/// For each definition in this crate, we encode a key. When the
/// crate is loaded, we read all the keys and put them in this
/// hashmap, which gives the reverse mapping. This allows us to
/// quickly retrace a `DefPath`, which is needed for incremental
/// compilation support.
def_path_table: DefPathTable,
/// Trait impl data.
/// FIXME: Used only from queries and can use query cache,
/// so pre-decoding can probably be avoided.
trait_impls: FxHashMap<(u32, DefIndex), Lazy<[DefIndex]>>,
/// Proc macro descriptions for this crate, if it's a proc macro crate.
raw_proc_macros: Option<&'static [ProcMacro]>,
/// Source maps for code from the crate.
source_map_import_info: Once<Vec<ImportedSourceFile>>,
/// Used for decoding interpret::AllocIds in a cached & thread-safe manner.
alloc_decoding_state: AllocDecodingState,
/// The `DepNodeIndex` of the `DepNode` representing this upstream crate.
/// It is initialized on the first access in `get_crate_dep_node_index()`.
/// Do not access the value directly, as it might not have been initialized yet.
/// The field must always be initialized to `DepNodeIndex::INVALID`.
dep_node_index: AtomicCell<DepNodeIndex>,
// --- Other significant crate properties ---
/// ID of this crate, from the current compilation session's point of view.
cnum: CrateNum,
/// Maps crate IDs as they are were seen from this crate's compilation sessions into
/// IDs as they are seen from the current compilation session.
cnum_map: CrateNumMap,
/// Same ID set as `cnum_map` plus maybe some injected crates like panic runtime.
crate dependencies: Lock<Vec<CrateNum>>,
/// How to link (or not link) this crate to the currently compiled crate.
crate dep_kind: Lock<DepKind>,
/// Filesystem location of this crate.
crate source: CrateSource,
/// Whether or not this crate should be consider a private dependency
/// for purposes of the 'exported_private_dependencies' lint
private_dep: bool,
/// The hash for the host proc macro. Used to support `-Z dual-proc-macro`.
host_hash: Option<Svh>,
// --- Data used only for improving diagnostics ---
/// Information about the `extern crate` item or path that caused this crate to be loaded.
/// If this is `None`, then the crate was injected (e.g., by the allocator).
crate extern_crate: Lock<Option<ExternCrate>>,
}
/// Holds information about a syntax_pos::SourceFile imported from another crate.
/// See `imported_source_files()` for more information.
crate struct ImportedSourceFile {
struct ImportedSourceFile {
/// This SourceFile's byte-offset within the source_map of its original crate
original_start_pos: syntax_pos::BytePos,
/// The end of this SourceFile within the source_map of its original crate
@ -485,6 +554,46 @@ fn def_kind(&self) -> Option<DefKind> {
}
impl<'a, 'tcx> CrateMetadata {
crate fn new(
sess: &Session,
blob: MetadataBlob,
root: CrateRoot<'static>,
raw_proc_macros: Option<&'static [ProcMacro]>,
cnum: CrateNum,
cnum_map: CrateNumMap,
dep_kind: DepKind,
source: CrateSource,
private_dep: bool,
host_hash: Option<Svh>,
) -> CrateMetadata {
let def_path_table = record_time(&sess.perf_stats.decode_def_path_tables_time, || {
root.def_path_table.decode((&blob, sess))
});
let trait_impls = root.impls.decode((&blob, sess))
.map(|trait_impls| (trait_impls.trait_id, trait_impls.impls)).collect();
let alloc_decoding_state =
AllocDecodingState::new(root.interpret_alloc_index.decode(&blob).collect());
let dependencies = Lock::new(cnum_map.iter().cloned().collect());
CrateMetadata {
blob,
root,
def_path_table,
trait_impls,
raw_proc_macros,
source_map_import_info: Once::new(),
alloc_decoding_state,
dep_node_index: AtomicCell::new(DepNodeIndex::INVALID),
cnum,
cnum_map,
dependencies,
dep_kind: Lock::new(dep_kind),
source,
private_dep,
host_hash,
extern_crate: Lock::new(None),
}
}
fn is_proc_macro_crate(&self) -> bool {
self.root.proc_macro_decls_static.is_some()
}
@ -1391,7 +1500,7 @@ fn get_crate_dep_node_index(&self, tcx: TyCtxt<'tcx>) -> DepNodeIndex {
// would always write the same value.
let def_path_hash = self.def_path_hash(CRATE_DEF_INDEX);
let dep_node = def_path_hash.to_dep_node(DepKind::CrateMetadata);
let dep_node = def_path_hash.to_dep_node(dep_graph::DepKind::CrateMetadata);
dep_node_index = tcx.dep_graph.dep_node_index_of(&dep_node);
assert!(dep_node_index != DepNodeIndex::INVALID);

View File

@ -52,7 +52,7 @@ pub fn provide_extern<$lt>(providers: &mut Providers<$lt>) {
assert!(!$def_id.is_local());
let $cdata = $tcx.crate_data_as_any($def_id.krate);
let $cdata = $cdata.downcast_ref::<cstore::CrateMetadata>()
let $cdata = $cdata.downcast_ref::<rmeta::CrateMetadata>()
.expect("CrateStore created data is not a CrateMetadata");
if $tcx.dep_graph.is_fully_enabled() {

View File

@ -25,7 +25,7 @@
use std::num::NonZeroUsize;
pub use decoder::{provide, provide_extern};
crate use decoder::{ImportedSourceFile, MetadataBlob};
crate use decoder::{CrateMetadata, CrateNumMap, MetadataBlob};
mod decoder;
mod encoder;
@ -197,10 +197,10 @@ macro_rules! Lazy {
native_libraries: Lazy<[NativeLibrary]>,
foreign_modules: Lazy<[ForeignModule]>,
source_map: Lazy<[syntax_pos::SourceFile]>,
pub def_path_table: Lazy<hir::map::definitions::DefPathTable>,
pub impls: Lazy<[TraitImpls]>,
def_path_table: Lazy<hir::map::definitions::DefPathTable>,
impls: Lazy<[TraitImpls]>,
exported_symbols: Lazy!([(ExportedSymbol<'tcx>, SymbolExportLevel)]),
pub interpret_alloc_index: Lazy<[u32]>,
interpret_alloc_index: Lazy<[u32]>,
per_def: LazyPerDefTables<'tcx>,
@ -229,8 +229,8 @@ macro_rules! Lazy {
#[derive(RustcEncodable, RustcDecodable)]
crate struct TraitImpls {
pub trait_id: (u32, DefIndex),
pub impls: Lazy<[DefIndex]>,
trait_id: (u32, DefIndex),
impls: Lazy<[DefIndex]>,
}
#[derive(RustcEncodable, RustcDecodable)]