diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index c3a195641f9c2..0511d83e33d99 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -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 @@ impl<'a> CrateLoader<'a> { 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 @@ impl<'a> CrateLoader<'a> { 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 @@ impl<'a> CrateLoader<'a> { 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. diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index e2d3da6237a3f..48cf0b982f290 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -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; - -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>, - /// 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, - - // --- 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>, - /// How to link (or not link) this crate to the currently compiled crate. - crate dep_kind: Lock, - /// 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, - - // --- 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>, -} - #[derive(Clone)] pub struct CStore { metas: IndexVec>>, @@ -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, - ) -> 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 { diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index 5ea23dc4b9821..30b60b6ed6733 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -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 @@ mod cstore_impl; 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; + +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>, + /// 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, + + // --- 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>, + /// How to link (or not link) this crate to the currently compiled crate. + crate dep_kind: Lock, + /// 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, + + // --- 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>, +} + /// 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 @@ impl<'tcx> EntryKind<'tcx> { } 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, + ) -> 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 @@ impl<'a, 'tcx> CrateMetadata { // 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); diff --git a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs index a6cb3864ca7d4..aa1dc843654f0 100644 --- a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs +++ b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs @@ -52,7 +52,7 @@ macro_rules! provide { assert!(!$def_id.is_local()); let $cdata = $tcx.crate_data_as_any($def_id.krate); - let $cdata = $cdata.downcast_ref::() + let $cdata = $cdata.downcast_ref::() .expect("CrateStore created data is not a CrateMetadata"); if $tcx.dep_graph.is_fully_enabled() { diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs index c1dd8499219f8..1dba07ccc628c 100644 --- a/src/librustc_metadata/rmeta/mod.rs +++ b/src/librustc_metadata/rmeta/mod.rs @@ -25,7 +25,7 @@ use std::marker::PhantomData; 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 @@ crate struct CrateRoot<'tcx> { native_libraries: Lazy<[NativeLibrary]>, foreign_modules: Lazy<[ForeignModule]>, source_map: Lazy<[syntax_pos::SourceFile]>, - pub def_path_table: Lazy, - pub impls: Lazy<[TraitImpls]>, + def_path_table: Lazy, + 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 @@ crate struct CrateDep { #[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)]