diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 7971c33426b2e..002e6874466bb 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -83,8 +83,6 @@ pub struct LoweringContext<'a> { /// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes. sess: &'a Session, - cstore: &'a dyn CrateStore, - resolver: &'a mut dyn Resolver, /// HACK(Centril): there is a cyclic dependency between the parser and lowering @@ -160,6 +158,8 @@ pub struct LoweringContext<'a> { } pub trait Resolver { + fn cstore(&self) -> &dyn CrateStore; + /// Obtains resolution for a `NodeId` with a single resolution. fn get_partial_res(&mut self, id: NodeId) -> Option; @@ -240,7 +240,6 @@ impl<'a> ImplTraitContext<'a> { pub fn lower_crate( sess: &Session, - cstore: &dyn CrateStore, dep_graph: &DepGraph, krate: &Crate, resolver: &mut dyn Resolver, @@ -256,7 +255,6 @@ pub fn lower_crate( LoweringContext { crate_root: sess.parse_sess.injected_crate_name.try_get().copied(), sess, - cstore, resolver, nt_to_tokenstream, items: BTreeMap::new(), @@ -980,7 +978,7 @@ impl<'a> LoweringContext<'a> { if id.is_local() { self.resolver.definitions().def_key(id.index) } else { - self.cstore.def_key(id) + self.resolver.cstore().def_key(id) } } @@ -1727,8 +1725,8 @@ impl<'a> LoweringContext<'a> { return n; } assert!(!def_id.is_local()); - let item_generics = - self.cstore.item_generics_cloned_untracked(def_id, self.sess); + let item_generics = self.resolver.cstore() + .item_generics_cloned_untracked(def_id, self.sess); let n = item_generics.own_counts().lifetimes; self.type_def_lifetime_params.insert(def_id, n); n diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index ec1e32988a607..d5558db2397e7 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -16,7 +16,7 @@ use syntax::ast; use syntax::symbol::Symbol; use syntax_pos::Span; use rustc_target::spec::Target; -use rustc_data_structures::sync::{self, MetadataRef, Lrc}; +use rustc_data_structures::sync::{self, MetadataRef}; use rustc_macros::HashStable; pub use self::NativeLibraryKind::*; @@ -191,6 +191,8 @@ pub trait MetadataLoader { -> Result; } +pub type MetadataLoaderDyn = dyn MetadataLoader + Sync; + /// A store of Rust crates, through which their metadata can be accessed. /// /// Note that this trait should probably not be expanding today. All new @@ -201,13 +203,13 @@ pub trait MetadataLoader { /// (it'd break incremental compilation) and should only be called pre-HIR (e.g. /// during resolve) pub trait CrateStore { - fn crate_data_as_rc_any(&self, krate: CrateNum) -> Lrc; + fn crate_data_as_any(&self, cnum: CrateNum) -> &dyn Any; // resolve fn def_key(&self, def: DefId) -> DefKey; fn def_path(&self, def: DefId) -> hir_map::DefPath; fn def_path_hash(&self, def: DefId) -> hir_map::DefPathHash; - fn def_path_table(&self, cnum: CrateNum) -> Lrc; + fn def_path_table(&self, cnum: CrateNum) -> &DefPathTable; // "queries" used in resolve that aren't tracked for incremental compilation fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol; diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index d5a93e0290550..f99298281fecc 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1027,7 +1027,7 @@ pub struct GlobalCtxt<'tcx> { interners: CtxtInterners<'tcx>, - cstore: &'tcx CrateStoreDyn, + cstore: Box, pub sess: &'tcx Session, @@ -1195,11 +1195,10 @@ impl<'tcx> TyCtxt<'tcx> { pub fn create_global_ctxt( s: &'tcx Session, lint_store: Lrc, - cstore: &'tcx CrateStoreDyn, local_providers: ty::query::Providers<'tcx>, extern_providers: ty::query::Providers<'tcx>, arenas: &'tcx AllArenas, - resolutions: ty::Resolutions, + resolutions: ty::ResolverOutputs, hir: hir_map::Map<'tcx>, on_disk_query_result_cache: query::OnDiskCache<'tcx>, crate_name: &str, @@ -1213,34 +1212,28 @@ impl<'tcx> TyCtxt<'tcx> { let common_lifetimes = CommonLifetimes::new(&interners); let common_consts = CommonConsts::new(&interners, &common_types); let dep_graph = hir.dep_graph.clone(); - let max_cnum = cstore.crates_untracked().iter().map(|c| c.as_usize()).max().unwrap_or(0); + let cstore = resolutions.cstore; + let crates = cstore.crates_untracked(); + let max_cnum = crates.iter().map(|c| c.as_usize()).max().unwrap_or(0); let mut providers = IndexVec::from_elem_n(extern_providers, max_cnum + 1); providers[LOCAL_CRATE] = local_providers; let def_path_hash_to_def_id = if s.opts.build_dep_graph() { - let upstream_def_path_tables: Vec<(CrateNum, Lrc<_>)> = cstore - .crates_untracked() + let def_path_tables = crates .iter() .map(|&cnum| (cnum, cstore.def_path_table(cnum))) - .collect(); - - let def_path_tables = || { - upstream_def_path_tables - .iter() - .map(|&(cnum, ref rc)| (cnum, &**rc)) - .chain(iter::once((LOCAL_CRATE, hir.definitions().def_path_table()))) - }; + .chain(iter::once((LOCAL_CRATE, hir.definitions().def_path_table()))); // Precompute the capacity of the hashmap so we don't have to // re-allocate when populating it. - let capacity = def_path_tables().map(|(_, t)| t.size()).sum::(); + let capacity = def_path_tables.clone().map(|(_, t)| t.size()).sum::(); let mut map: FxHashMap<_, _> = FxHashMap::with_capacity_and_hasher( capacity, ::std::default::Default::default() ); - for (cnum, def_path_table) in def_path_tables() { + for (cnum, def_path_table) in def_path_tables { def_path_table.add_def_path_hashes_to(cnum, &mut map); } @@ -1417,8 +1410,8 @@ impl<'tcx> TyCtxt<'tcx> { // Note that this is *untracked* and should only be used within the query // system if the result is otherwise tracked through queries - pub fn crate_data_as_rc_any(self, cnum: CrateNum) -> Lrc { - self.cstore.crate_data_as_rc_any(cnum) + pub fn crate_data_as_any(self, cnum: CrateNum) -> &'tcx dyn Any { + self.cstore.crate_data_as_any(cnum) } #[inline(always)] @@ -1428,7 +1421,7 @@ impl<'tcx> TyCtxt<'tcx> { StableHashingContext::new(self.sess, krate, self.hir().definitions(), - self.cstore) + &*self.cstore) } // This method makes sure that we have a DepNode and a Fingerprint for diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index feede00fea1c3..90450494a1419 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -15,6 +15,7 @@ use rustc_macros::HashStable; use crate::ich::Fingerprint; use crate::ich::StableHashingContext; use crate::infer::canonical::Canonical; +use crate::middle::cstore::CrateStoreDyn; use crate::middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; use crate::middle::resolve_lifetime::ObjectLifetimeDefault; use crate::mir::Body; @@ -119,8 +120,9 @@ mod sty; // Data types -#[derive(Clone)] -pub struct Resolutions { +pub struct ResolverOutputs { + pub definitions: hir_map::Definitions, + pub cstore: Box, pub extern_crate_map: NodeMap, pub trait_map: TraitMap, pub maybe_unused_trait_imports: NodeSet, diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 8c1797cfb7de4..e09b600afd4e5 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -56,7 +56,7 @@ use std::sync::Arc; use std::ffi::CStr; use rustc::dep_graph::DepGraph; -use rustc::middle::cstore::{EncodedMetadata, MetadataLoader}; +use rustc::middle::cstore::{EncodedMetadata, MetadataLoaderDyn}; use rustc::session::Session; use rustc::session::config::{OutputFilenames, OutputType, PrintRequest, OptLevel}; use rustc::ty::{self, TyCtxt}; @@ -260,7 +260,7 @@ impl CodegenBackend for LlvmCodegenBackend { target_features(sess) } - fn metadata_loader(&self) -> Box { + fn metadata_loader(&self) -> Box { box metadata::LlvmMetadataLoader } diff --git a/src/librustc_codegen_utils/codegen_backend.rs b/src/librustc_codegen_utils/codegen_backend.rs index 1077c1f42637e..0e2c3731eae6d 100644 --- a/src/librustc_codegen_utils/codegen_backend.rs +++ b/src/librustc_codegen_utils/codegen_backend.rs @@ -14,7 +14,7 @@ use rustc::util::common::ErrorReported; use rustc::session::config::{OutputFilenames, PrintRequest}; use rustc::ty::TyCtxt; use rustc::ty::query::Providers; -use rustc::middle::cstore::{EncodedMetadata, MetadataLoader}; +use rustc::middle::cstore::{EncodedMetadata, MetadataLoaderDyn}; use rustc::dep_graph::DepGraph; pub use rustc_data_structures::sync::MetadataRef; @@ -26,7 +26,7 @@ pub trait CodegenBackend { fn print_passes(&self) {} fn print_version(&self) {} - fn metadata_loader(&self) -> Box; + fn metadata_loader(&self) -> Box; fn provide(&self, _providers: &mut Providers<'_>); fn provide_extern(&self, _providers: &mut Providers<'_>); fn codegen_crate<'tcx>( diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 5d9dec14c6c8e..15adf7e4add73 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -36,11 +36,11 @@ use rustc::session::config::nightly_options; use rustc::session::{early_error, early_warn}; use rustc::lint::Lint; use rustc::lint; +use rustc::middle::cstore::MetadataLoader; use rustc::hir::def_id::LOCAL_CRATE; use rustc::ty::TyCtxt; use rustc::util::common::{set_time_depth, time, print_time_passes_entry, ErrorReported}; use rustc_metadata::locator; -use rustc_metadata::cstore::CStore; use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_interface::interface; use rustc_interface::util::get_codegen_sysroot; @@ -277,7 +277,7 @@ pub fn run_compiler( compiler.output_file(), ).and_then(|| RustcDefaultCalls::list_metadata( sess, - compiler.cstore(), + &*compiler.codegen_backend().metadata_loader(), &matches, compiler.input() )); @@ -614,7 +614,7 @@ fn show_content_with_pager(content: &String) { impl RustcDefaultCalls { pub fn list_metadata(sess: &Session, - cstore: &CStore, + metadata_loader: &dyn MetadataLoader, matches: &getopts::Matches, input: &Input) -> Compilation { @@ -626,7 +626,7 @@ impl RustcDefaultCalls { let mut v = Vec::new(); locator::list_file_metadata(&sess.target.target, path, - cstore, + metadata_loader, &mut v) .unwrap(); println!("{}", String::from_utf8(v).unwrap()); diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs index 24ea0fc8bf635..e014e4ed0fdc1 100644 --- a/src/librustc_interface/interface.rs +++ b/src/librustc_interface/interface.rs @@ -11,7 +11,6 @@ use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_data_structures::OnDrop; use rustc_data_structures::sync::Lrc; use rustc_data_structures::fx::{FxHashSet, FxHashMap}; -use rustc_metadata::cstore::CStore; use std::path::PathBuf; use std::result; use std::sync::{Arc, Mutex}; @@ -37,7 +36,6 @@ pub struct Compiler { pub(crate) output_dir: Option, pub(crate) output_file: Option, pub(crate) queries: Queries, - pub(crate) cstore: Lrc, pub(crate) crate_name: Option, pub(crate) register_lints: Option>, } @@ -49,9 +47,6 @@ impl Compiler { pub fn codegen_backend(&self) -> &Lrc> { &self.codegen_backend } - pub fn cstore(&self) -> &Lrc { - &self.cstore - } pub fn source_map(&self) -> &Lrc { &self.source_map } @@ -160,13 +155,10 @@ where config.lint_caps, ); - let cstore = Lrc::new(CStore::new(codegen_backend.metadata_loader())); - let compiler = Compiler { sess, codegen_backend, source_map, - cstore, input: config.input, input_path: config.input_path, output_dir: config.output_dir, diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 2044b73db8aa9..58936172c5bce 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -9,8 +9,8 @@ use rustc::hir::lowering::lower_crate; use rustc::hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc::lint; use rustc::middle::{self, reachable, resolve_lifetime, stability}; -use rustc::middle::cstore::CrateStore; -use rustc::ty::{self, AllArenas, Resolutions, TyCtxt, GlobalCtxt}; +use rustc::middle::cstore::{CrateStore, MetadataLoader, MetadataLoaderDyn}; +use rustc::ty::{self, AllArenas, ResolverOutputs, TyCtxt, GlobalCtxt}; use rustc::ty::steal::Steal; use rustc::traits; use rustc::util::common::{time, ErrorReported}; @@ -23,8 +23,7 @@ use rustc_codegen_utils::link::filename_for_metadata; use rustc_data_structures::{box_region_allow_access, declare_box_region_type, parallel}; use rustc_data_structures::sync::{Lrc, ParallelIterator, par_iter}; use rustc_incremental; -use rustc_metadata::creader::CrateLoader; -use rustc_metadata::cstore::{self, CStore}; +use rustc_metadata::cstore; use rustc_mir as mir; use rustc_passes::{self, ast_validation, hir_stats, layout_test}; use rustc_plugin as plugin; @@ -46,12 +45,10 @@ use syntax_ext; use rustc_serialize::json; use tempfile::Builder as TempFileBuilder; +use std::{env, fs, iter, mem}; use std::any::Any; -use std::env; use std::ffi::OsString; -use std::fs; use std::io::{self, Write}; -use std::iter; use std::path::PathBuf; use std::cell::RefCell; use std::rc::Rc; @@ -105,7 +102,7 @@ fn count_nodes(krate: &ast::Crate) -> usize { declare_box_region_type!( pub BoxedResolver, for(), - (&mut Resolver<'_>) -> (Result, ExpansionResult) + (&mut Resolver<'_>) -> (Result, ResolverOutputs) ); /// Runs the "early phases" of the compiler: initial `cfg` processing, @@ -118,7 +115,7 @@ declare_box_region_type!( pub fn configure_and_expand( sess: Lrc, lint_store: Lrc, - cstore: Lrc, + metadata_loader: Box, krate: ast::Crate, crate_name: &str, plugin_info: PluginInfo, @@ -131,16 +128,14 @@ pub fn configure_and_expand( let crate_name = crate_name.to_string(); let (result, resolver) = BoxedResolver::new(static move || { let sess = &*sess; - let crate_loader = CrateLoader::new(sess, &*cstore, &crate_name); let resolver_arenas = Resolver::arenas(); let res = configure_and_expand_inner( sess, &lint_store, - &*cstore, krate, &crate_name, &resolver_arenas, - &crate_loader, + &*metadata_loader, plugin_info, ); let mut resolver = match res { @@ -154,68 +149,16 @@ pub fn configure_and_expand( } }; box_region_allow_access!(for(), (&mut Resolver<'_>), (&mut resolver)); - ExpansionResult::from_owned_resolver(resolver) + resolver.into_outputs() }); result.map(|k| (k, resolver)) } -pub struct ExpansionResult { - pub defs: Steal, - pub resolutions: Steal, -} - -impl ExpansionResult { - fn from_owned_resolver( - resolver: Resolver<'_>, - ) -> Self { - ExpansionResult { - defs: Steal::new(resolver.definitions), - resolutions: Steal::new(Resolutions { - extern_crate_map: resolver.extern_crate_map, - export_map: resolver.export_map, - trait_map: resolver.trait_map, - glob_map: resolver.glob_map, - maybe_unused_trait_imports: resolver.maybe_unused_trait_imports, - maybe_unused_extern_crates: resolver.maybe_unused_extern_crates, - extern_prelude: resolver.extern_prelude.iter().map(|(ident, entry)| { - (ident.name, entry.introduced_by_item) - }).collect(), - }), - } - } - - pub fn from_resolver_ref( - resolver: &Resolver<'_>, - ) -> Self { - ExpansionResult { - defs: Steal::new(resolver.definitions.clone()), - resolutions: Steal::new(Resolutions { - extern_crate_map: resolver.extern_crate_map.clone(), - export_map: resolver.export_map.clone(), - trait_map: resolver.trait_map.clone(), - glob_map: resolver.glob_map.clone(), - maybe_unused_trait_imports: resolver.maybe_unused_trait_imports.clone(), - maybe_unused_extern_crates: resolver.maybe_unused_extern_crates.clone(), - extern_prelude: resolver.extern_prelude.iter().map(|(ident, entry)| { - (ident.name, entry.introduced_by_item) - }).collect(), - }), - } - } -} - impl BoxedResolver { - pub fn to_expansion_result( - resolver: Rc>, - ) -> ExpansionResult { + pub fn to_resolver_outputs(resolver: Rc>) -> ResolverOutputs { match Rc::try_unwrap(resolver) { Ok(resolver) => resolver.into_inner().complete(), - Err(resolver) => { - let resolver = &*resolver; - resolver.borrow_mut().access(|resolver| { - ExpansionResult::from_resolver_ref(resolver) - }) - } + Err(resolver) => resolver.borrow_mut().access(|resolver| resolver.clone_outputs()), } } } @@ -226,7 +169,7 @@ pub struct PluginInfo { pub fn register_plugins<'a>( sess: &'a Session, - cstore: &'a CStore, + metadata_loader: &'a dyn MetadataLoader, register_lints: impl Fn(&Session, &mut lint::LintStore), mut krate: ast::Crate, crate_name: &str, @@ -274,9 +217,8 @@ pub fn register_plugins<'a>( let registrars = time(sess, "plugin loading", || { plugin::load::load_plugins( sess, - &cstore, + metadata_loader, &krate, - crate_name, Some(sess.opts.debugging_opts.extra_plugins.clone()), ) }); @@ -313,11 +255,10 @@ pub fn register_plugins<'a>( fn configure_and_expand_inner<'a>( sess: &'a Session, lint_store: &'a lint::LintStore, - cstore: &'a CStore, mut krate: ast::Crate, crate_name: &str, resolver_arenas: &'a ResolverArenas<'a>, - crate_loader: &'a CrateLoader<'a>, + metadata_loader: &'a MetadataLoaderDyn, plugin_info: PluginInfo, ) -> Result<(ast::Crate, Resolver<'a>)> { time(sess, "pre-AST-expansion lint checks", || { @@ -331,10 +272,9 @@ fn configure_and_expand_inner<'a>( let mut resolver = Resolver::new( sess, - cstore, &krate, crate_name, - crate_loader, + metadata_loader, &resolver_arenas, ); syntax_ext::register_builtin_macros(&mut resolver, sess.edition()); @@ -534,7 +474,6 @@ fn configure_and_expand_inner<'a>( pub fn lower_to_hir( sess: &Session, lint_store: &lint::LintStore, - cstore: &CStore, resolver: &mut Resolver<'_>, dep_graph: &DepGraph, krate: &ast::Crate, @@ -542,7 +481,7 @@ pub fn lower_to_hir( // Lower AST to HIR. let hir_forest = time(sess, "lowering AST -> HIR", || { let nt_to_tokenstream = syntax::parse::nt_to_tokenstream; - let hir_crate = lower_crate(sess, cstore, &dep_graph, &krate, resolver, nt_to_tokenstream); + let hir_crate = lower_crate(sess, &dep_graph, &krate, resolver, nt_to_tokenstream); if sess.opts.debugging_opts.hir_stats { hir_stats::print_hir_stats(&hir_crate); @@ -648,8 +587,12 @@ fn escape_dep_filename(filename: &FileName) -> String { filename.to_string().replace(" ", "\\ ") } -fn write_out_deps(compiler: &Compiler, outputs: &OutputFilenames, out_filenames: &[PathBuf]) { - let sess = &compiler.sess; +fn write_out_deps( + sess: &Session, + boxed_resolver: &Steal>>, + outputs: &OutputFilenames, + out_filenames: &[PathBuf], +) { // Write out dependency rules to the dep-info file if requested if !sess.opts.output_types.contains_key(&OutputType::DepInfo) { return; @@ -668,18 +611,20 @@ fn write_out_deps(compiler: &Compiler, outputs: &OutputFilenames, out_filenames: .collect(); if sess.binary_dep_depinfo() { - for cnum in compiler.cstore.crates_untracked() { - let source = compiler.cstore.crate_source_untracked(cnum); - if let Some((path, _)) = source.dylib { - files.push(escape_dep_filename(&FileName::Real(path))); + boxed_resolver.borrow().borrow_mut().access(|resolver| { + for cnum in resolver.cstore().crates_untracked() { + let source = resolver.cstore().crate_source_untracked(cnum); + if let Some((path, _)) = source.dylib { + files.push(escape_dep_filename(&FileName::Real(path))); + } + if let Some((path, _)) = source.rlib { + files.push(escape_dep_filename(&FileName::Real(path))); + } + if let Some((path, _)) = source.rmeta { + files.push(escape_dep_filename(&FileName::Real(path))); + } } - if let Some((path, _)) = source.rlib { - files.push(escape_dep_filename(&FileName::Real(path))); - } - if let Some((path, _)) = source.rmeta { - files.push(escape_dep_filename(&FileName::Real(path))); - } - } + }); } let mut file = fs::File::create(&deps_filename)?; @@ -717,6 +662,7 @@ pub fn prepare_outputs( sess: &Session, compiler: &Compiler, krate: &ast::Crate, + boxed_resolver: &Steal>>, crate_name: &str ) -> Result { // FIXME: rustdoc passes &[] instead of &krate.attrs here @@ -758,7 +704,7 @@ pub fn prepare_outputs( } } - write_out_deps(compiler, &outputs, &output_paths); + write_out_deps(sess, boxed_resolver, &outputs, &output_paths); let only_dep_info = sess.opts.output_types.contains_key(&OutputType::DepInfo) && sess.opts.output_types.len() == 1; @@ -823,26 +769,24 @@ pub fn create_global_ctxt( compiler: &Compiler, lint_store: Lrc, mut hir_forest: hir::map::Forest, - defs: hir::map::Definitions, - resolutions: Resolutions, + mut resolver_outputs: ResolverOutputs, outputs: OutputFilenames, crate_name: &str, ) -> BoxedGlobalCtxt { let sess = compiler.session().clone(); - let cstore = compiler.cstore.clone(); let codegen_backend = compiler.codegen_backend().clone(); let crate_name = crate_name.to_string(); + let defs = mem::take(&mut resolver_outputs.definitions); let ((), result) = BoxedGlobalCtxt::new(static move || { let sess = &*sess; - let cstore = &*cstore; let global_ctxt: Option>; let arenas = AllArenas::new(); // Construct the HIR map. let hir_map = time(sess, "indexing HIR", || { - hir::map::map_crate(sess, cstore, &mut hir_forest, &defs) + hir::map::map_crate(sess, &*resolver_outputs.cstore, &mut hir_forest, &defs) }); let query_result_on_disk_cache = time(sess, "load query result cache", || { @@ -860,11 +804,10 @@ pub fn create_global_ctxt( let gcx = TyCtxt::create_global_ctxt( sess, lint_store, - cstore, local_providers, extern_providers, &arenas, - resolutions, + resolver_outputs, hir_map, query_result_on_disk_cache, &crate_name, diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 84648ca8326fb..ea51e63725ea2 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -1,5 +1,5 @@ use crate::interface::{Compiler, Result}; -use crate::passes::{self, BoxedResolver, ExpansionResult, BoxedGlobalCtxt, PluginInfo}; +use crate::passes::{self, BoxedResolver, BoxedGlobalCtxt, PluginInfo}; use rustc_incremental::DepGraphFuture; use rustc_data_structures::sync::Lrc; @@ -11,6 +11,7 @@ use rustc::session::Session; use rustc::lint::LintStore; use rustc::hir::def_id::LOCAL_CRATE; use rustc::ty::steal::Steal; +use rustc::ty::ResolverOutputs; use rustc::dep_graph::DepGraph; use std::cell::{Ref, RefMut, RefCell}; use std::rc::Rc; @@ -81,7 +82,7 @@ pub(crate) struct Queries { register_plugins: Query<(ast::Crate, PluginInfo, Lrc)>, expansion: Query<(ast::Crate, Steal>>, Lrc)>, dep_graph: Query, - lower_to_hir: Query<(Steal, ExpansionResult)>, + lower_to_hir: Query<(Steal, Steal)>, prepare_outputs: Query, global_ctxt: Query, ongoing_codegen: Query>, @@ -118,7 +119,7 @@ impl Compiler { let empty: &(dyn Fn(&Session, &mut lint::LintStore) + Sync + Send) = &|_, _| {}; let result = passes::register_plugins( self.session(), - self.cstore(), + &*self.codegen_backend().metadata_loader(), self.register_lints .as_ref() .map(|p| &**p) @@ -164,7 +165,7 @@ impl Compiler { passes::configure_and_expand( self.sess.clone(), lint_store.clone(), - self.cstore().clone(), + self.codegen_backend().metadata_loader(), krate, &crate_name, plugin_info, @@ -191,7 +192,9 @@ impl Compiler { }) } - pub fn lower_to_hir(&self) -> Result<&Query<(Steal, ExpansionResult)>> { + pub fn lower_to_hir( + &self, + ) -> Result<&Query<(Steal, Steal)>> { self.queries.lower_to_hir.compute(|| { let expansion_result = self.expansion()?; let peeked = expansion_result.peek(); @@ -202,23 +205,22 @@ impl Compiler { passes::lower_to_hir( self.session(), lint_store, - self.cstore(), resolver, &*self.dep_graph()?.peek(), &krate ) })?); - Ok((hir, BoxedResolver::to_expansion_result(resolver))) + Ok((hir, Steal::new(BoxedResolver::to_resolver_outputs(resolver)))) }) } pub fn prepare_outputs(&self) -> Result<&Query> { self.queries.prepare_outputs.compute(|| { - let krate = self.expansion()?; - let krate = krate.peek(); + let expansion_result = self.expansion()?; + let (krate, boxed_resolver, _) = &*expansion_result.peek(); let crate_name = self.crate_name()?; let crate_name = crate_name.peek(); - passes::prepare_outputs(self.session(), self, &krate.0, &*crate_name) + passes::prepare_outputs(self.session(), self, &krate, &boxed_resolver, &crate_name) }) } @@ -229,13 +231,12 @@ impl Compiler { let lint_store = self.expansion()?.peek().2.clone(); let hir = self.lower_to_hir()?; let hir = hir.peek(); - let (ref hir_forest, ref expansion) = *hir; + let (hir_forest, resolver_outputs) = &*hir; Ok(passes::create_global_ctxt( self, lint_store, hir_forest.steal(), - expansion.defs.steal(), - expansion.resolutions.steal(), + resolver_outputs.steal(), outputs, &crate_name)) }) diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 7412e8a2cb9bd..f0a68058de8ca 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -3,7 +3,7 @@ use crate::cstore::{self, CStore, MetadataBlob}; use crate::locator::{self, CratePaths}; use crate::schema::{CrateRoot, CrateDep}; -use rustc_data_structures::sync::{Lrc, RwLock, Lock, AtomicCell}; +use rustc_data_structures::sync::{RwLock, Lock, AtomicCell}; use rustc::hir::def_id::CrateNum; use rustc_data_structures::svh::Svh; @@ -14,21 +14,20 @@ use rustc::session::{Session, CrateDisambiguator}; use rustc::session::config::{Sanitizer, self}; use rustc_target::spec::{PanicStrategy, TargetTriple}; use rustc::session::search_paths::PathKind; -use rustc::middle::cstore::{CrateSource, ExternCrate, ExternCrateSource}; +use rustc::middle::cstore::{CrateSource, ExternCrate, ExternCrateSource, MetadataLoaderDyn}; use rustc::util::common::record_time; use rustc::util::nodemap::FxHashSet; use rustc::hir::map::Definitions; use rustc::hir::def_id::LOCAL_CRATE; -use std::ops::Deref; -use std::path::{Path, PathBuf}; +use std::path::Path; use std::{cmp, fs}; use syntax::ast; use syntax::attr; use syntax_expand::allocator::{global_allocator_spans, AllocatorKind}; use syntax::symbol::{Symbol, sym}; -use syntax::{span_err, span_fatal}; +use syntax::span_fatal; use syntax_pos::{Span, DUMMY_SP}; use log::{debug, info, log_enabled}; use proc_macro::bridge::client::ProcMacro; @@ -39,9 +38,12 @@ crate struct Library { } pub struct CrateLoader<'a> { + // Immutable configuration. sess: &'a Session, - cstore: &'a CStore, + metadata_loader: &'a MetadataLoaderDyn, local_crate_name: Symbol, + // Mutable output. + cstore: CStore, } fn dump_crates(cstore: &CStore) { @@ -58,29 +60,6 @@ fn dump_crates(cstore: &CStore) { }); } -// Extra info about a crate loaded for plugins or exported macros. -struct ExtensionCrate { - metadata: PMDSource, - dylib: Option, - target_only: bool, -} - -enum PMDSource { - Registered(Lrc), - Owned(Library), -} - -impl Deref for PMDSource { - type Target = MetadataBlob; - - fn deref(&self) -> &MetadataBlob { - match *self { - PMDSource::Registered(ref cmd) => &cmd.blob, - PMDSource::Owned(ref lib) => &lib.metadata - } - } -} - enum LoadResult { Previous(CrateNum), Loaded(Library), @@ -99,14 +78,27 @@ impl<'a> LoadError<'a> { } impl<'a> CrateLoader<'a> { - pub fn new(sess: &'a Session, cstore: &'a CStore, local_crate_name: &str) -> Self { + pub fn new( + sess: &'a Session, + metadata_loader: &'a MetadataLoaderDyn, + local_crate_name: &str, + ) -> Self { CrateLoader { sess, - cstore, + metadata_loader, local_crate_name: Symbol::intern(local_crate_name), + cstore: Default::default(), } } + pub fn cstore(&self) -> &CStore { + &self.cstore + } + + pub fn into_cstore(self) -> CStore { + self.cstore + } + fn existing_match(&self, name: Symbol, hash: Option<&Svh>, kind: PathKind) -> Option { let mut ret = None; @@ -187,14 +179,14 @@ impl<'a> CrateLoader<'a> { } fn register_crate( - &self, + &mut self, host_lib: Option, root: Option<&CratePaths>, span: Span, lib: Library, dep_kind: DepKind, name: Symbol - ) -> (CrateNum, Lrc) { + ) -> CrateNum { let _prof_timer = self.sess.prof.generic_activity("metadata_register_crate"); let Library { source, metadata } = lib; @@ -248,9 +240,9 @@ impl<'a> CrateLoader<'a> { crate_root.def_path_table.decode((&metadata, self.sess)) }); - let cmeta = cstore::CrateMetadata { + self.cstore.set_crate_data(cnum, cstore::CrateMetadata { extern_crate: Lock::new(None), - def_path_table: Lrc::new(def_path_table), + def_path_table, trait_impls, root: crate_root, blob: metadata, @@ -264,11 +256,9 @@ impl<'a> CrateLoader<'a> { private_dep, raw_proc_macros, dep_node_index: AtomicCell::new(DepNodeIndex::INVALID), - }; + }); - let cmeta = Lrc::new(cmeta); - self.cstore.set_crate_data(cnum, cmeta.clone()); - (cnum, cmeta) + cnum } fn load_proc_macro<'b>( @@ -327,22 +317,22 @@ impl<'a> CrateLoader<'a> { } fn resolve_crate<'b>( - &'b self, + &'b mut self, name: Symbol, span: Span, dep_kind: DepKind, dep: Option<(&'b CratePaths, &'b CrateDep)>, - ) -> (CrateNum, Lrc) { + ) -> CrateNum { self.maybe_resolve_crate(name, span, dep_kind, dep).unwrap_or_else(|err| err.report()) } fn maybe_resolve_crate<'b>( - &'b self, + &'b mut self, name: Symbol, span: Span, mut dep_kind: DepKind, dep: Option<(&'b CratePaths, &'b CrateDep)>, - ) -> Result<(CrateNum, Lrc), LoadError<'b>> { + ) -> Result> { info!("resolving crate `{}`", name); let (root, hash, extra_filename, path_kind) = match dep { Some((root, dep)) => @@ -370,7 +360,7 @@ impl<'a> CrateLoader<'a> { rejected_via_filename: vec![], should_match_name: true, is_proc_macro: Some(false), - metadata_loader: &*self.cstore.metadata_loader, + metadata_loader: self.metadata_loader, }; self.load(&mut locate_ctxt).map(|r| (r, None)).or_else(|| { @@ -388,7 +378,7 @@ impl<'a> CrateLoader<'a> { data.dep_kind.with_lock(|data_dep_kind| { *data_dep_kind = cmp::max(*data_dep_kind, dep_kind); }); - Ok((cnum, data)) + Ok(cnum) } (LoadResult::Loaded(library), host_library) => { Ok(self.register_crate(host_library, root, span, library, dep_kind, name)) @@ -466,7 +456,7 @@ impl<'a> CrateLoader<'a> { } // Go through the crate metadata and load any crates that it references - fn resolve_crate_deps(&self, + fn resolve_crate_deps(&mut self, root: &CratePaths, crate_root: &CrateRoot<'_>, metadata: &MetadataBlob, @@ -492,73 +482,10 @@ impl<'a> CrateLoader<'a> { DepKind::MacrosOnly => DepKind::MacrosOnly, _ => dep.kind, }; - self.resolve_crate(dep.name, span, dep_kind, Some((root, &dep))).0 + self.resolve_crate(dep.name, span, dep_kind, Some((root, &dep))) })).collect() } - fn read_extension_crate(&self, name: Symbol, span: Span) -> ExtensionCrate { - info!("read extension crate `{}`", name); - let target_triple = self.sess.opts.target_triple.clone(); - let host_triple = TargetTriple::from_triple(config::host_triple()); - let is_cross = target_triple != host_triple; - let mut target_only = false; - let mut locate_ctxt = locator::Context { - sess: self.sess, - span, - crate_name: name, - hash: None, - extra_filename: None, - filesearch: self.sess.host_filesearch(PathKind::Crate), - target: &self.sess.host, - triple: host_triple, - root: None, - rejected_via_hash: vec![], - rejected_via_triple: vec![], - rejected_via_kind: vec![], - rejected_via_version: vec![], - rejected_via_filename: vec![], - should_match_name: true, - is_proc_macro: None, - metadata_loader: &*self.cstore.metadata_loader, - }; - let library = self.load(&mut locate_ctxt).or_else(|| { - if !is_cross { - return None - } - // Try loading from target crates. This will abort later if we - // try to load a plugin registrar function, - target_only = true; - - locate_ctxt.target = &self.sess.target.target; - locate_ctxt.triple = target_triple; - locate_ctxt.filesearch = self.sess.target_filesearch(PathKind::Crate); - - self.load(&mut locate_ctxt) - }); - let library = match library { - Some(l) => l, - None => locate_ctxt.report_errs(), - }; - - let (dylib, metadata) = match library { - LoadResult::Previous(cnum) => { - let data = self.cstore.get_crate_data(cnum); - (data.source.dylib.clone(), PMDSource::Registered(data)) - } - LoadResult::Loaded(library) => { - let dylib = library.source.dylib.clone(); - let metadata = PMDSource::Owned(library); - (dylib, metadata) - } - }; - - ExtensionCrate { - metadata, - dylib: dylib.map(|p| p.0), - target_only, - } - } - fn dlsym_proc_macros(&self, path: &Path, disambiguator: CrateDisambiguator, @@ -590,42 +517,7 @@ impl<'a> CrateLoader<'a> { decls } - /// Look for a plugin registrar. Returns library path, crate - /// SVH and DefIndex of the registrar function. - pub fn find_plugin_registrar(&self, - span: Span, - name: Symbol) - -> Option<(PathBuf, CrateDisambiguator)> { - let ekrate = self.read_extension_crate(name, span); - - if ekrate.target_only { - // Need to abort before syntax expansion. - let message = format!("plugin `{}` is not available for triple `{}` \ - (only found {})", - name, - config::host_triple(), - self.sess.opts.target_triple); - span_fatal!(self.sess, span, E0456, "{}", &message); - } - - let root = ekrate.metadata.get_root(); - match ekrate.dylib.as_ref() { - Some(dylib) => { - Some((dylib.to_path_buf(), root.disambiguator)) - } - None => { - span_err!(self.sess, span, E0457, - "plugin `{}` only found in rlib format, but must be available \ - in dylib format", - name); - // No need to abort because the loading code will just ignore this - // empty dylib. - None - } - } - } - - fn inject_panic_runtime(&self, krate: &ast::Crate) { + fn inject_panic_runtime(&mut self, krate: &ast::Crate) { // If we're only compiling an rlib, then there's no need to select a // panic runtime, so we just skip this section entirely. let any_non_rlib = self.sess.crate_types.borrow().iter().any(|ct| { @@ -687,7 +579,8 @@ impl<'a> CrateLoader<'a> { }; info!("panic runtime not found -- loading {}", name); - let (cnum, data) = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None); + let cnum = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None); + let data = self.cstore.get_crate_data(cnum); // Sanity check the loaded crate to ensure it is indeed a panic runtime // and the panic strategy is indeed what we thought it was. @@ -706,7 +599,7 @@ impl<'a> CrateLoader<'a> { &|data| data.root.needs_panic_runtime); } - fn inject_sanitizer_runtime(&self) { + fn inject_sanitizer_runtime(&mut self) { if let Some(ref sanitizer) = self.sess.opts.debugging_opts.sanitizer { // Sanitizers can only be used on some tested platforms with // executables linked to `std` @@ -791,7 +684,8 @@ impl<'a> CrateLoader<'a> { }); info!("loading sanitizer: {}", name); - let data = self.resolve_crate(name, DUMMY_SP, DepKind::Explicit, None).1; + let cnum = self.resolve_crate(name, DUMMY_SP, DepKind::Explicit, None); + let data = self.cstore.get_crate_data(cnum); // Sanity check the loaded crate to ensure it is indeed a sanitizer runtime if !data.root.sanitizer_runtime { @@ -804,14 +698,15 @@ impl<'a> CrateLoader<'a> { } } - fn inject_profiler_runtime(&self) { + fn inject_profiler_runtime(&mut self) { if self.sess.opts.debugging_opts.profile || self.sess.opts.cg.profile_generate.enabled() { info!("loading profiler"); let name = Symbol::intern("profiler_builtins"); - let data = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None).1; + let cnum = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None); + let data = self.cstore.get_crate_data(cnum); // Sanity check the loaded crate to ensure it is indeed a profiler runtime if !data.root.profiler_runtime { @@ -957,10 +852,8 @@ impl<'a> CrateLoader<'a> { data.dependencies.borrow_mut().push(krate); }); } -} -impl<'a> CrateLoader<'a> { - pub fn postprocess(&self, krate: &ast::Crate) { + pub fn postprocess(&mut self, krate: &ast::Crate) { self.inject_sanitizer_runtime(); self.inject_profiler_runtime(); self.inject_allocator_crate(krate); @@ -971,7 +864,11 @@ impl<'a> CrateLoader<'a> { } } - pub fn process_extern_crate(&self, item: &ast::Item, definitions: &Definitions) -> CrateNum { + pub fn process_extern_crate( + &mut self, + item: &ast::Item, + definitions: &Definitions, + ) -> CrateNum { match item.kind { ast::ItemKind::ExternCrate(orig_name) => { debug!("resolving extern crate stmt. ident: {} orig_name: {:?}", @@ -990,7 +887,7 @@ impl<'a> CrateLoader<'a> { DepKind::Explicit }; - let cnum = self.resolve_crate(name, item.span, dep_kind, None).0; + let cnum = self.resolve_crate(name, item.span, dep_kind, None); let def_id = definitions.opt_local_def_id(item.id).unwrap(); let path_len = definitions.def_path(def_id.index).data.len(); @@ -1010,8 +907,8 @@ impl<'a> CrateLoader<'a> { } } - pub fn process_path_extern(&self, name: Symbol, span: Span) -> CrateNum { - let cnum = self.resolve_crate(name, span, DepKind::Explicit, None).0; + pub fn process_path_extern(&mut self, name: Symbol, span: Span) -> CrateNum { + let cnum = self.resolve_crate(name, span, DepKind::Explicit, None); self.update_extern_crate( cnum, @@ -1028,8 +925,8 @@ impl<'a> CrateLoader<'a> { cnum } - pub fn maybe_process_path_extern(&self, name: Symbol, span: Span) -> Option { - let cnum = self.maybe_resolve_crate(name, span, DepKind::Explicit, None).ok()?.0; + pub fn maybe_process_path_extern(&mut self, name: Symbol, span: Span) -> Option { + let cnum = self.maybe_resolve_crate(name, span, DepKind::Explicit, None).ok()?; self.update_extern_crate( cnum, diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 9a0b98ffb73a9..6b06cf575edcf 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -5,12 +5,13 @@ use crate::schema; 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, MetadataLoader}; +use rustc::middle::cstore::{CrateSource, DepKind, ExternCrate}; use rustc::mir::interpret::AllocDecodingState; use rustc_index::vec::IndexVec; use rustc::util::nodemap::FxHashMap; use rustc_data_structures::sync::{Lrc, RwLock, Lock, MetadataRef, AtomicCell}; use syntax::ast; +use syntax::edition::Edition; use syntax_expand::base::SyntaxExtension; use syntax_pos; use proc_macro::bridge::client::ProcMacro; @@ -36,7 +37,7 @@ crate struct ImportedSourceFile { pub translated_source_file: Lrc, } -pub struct CrateMetadata { +crate struct CrateMetadata { /// The primary crate data - binary metadata blob. crate blob: MetadataBlob, @@ -53,7 +54,7 @@ pub struct CrateMetadata { /// 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: Lrc, + 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. @@ -94,50 +95,48 @@ pub struct CrateMetadata { crate extern_crate: Lock>, } +#[derive(Clone)] pub struct CStore { - metas: RwLock>>>, - crate metadata_loader: Box, + metas: IndexVec>>, } pub enum LoadedMacro { - MacroDef(ast::Item), + MacroDef(ast::Item, Edition), ProcMacro(SyntaxExtension), } -impl CStore { - pub fn new(metadata_loader: Box) -> CStore { +impl Default for CStore { + fn default() -> Self { CStore { // We add an empty entry for LOCAL_CRATE (which maps to zero) in // order to make array indices in `metas` match with the // corresponding `CrateNum`. This first entry will always remain // `None`. - metas: RwLock::new(IndexVec::from_elem_n(None, 1)), - metadata_loader, + metas: IndexVec::from_elem_n(None, 1), } } +} - crate fn alloc_new_crate_num(&self) -> CrateNum { - let mut metas = self.metas.borrow_mut(); - let cnum = CrateNum::new(metas.len()); - metas.push(None); - cnum +impl CStore { + crate fn alloc_new_crate_num(&mut self) -> CrateNum { + self.metas.push(None); + CrateNum::new(self.metas.len() - 1) } - crate fn get_crate_data(&self, cnum: CrateNum) -> Lrc { - self.metas.borrow()[cnum].clone() + crate fn get_crate_data(&self, cnum: CrateNum) -> &CrateMetadata { + self.metas[cnum].as_ref() .unwrap_or_else(|| panic!("Failed to get crate data for {:?}", cnum)) } - crate fn set_crate_data(&self, cnum: CrateNum, data: Lrc) { - let mut metas = self.metas.borrow_mut(); - assert!(metas[cnum].is_none(), "Overwriting crate metadata entry"); - metas[cnum] = Some(data); + crate fn set_crate_data(&mut self, cnum: CrateNum, data: CrateMetadata) { + assert!(self.metas[cnum].is_none(), "Overwriting crate metadata entry"); + self.metas[cnum] = Some(Lrc::new(data)); } crate fn iter_crate_data(&self, mut i: I) - where I: FnMut(CrateNum, &Lrc) + where I: FnMut(CrateNum, &CrateMetadata) { - for (k, v) in self.metas.borrow().iter_enumerated() { + for (k, v) in self.metas.iter_enumerated() { if let &Some(ref v) = v { i(k, v); } @@ -168,7 +167,7 @@ impl CStore { crate fn do_postorder_cnums_untracked(&self) -> Vec { let mut ordering = Vec::new(); - for (num, v) in self.metas.borrow().iter_enumerated() { + for (num, v) in self.metas.iter_enumerated() { if let &Some(_) = v { self.push_dependencies_in_postorder(&mut ordering, num); } diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 6aba66a79ab3b..d942a19194a14 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -29,7 +29,6 @@ use std::sync::Arc; use syntax::ast; use syntax::attr; use syntax::source_map; -use syntax::edition::Edition; use syntax::parse::source_file_to_stream; use syntax::parse::parser::emit_unclosed_delims; use syntax::source_map::Spanned; @@ -54,7 +53,7 @@ macro_rules! provide { let ($def_id, $other) = def_id_arg.into_args(); assert!(!$def_id.is_local()); - let $cdata = $tcx.crate_data_as_rc_any($def_id.krate); + let $cdata = $tcx.crate_data_as_any($def_id.krate); let $cdata = $cdata.downcast_ref::() .expect("CrateStore created data is not a CrateMetadata"); @@ -411,10 +410,6 @@ impl cstore::CStore { } } - pub fn crate_edition_untracked(&self, cnum: CrateNum) -> Edition { - self.get_crate_data(cnum).root.edition - } - pub fn struct_field_names_untracked(&self, def: DefId, sess: &Session) -> Vec> { self.get_crate_data(def.krate).get_struct_field_names(def.index, sess) } @@ -470,7 +465,7 @@ impl cstore::CStore { }), vis: source_map::respan(local_span.shrink_to_lo(), ast::VisibilityKind::Inherited), tokens: None, - }) + }, data.root.edition) } pub fn associated_item_cloned_untracked(&self, def: DefId) -> ty::AssocItem { @@ -483,8 +478,8 @@ impl cstore::CStore { } impl CrateStore for cstore::CStore { - fn crate_data_as_rc_any(&self, krate: CrateNum) -> Lrc { - self.get_crate_data(krate) + fn crate_data_as_any(&self, cnum: CrateNum) -> &dyn Any { + self.get_crate_data(cnum) } fn item_generics_cloned_untracked(&self, def: DefId, sess: &Session) -> ty::Generics { @@ -525,8 +520,8 @@ impl CrateStore for cstore::CStore { self.get_crate_data(def.krate).def_path_hash(def.index) } - fn def_path_table(&self, cnum: CrateNum) -> Lrc { - self.get_crate_data(cnum).def_path_table.clone() + fn def_path_table(&self, cnum: CrateNum) -> &DefPathTable { + &self.get_crate_data(cnum).def_path_table } fn crates_untracked(&self) -> Vec diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index 05676dad3340c..a5298402dd411 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -212,7 +212,7 @@ //! no means all of the necessary details. Take a look at the rest of //! metadata::locator or metadata::creader for all the juicy details! -use crate::cstore::{MetadataBlob, CStore}; +use crate::cstore::MetadataBlob; use crate::creader::Library; use crate::schema::{METADATA_HEADER, rustc_version}; @@ -220,12 +220,13 @@ use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::MetadataRef; use rustc::middle::cstore::{CrateSource, MetadataLoader}; -use rustc::session::{config, Session}; +use rustc::session::{config, Session, CrateDisambiguator}; use rustc::session::filesearch::{FileSearch, FileMatches, FileDoesntMatch}; use rustc::session::search_paths::PathKind; use rustc::util::nodemap::FxHashMap; use errors::DiagnosticBuilder; +use syntax::{span_err, span_fatal}; use syntax::symbol::{Symbol, sym}; use syntax::struct_span_err; use syntax_pos::Span; @@ -911,10 +912,87 @@ fn get_metadata_section_imp(target: &Target, } } +/// Look for a plugin registrar. Returns its library path and crate disambiguator. +pub fn find_plugin_registrar( + sess: &Session, + metadata_loader: &dyn MetadataLoader, + span: Span, + name: Symbol, +) -> Option<(PathBuf, CrateDisambiguator)> { + info!("find plugin registrar `{}`", name); + let target_triple = sess.opts.target_triple.clone(); + let host_triple = TargetTriple::from_triple(config::host_triple()); + let is_cross = target_triple != host_triple; + let mut target_only = false; + let mut locate_ctxt = Context { + sess, + span, + crate_name: name, + hash: None, + extra_filename: None, + filesearch: sess.host_filesearch(PathKind::Crate), + target: &sess.host, + triple: host_triple, + root: None, + rejected_via_hash: vec![], + rejected_via_triple: vec![], + rejected_via_kind: vec![], + rejected_via_version: vec![], + rejected_via_filename: vec![], + should_match_name: true, + is_proc_macro: None, + metadata_loader, + }; + + let library = locate_ctxt.maybe_load_library_crate().or_else(|| { + if !is_cross { + return None + } + // Try loading from target crates. This will abort later if we + // try to load a plugin registrar function, + target_only = true; + + locate_ctxt.target = &sess.target.target; + locate_ctxt.triple = target_triple; + locate_ctxt.filesearch = sess.target_filesearch(PathKind::Crate); + + locate_ctxt.maybe_load_library_crate() + }); + let library = match library { + Some(l) => l, + None => locate_ctxt.report_errs(), + }; + + if target_only { + // Need to abort before syntax expansion. + let message = format!("plugin `{}` is not available for triple `{}` \ + (only found {})", + name, + config::host_triple(), + sess.opts.target_triple); + span_fatal!(sess, span, E0456, "{}", &message); + } + + match library.source.dylib { + Some(dylib) => { + Some((dylib.0, library.metadata.get_root().disambiguator)) + } + None => { + span_err!(sess, span, E0457, + "plugin `{}` only found in rlib format, but must be available \ + in dylib format", + name); + // No need to abort because the loading code will just ignore this + // empty dylib. + None + } + } +} + /// A diagnostic function for dumping crate metadata to an output stream. pub fn list_file_metadata(target: &Target, path: &Path, - cstore: &CStore, + metadata_loader: &dyn MetadataLoader, out: &mut dyn io::Write) -> io::Result<()> { let filename = path.file_name().unwrap().to_str().unwrap(); @@ -925,7 +1003,7 @@ pub fn list_file_metadata(target: &Target, } else { CrateFlavor::Dylib }; - match get_metadata_section(target, flavor, path, &*cstore.metadata_loader) { + match get_metadata_section(target, flavor, path, metadata_loader) { Ok(metadata) => metadata.list_crate_metadata(out), Err(msg) => write!(out, "{}\n", msg), } diff --git a/src/librustc_plugin/load.rs b/src/librustc_plugin/load.rs index 4481892bcf244..8ceb56b0fd2b4 100644 --- a/src/librustc_plugin/load.rs +++ b/src/librustc_plugin/load.rs @@ -1,8 +1,8 @@ //! Used by `rustc` when loading a plugin. +use rustc::middle::cstore::MetadataLoader; use rustc::session::Session; -use rustc_metadata::creader::CrateLoader; -use rustc_metadata::cstore::CStore; +use rustc_metadata::locator; use crate::registry::Registry; use std::borrow::ToOwned; @@ -25,7 +25,7 @@ pub struct PluginRegistrar { struct PluginLoader<'a> { sess: &'a Session, - reader: CrateLoader<'a>, + metadata_loader: &'a dyn MetadataLoader, plugins: Vec, } @@ -37,11 +37,10 @@ fn call_malformed_plugin_attribute(sess: &Session, span: Span) { /// Read plugin metadata and dynamically load registrar functions. pub fn load_plugins(sess: &Session, - cstore: &CStore, + metadata_loader: &dyn MetadataLoader, krate: &ast::Crate, - crate_name: &str, addl_plugins: Option>) -> Vec { - let mut loader = PluginLoader::new(sess, cstore, crate_name); + let mut loader = PluginLoader { sess, metadata_loader, plugins: Vec::new() }; // do not report any error now. since crate attributes are // not touched by expansion, every use of plugin without @@ -80,16 +79,8 @@ pub fn load_plugins(sess: &Session, } impl<'a> PluginLoader<'a> { - fn new(sess: &'a Session, cstore: &'a CStore, crate_name: &str) -> Self { - PluginLoader { - sess, - reader: CrateLoader::new(sess, cstore, crate_name), - plugins: vec![], - } - } - fn load_plugin(&mut self, span: Span, name: Symbol, args: Vec) { - let registrar = self.reader.find_plugin_registrar(span, name); + let registrar = locator::find_plugin_registrar(self.sess, self.metadata_loader, span, name); if let Some((lib, disambiguator)) = registrar { let symbol = self.sess.generate_plugin_registrar_symbol(disambiguator); diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 6444a82fd7379..c0fb8e33a819e 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -110,9 +110,9 @@ impl<'a> Resolver<'a> { } let (name, parent) = if def_id.index == CRATE_DEF_INDEX { - (self.cstore.crate_name_untracked(def_id.krate), None) + (self.cstore().crate_name_untracked(def_id.krate), None) } else { - let def_key = self.cstore.def_key(def_id); + let def_key = self.cstore().def_key(def_id); (def_key.disambiguated_data.data.get_opt_name().unwrap(), Some(self.get_module(DefId { index: def_key.parent.unwrap(), ..def_id }))) }; @@ -153,9 +153,8 @@ impl<'a> Resolver<'a> { return Some(ext.clone()); } - let ext = Lrc::new(match self.cstore.load_macro_untracked(def_id, &self.session) { - LoadedMacro::MacroDef(item) => - self.compile_macro(&item, self.cstore.crate_edition_untracked(def_id.krate)), + let ext = Lrc::new(match self.cstore().load_macro_untracked(def_id, &self.session) { + LoadedMacro::MacroDef(item, edition) => self.compile_macro(&item, edition), LoadedMacro::ProcMacro(ext) => ext, }); @@ -177,7 +176,7 @@ impl<'a> Resolver<'a> { crate fn build_reduced_graph_external(&mut self, module: Module<'a>) { let def_id = module.def_id().expect("unpopulated module without a def-id"); - for child in self.cstore.item_children_untracked(def_id, self.session) { + for child in self.cstore().item_children_untracked(def_id, self.session) { let child = child.map_id(|_| panic!("unexpected id")); BuildReducedGraphVisitor { r: self, parent_scope: ParentScope::module(module) } .build_reduced_graph_for_external_crate_res(child); @@ -885,19 +884,19 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { bug!("unexpected resolution: {:?}", res) } // Record some extra data for better diagnostics. + let cstore = self.r.cstore(); match res { Res::Def(DefKind::Struct, def_id) | Res::Def(DefKind::Union, def_id) => { - let field_names = - self.r.cstore.struct_field_names_untracked(def_id, self.r.session); + let field_names = cstore.struct_field_names_untracked(def_id, self.r.session); self.insert_field_names(def_id, field_names); } Res::Def(DefKind::Method, def_id) => { - if self.r.cstore.associated_item_cloned_untracked(def_id).method_has_self_argument { + if cstore.associated_item_cloned_untracked(def_id).method_has_self_argument { self.r.has_self.insert(def_id); } } Res::Def(DefKind::Ctor(CtorOf::Struct, ..), def_id) => { - let parent = self.r.cstore.def_key(def_id).parent; + let parent = cstore.def_key(def_id).parent; if let Some(struct_def_id) = parent.map(|index| DefId { index, ..def_id }) { self.r.struct_constructors.insert(struct_def_id, (res, vis)); } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 17d8f0f211a92..1c67395fbf0b2 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -21,14 +21,14 @@ use Determinacy::*; use rustc::hir::map::Definitions; use rustc::hir::{self, PrimTy, Bool, Char, Float, Int, Uint, Str}; -use rustc::middle::cstore::CrateStore; +use rustc::middle::cstore::{CrateStore, MetadataLoaderDyn}; use rustc::session::Session; use rustc::lint; use rustc::hir::def::{self, DefKind, PartialRes, CtorKind, CtorOf, NonMacroAttrKind, ExportMap}; use rustc::hir::def::Namespace::*; use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefId}; use rustc::hir::{TraitMap, GlobMap}; -use rustc::ty::{self, DefIdTree}; +use rustc::ty::{self, DefIdTree, ResolverOutputs}; use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap}; use rustc::span_bug; @@ -829,14 +829,13 @@ pub struct ExternPreludeEntry<'a> { /// This is the visitor that walks the whole crate. pub struct Resolver<'a> { session: &'a Session, - cstore: &'a CStore, - pub definitions: Definitions, + definitions: Definitions, - pub graph_root: Module<'a>, + graph_root: Module<'a>, prelude: Option>, - pub extern_prelude: FxHashMap>, + extern_prelude: FxHashMap>, /// N.B., this is used only for better diagnostics, not name resolution itself. has_self: FxHashSet, @@ -869,9 +868,9 @@ pub struct Resolver<'a> { label_res_map: NodeMap, /// `CrateNum` resolutions of `extern crate` items. - pub extern_crate_map: NodeMap, - pub export_map: ExportMap, - pub trait_map: TraitMap, + extern_crate_map: NodeMap, + export_map: ExportMap, + trait_map: TraitMap, /// A map from nodes to anonymous modules. /// Anonymous modules are pseudo-modules that are implicitly created around items @@ -898,11 +897,11 @@ pub struct Resolver<'a> { underscore_disambiguator: u32, /// Maps glob imports to the names of items actually imported. - pub glob_map: GlobMap, + glob_map: GlobMap, used_imports: FxHashSet<(NodeId, Namespace)>, - pub maybe_unused_trait_imports: NodeSet, - pub maybe_unused_extern_crates: Vec<(NodeId, Span)>, + maybe_unused_trait_imports: NodeSet, + maybe_unused_extern_crates: Vec<(NodeId, Span)>, /// Privacy errors are delayed until the end in order to deduplicate them. privacy_errors: Vec>, @@ -916,11 +915,11 @@ pub struct Resolver<'a> { arenas: &'a ResolverArenas<'a>, dummy_binding: &'a NameBinding<'a>, - crate_loader: &'a CrateLoader<'a>, + crate_loader: CrateLoader<'a>, macro_names: FxHashSet, builtin_macros: FxHashMap, macro_use_prelude: FxHashMap>, - pub all_macros: FxHashMap, + all_macros: FxHashMap, macro_map: FxHashMap>, dummy_ext_bang: Lrc, dummy_ext_derive: Lrc, @@ -1015,7 +1014,7 @@ impl<'a, 'b> DefIdTree for &'a Resolver<'b> { fn parent(self, id: DefId) -> Option { match id.krate { LOCAL_CRATE => self.definitions.def_key(id.index).parent, - _ => self.cstore.def_key(id).parent, + _ => self.cstore().def_key(id).parent, }.map(|index| DefId { index, ..id }) } } @@ -1023,6 +1022,10 @@ impl<'a, 'b> DefIdTree for &'a Resolver<'b> { /// This interface is used through the AST→HIR step, to embed full paths into the HIR. After that /// the resolver is no longer needed as all the relevant information is inline. impl<'a> hir::lowering::Resolver for Resolver<'a> { + fn cstore(&self) -> &dyn CrateStore { + self.cstore() + } + fn resolve_str_path( &mut self, span: Span, @@ -1083,10 +1086,9 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> { impl<'a> Resolver<'a> { pub fn new(session: &'a Session, - cstore: &'a CStore, krate: &Crate, crate_name: &str, - crate_loader: &'a CrateLoader<'a>, + metadata_loader: &'a MetadataLoaderDyn, arenas: &'a ResolverArenas<'a>) -> Resolver<'a> { let root_def_id = DefId::local(CRATE_DEF_INDEX); @@ -1147,8 +1149,6 @@ impl<'a> Resolver<'a> { Resolver { session, - cstore, - definitions, // The outermost module has def ID 0; this is not reflected in the @@ -1202,7 +1202,7 @@ impl<'a> Resolver<'a> { vis: ty::Visibility::Public, }), - crate_loader, + crate_loader: CrateLoader::new(session, metadata_loader, crate_name), macro_names: FxHashSet::default(), builtin_macros: Default::default(), macro_use_prelude: FxHashMap::default(), @@ -1236,6 +1236,42 @@ impl<'a> Resolver<'a> { Default::default() } + pub fn into_outputs(self) -> ResolverOutputs { + ResolverOutputs { + definitions: self.definitions, + cstore: Box::new(self.crate_loader.into_cstore()), + extern_crate_map: self.extern_crate_map, + export_map: self.export_map, + trait_map: self.trait_map, + glob_map: self.glob_map, + maybe_unused_trait_imports: self.maybe_unused_trait_imports, + maybe_unused_extern_crates: self.maybe_unused_extern_crates, + extern_prelude: self.extern_prelude.iter().map(|(ident, entry)| { + (ident.name, entry.introduced_by_item) + }).collect(), + } + } + + pub fn clone_outputs(&self) -> ResolverOutputs { + ResolverOutputs { + definitions: self.definitions.clone(), + cstore: Box::new(self.cstore().clone()), + extern_crate_map: self.extern_crate_map.clone(), + export_map: self.export_map.clone(), + trait_map: self.trait_map.clone(), + glob_map: self.glob_map.clone(), + maybe_unused_trait_imports: self.maybe_unused_trait_imports.clone(), + maybe_unused_extern_crates: self.maybe_unused_extern_crates.clone(), + extern_prelude: self.extern_prelude.iter().map(|(ident, entry)| { + (ident.name, entry.introduced_by_item) + }).collect(), + } + } + + pub fn cstore(&self) -> &CStore { + self.crate_loader.cstore() + } + fn non_macro_attr(&self, mark_used: bool) -> Lrc { self.non_macro_attrs[mark_used as usize].clone() } @@ -2808,6 +2844,16 @@ impl<'a> Resolver<'a> { seg.id = self.session.next_node_id(); seg } + + // For rustdoc. + pub fn graph_root(&self) -> Module<'a> { + self.graph_root + } + + // For rustdoc. + pub fn all_macros(&self) -> &FxHashMap { + &self.all_macros + } } fn names_to_string(names: &[Name]) -> String { diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 34edd5eaf4fc7..31340ddd68372 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -1344,7 +1344,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { if res != Res::Err { if let Some(def_id) = res.opt_def_id() { if !def_id.is_local() { - this.cstore.export_macros_untracked(def_id.krate); + this.cstore().export_macros_untracked(def_id.krate); } } reexports.push(Export { diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index e7cc8b76e485d..a6a8fec429e20 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -479,8 +479,8 @@ fn build_static(cx: &DocContext<'_>, did: DefId, mutable: bool) -> clean::Static fn build_macro(cx: &DocContext<'_>, did: DefId, name: ast::Name) -> clean::ItemEnum { let imported_from = cx.tcx.original_crate_name(did.krate); - match cx.cstore.load_macro_untracked(did, cx.sess()) { - LoadedMacro::MacroDef(def) => { + match cx.enter_resolver(|r| r.cstore().load_macro_untracked(did, cx.sess())) { + LoadedMacro::MacroDef(def, _) => { let matchers: hir::HirVec = if let ast::ItemKind::MacroDef(ref def) = def.kind { let tts: Vec<_> = def.stream().into_trees().collect(); tts.chunks(4).map(|arm| arm[0].span()).collect() diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 39ab30e8ecfc7..b227f432a4e98 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -12,7 +12,6 @@ use rustc::util::nodemap::{FxHashMap, FxHashSet}; use rustc_interface::interface; use rustc_driver::abort_on_err; use rustc_resolve as resolve; -use rustc_metadata::cstore::CStore; use syntax::source_map; use syntax::attr; @@ -43,7 +42,6 @@ pub struct DocContext<'tcx> { pub tcx: TyCtxt<'tcx>, pub resolver: Rc>, - pub cstore: Lrc, /// Later on moved into `html::render::CACHE_KEY` pub renderinfo: RefCell, /// Later on moved through `clean::Crate` into `html::render::CACHE_KEY` @@ -117,9 +115,7 @@ impl<'tcx> DocContext<'tcx> { .def_path_table() .next_id() } else { - self.cstore - .def_path_table(crate_num) - .next_id() + self.enter_resolver(|r| r.cstore().def_path_table(crate_num).next_id()) }; DefId { @@ -376,7 +372,6 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt let mut ctxt = DocContext { tcx, resolver, - cstore: compiler.cstore().clone(), external_traits: Default::default(), active_extern_traits: Default::default(), renderinfo: RefCell::new(renderinfo), diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 4270b162bafa4..caa7f08f68cff 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -432,13 +432,13 @@ fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option { let path = ast::Path::from_ident(Ident::from_str(path_str)); cx.enter_resolver(|resolver| { if let Ok((Some(ext), res)) = resolver.resolve_macro_path( - &path, None, &ParentScope::module(resolver.graph_root), false, false + &path, None, &ParentScope::module(resolver.graph_root()), false, false ) { if let SyntaxExtensionKind::LegacyBang { .. } = ext.kind { return Some(res.map_id(|_| panic!("unexpected id"))); } } - if let Some(res) = resolver.all_macros.get(&Symbol::intern(path_str)) { + if let Some(res) = resolver.all_macros().get(&Symbol::intern(path_str)) { return Some(res.map_id(|_| panic!("unexpected id"))); } None diff --git a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs index 1566a153ec03c..eb96c61060b39 100644 --- a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs +++ b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs @@ -9,14 +9,14 @@ extern crate rustc_target; extern crate rustc_driver; use std::any::Any; -use std::sync::{Arc, mpsc}; +use std::sync::Arc; use std::path::Path; use syntax::symbol::Symbol; use rustc::session::Session; use rustc::session::config::OutputFilenames; use rustc::ty::TyCtxt; use rustc::ty::query::Providers; -use rustc::middle::cstore::{EncodedMetadata, MetadataLoader}; +use rustc::middle::cstore::{EncodedMetadata, MetadataLoader, MetadataLoaderDyn}; use rustc::dep_graph::DepGraph; use rustc::util::common::ErrorReported; use rustc_codegen_utils::codegen_backend::CodegenBackend; @@ -41,7 +41,7 @@ impl MetadataLoader for NoLlvmMetadataLoader { struct TheBackend; impl CodegenBackend for TheBackend { - fn metadata_loader(&self) -> Box { + fn metadata_loader(&self) -> Box { Box::new(NoLlvmMetadataLoader) }