Rollup merge of #65625 - petrochenkov:cstore, r=Mark-Simulacrum,Zoxc

Turn crate store into a resolver output

Crate store (`CStore`) is a vector of data (`CrateMetadata`) associated with extern crates loaded during the current compilation session.

All crates are loaded in the resolver when resolving either paths pointing to extern prelude or `extern crate` items. (There are also a couple of crates like panic runtime that are loaded kind of like implicit `extern crate`s, but that also happens in resolve.)

The use of `CStore` from `rustc_plugin` (which is outside of the resolver) was unnecessary because legacy plugins are not added to the crate store and don't use `CrateNum`s.

So, `CStore` can be produced by the resolver instead of being kept in some really global data (`rustc_interface::Compiler`) like now.

As a result of crate store being more "local" we can now remove some locks and `Lrc`s.
This commit is contained in:
Mazdak Farrokhzad 2019-10-24 20:19:59 +02:00 committed by GitHub
commit cdb7634f0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 346 additions and 415 deletions

View File

@ -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<PartialRes>;
@ -240,7 +240,6 @@ fn reborrow(&'b mut self) -> ImplTraitContext<'b> {
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 @@ fn def_key(&mut self, id: DefId) -> DefKey {
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 @@ fn lower_qpath(
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

View File

@ -16,7 +16,7 @@
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 @@ fn get_dylib_metadata(&self,
-> Result<MetadataRef, String>;
}
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 @@ fn get_dylib_metadata(&self,
/// (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<dyn Any>;
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<DefPathTable>;
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;

View File

@ -1027,7 +1027,7 @@ pub struct GlobalCtxt<'tcx> {
interners: CtxtInterners<'tcx>,
cstore: &'tcx CrateStoreDyn,
cstore: Box<CrateStoreDyn>,
pub sess: &'tcx Session,
@ -1195,11 +1195,10 @@ pub fn lift<T: ?Sized + Lift<'tcx>>(self, value: &T) -> Option<T::Lifted> {
pub fn create_global_ctxt(
s: &'tcx Session,
lint_store: Lrc<lint::LintStore>,
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 @@ pub fn create_global_ctxt(
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::<usize>();
let capacity = def_path_tables.clone().map(|(_, t)| t.size()).sum::<usize>();
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 @@ pub fn encode_metadata(self)-> EncodedMetadata {
// 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<dyn Any> {
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 @@ pub fn create_stable_hashing_context(self) -> StableHashingContext<'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

View File

@ -15,6 +15,7 @@
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 @@
// Data types
#[derive(Clone)]
pub struct Resolutions {
pub struct ResolverOutputs {
pub definitions: hir_map::Definitions,
pub cstore: Box<CrateStoreDyn>,
pub extern_crate_map: NodeMap<CrateNum>,
pub trait_map: TraitMap,
pub maybe_unused_trait_imports: NodeSet,

View File

@ -56,7 +56,7 @@
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 @@ fn target_features(&self, sess: &Session) -> Vec<Symbol> {
target_features(sess)
}
fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync> {
fn metadata_loader(&self) -> Box<MetadataLoaderDyn> {
box metadata::LlvmMetadataLoader
}

View File

@ -14,7 +14,7 @@
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 @@ fn target_features(&self, _sess: &Session) -> Vec<Symbol> { vec![] }
fn print_passes(&self) {}
fn print_version(&self) {}
fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync>;
fn metadata_loader(&self) -> Box<MetadataLoaderDyn>;
fn provide(&self, _providers: &mut Providers<'_>);
fn provide_extern(&self, _providers: &mut Providers<'_>);
fn codegen_crate<'tcx>(

View File

@ -36,11 +36,11 @@
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 @@ pub fn list_metadata(sess: &Session,
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());

View File

@ -11,7 +11,6 @@
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<PathBuf>,
pub(crate) output_file: Option<PathBuf>,
pub(crate) queries: Queries,
pub(crate) cstore: Lrc<CStore>,
pub(crate) crate_name: Option<String>,
pub(crate) register_lints: Option<Box<dyn Fn(&Session, &mut lint::LintStore) + Send + Sync>>,
}
@ -49,9 +47,6 @@ pub fn session(&self) -> &Lrc<Session> {
pub fn codegen_backend(&self) -> &Lrc<Box<dyn CodegenBackend>> {
&self.codegen_backend
}
pub fn cstore(&self) -> &Lrc<CStore> {
&self.cstore
}
pub fn source_map(&self) -> &Lrc<SourceMap> {
&self.source_map
}
@ -160,13 +155,10 @@ pub fn run_compiler_in_existing_thread_pool<F, R>(config: Config, f: F) -> R
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,

View File

@ -9,8 +9,8 @@
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_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 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<ast::Crate>, ExpansionResult)
(&mut Resolver<'_>) -> (Result<ast::Crate>, ResolverOutputs)
);
/// Runs the "early phases" of the compiler: initial `cfg` processing,
@ -118,7 +115,7 @@ fn count_nodes(krate: &ast::Crate) -> usize {
pub fn configure_and_expand(
sess: Lrc<Session>,
lint_store: Lrc<lint::LintStore>,
cstore: Lrc<CStore>,
metadata_loader: Box<MetadataLoaderDyn>,
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<hir::map::Definitions>,
pub resolutions: Steal<Resolutions>,
}
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<RefCell<BoxedResolver>>,
) -> ExpansionResult {
pub fn to_resolver_outputs(resolver: Rc<RefCell<BoxedResolver>>) -> 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<Rc<RefCell<BoxedResolver>>>,
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<Rc<RefCell<BoxedResolver>>>,
crate_name: &str
) -> Result<OutputFilenames> {
// 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<lint::LintStore>,
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<GlobalCtxt<'_>>;
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,

View File

@ -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::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<LintStore>)>,
expansion: Query<(ast::Crate, Steal<Rc<RefCell<BoxedResolver>>>, Lrc<LintStore>)>,
dep_graph: Query<DepGraph>,
lower_to_hir: Query<(Steal<hir::map::Forest>, ExpansionResult)>,
lower_to_hir: Query<(Steal<hir::map::Forest>, Steal<ResolverOutputs>)>,
prepare_outputs: Query<OutputFilenames>,
global_ctxt: Query<BoxedGlobalCtxt>,
ongoing_codegen: Query<Box<dyn Any>>,
@ -118,7 +119,7 @@ pub fn register_plugins(&self) -> Result<&Query<(ast::Crate, PluginInfo, Lrc<Lin
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 @@ pub fn expansion(
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 @@ pub fn dep_graph(&self) -> Result<&Query<DepGraph>> {
})
}
pub fn lower_to_hir(&self) -> Result<&Query<(Steal<hir::map::Forest>, ExpansionResult)>> {
pub fn lower_to_hir(
&self,
) -> Result<&Query<(Steal<hir::map::Forest>, Steal<ResolverOutputs>)>> {
self.queries.lower_to_hir.compute(|| {
let expansion_result = self.expansion()?;
let peeked = expansion_result.peek();
@ -202,23 +205,22 @@ pub fn lower_to_hir(&self) -> Result<&Query<(Steal<hir::map::Forest>, ExpansionR
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<OutputFilenames>> {
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 @@ pub fn global_ctxt(&self) -> Result<&Query<BoxedGlobalCtxt>> {
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))
})

View File

@ -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::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 @@
}
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<PathBuf>,
target_only: bool,
}
enum PMDSource {
Registered(Lrc<cstore::CrateMetadata>),
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 @@ fn report(self) -> ! {
}
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<CrateNum> {
let mut ret = None;
@ -187,14 +179,14 @@ fn verify_no_symbol_conflicts(&self,
}
fn register_crate(
&self,
&mut self,
host_lib: Option<Library>,
root: Option<&CratePaths>,
span: Span,
lib: Library,
dep_kind: DepKind,
name: Symbol
) -> (CrateNum, Lrc<cstore::CrateMetadata>) {
) -> CrateNum {
let _prof_timer = self.sess.prof.generic_activity("metadata_register_crate");
let Library { source, metadata } = lib;
@ -248,9 +240,9 @@ fn register_crate(
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 @@ fn register_crate(
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 @@ fn load_proc_macro<'b>(
}
fn resolve_crate<'b>(
&'b self,
&'b mut self,
name: Symbol,
span: Span,
dep_kind: DepKind,
dep: Option<(&'b CratePaths, &'b CrateDep)>,
) -> (CrateNum, Lrc<cstore::CrateMetadata>) {
) -> 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<cstore::CrateMetadata>), LoadError<'b>> {
) -> Result<CrateNum, LoadError<'b>> {
info!("resolving crate `{}`", name);
let (root, hash, extra_filename, path_kind) = match dep {
Some((root, dep)) =>
@ -370,7 +360,7 @@ fn maybe_resolve_crate<'b>(
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 @@ fn maybe_resolve_crate<'b>(
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 @@ fn update_extern_crate(&self,
}
// 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 @@ fn resolve_crate_deps(&self,
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 @@ fn dlsym_proc_macros(&self,
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 @@ fn inject_panic_runtime(&self, krate: &ast::Crate) {
};
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 @@ fn inject_panic_runtime(&self, krate: &ast::Crate) {
&|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 @@ fn inject_sanitizer_runtime(&self) {
});
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 @@ fn inject_sanitizer_runtime(&self) {
}
}
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 @@ fn inject_dependency_if(&self,
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 @@ pub fn postprocess(&self, krate: &ast::Crate) {
}
}
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 @@ pub fn process_extern_crate(&self, item: &ast::Item, definitions: &Definitions)
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 @@ pub fn process_extern_crate(&self, item: &ast::Item, definitions: &Definitions)
}
}
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 @@ pub fn process_path_extern(&self, name: Symbol, span: Span) -> CrateNum {
cnum
}
pub fn maybe_process_path_extern(&self, name: Symbol, span: Span) -> Option<CrateNum> {
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<CrateNum> {
let cnum = self.maybe_resolve_crate(name, span, DepKind::Explicit, None).ok()?;
self.update_extern_crate(
cnum,

View File

@ -5,12 +5,13 @@
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 @@
pub translated_source_file: Lrc<syntax_pos::SourceFile>,
}
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<DefPathTable>,
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<Option<ExternCrate>>,
}
#[derive(Clone)]
pub struct CStore {
metas: RwLock<IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>>,
crate metadata_loader: Box<dyn MetadataLoader + Sync>,
metas: IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>,
}
pub enum LoadedMacro {
MacroDef(ast::Item),
MacroDef(ast::Item, Edition),
ProcMacro(SyntaxExtension),
}
impl CStore {
pub fn new(metadata_loader: Box<dyn MetadataLoader + Sync>) -> 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<CrateMetadata> {
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<CrateMetadata>) {
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<I>(&self, mut i: I)
where I: FnMut(CrateNum, &Lrc<CrateMetadata>)
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 @@ pub fn new(metadata_loader: Box<dyn MetadataLoader + Sync>) -> CStore {
crate fn do_postorder_cnums_untracked(&self) -> Vec<CrateNum> {
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);
}

View File

@ -29,7 +29,6 @@
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 @@ pub fn provide_extern<$lt>(providers: &mut Providers<$lt>) {
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::<cstore::CrateMetadata>()
.expect("CrateStore created data is not a CrateMetadata");
@ -411,10 +410,6 @@ pub fn export_macros_untracked(&self, cnum: CrateNum) {
}
}
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<Spanned<Symbol>> {
self.get_crate_data(def.krate).get_struct_field_names(def.index, sess)
}
@ -470,7 +465,7 @@ pub fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro {
}),
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 @@ pub fn crate_source_untracked(&self, cnum: CrateNum) -> CrateSource {
}
impl CrateStore for cstore::CStore {
fn crate_data_as_rc_any(&self, krate: CrateNum) -> Lrc<dyn Any> {
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 @@ fn def_path_hash(&self, def: DefId) -> DefPathHash {
self.get_crate_data(def.krate).def_path_hash(def.index)
}
fn def_path_table(&self, cnum: CrateNum) -> Lrc<DefPathTable> {
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<CrateNum>

View File

@ -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::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),
}

View File

@ -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<PluginRegistrar>,
}
@ -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<String>>) -> Vec<PluginRegistrar> {
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<ast::NestedMetaItem>) {
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);

View File

@ -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 @@ fn build_reduced_graph_for_external_crate_res(&mut self, child: Export<NodeId>)
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));
}

View File

@ -21,14 +21,14 @@
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<Module<'a>>,
pub extern_prelude: FxHashMap<Ident, ExternPreludeEntry<'a>>,
extern_prelude: FxHashMap<Ident, ExternPreludeEntry<'a>>,
/// N.B., this is used only for better diagnostics, not name resolution itself.
has_self: FxHashSet<DefId>,
@ -869,9 +868,9 @@ pub struct Resolver<'a> {
label_res_map: NodeMap<NodeId>,
/// `CrateNum` resolutions of `extern crate` items.
pub extern_crate_map: NodeMap<CrateNum>,
pub export_map: ExportMap<NodeId>,
pub trait_map: TraitMap,
extern_crate_map: NodeMap<CrateNum>,
export_map: ExportMap<NodeId>,
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<PrivacyError<'a>>,
@ -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<Ident>,
builtin_macros: FxHashMap<Name, SyntaxExtension>,
macro_use_prelude: FxHashMap<Name, &'a NameBinding<'a>>,
pub all_macros: FxHashMap<Name, Res>,
all_macros: FxHashMap<Name, Res>,
macro_map: FxHashMap<DefId, Lrc<SyntaxExtension>>,
dummy_ext_bang: Lrc<SyntaxExtension>,
dummy_ext_derive: Lrc<SyntaxExtension>,
@ -1015,7 +1014,7 @@ impl<'a, 'b> DefIdTree for &'a Resolver<'b> {
fn parent(self, id: DefId) -> Option<DefId> {
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 @@ fn parent(self, id: DefId) -> Option<DefId> {
/// 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 @@ fn has_derives(&self, node_id: NodeId, derives: SpecialDerives) -> bool {
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 @@ pub fn new(session: &'a Session,
Resolver {
session,
cstore,
definitions,
// The outermost module has def ID 0; this is not reflected in the
@ -1202,7 +1202,7 @@ pub fn new(session: &'a Session,
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 @@ pub fn arenas() -> ResolverArenas<'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<SyntaxExtension> {
self.non_macro_attrs[mark_used as usize].clone()
}
@ -2808,6 +2844,16 @@ fn new_ast_path_segment(&self, ident: Ident) -> ast::PathSegment {
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<Name, Res> {
&self.all_macros
}
}
fn names_to_string(names: &[Name]) -> String {

View File

@ -1344,7 +1344,7 @@ fn finalize_resolutions_in(&mut self, module: Module<'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 {

View File

@ -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<Span> = 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()

View File

@ -12,7 +12,6 @@
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<RefCell<interface::BoxedResolver>>,
pub cstore: Lrc<CStore>,
/// Later on moved into `html::render::CACHE_KEY`
pub renderinfo: RefCell<RenderInfo>,
/// Later on moved through `clean::Crate` into `html::render::CACHE_KEY`
@ -117,9 +115,7 @@ pub fn next_def_id(&self, crate_num: CrateNum) -> DefId {
.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),

View File

@ -432,13 +432,13 @@ fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option<Res> {
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

View File

@ -9,14 +9,14 @@
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 @@ fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result<Metadat
struct TheBackend;
impl CodegenBackend for TheBackend {
fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync> {
fn metadata_loader(&self) -> Box<MetadataLoaderDyn> {
Box::new(NoLlvmMetadataLoader)
}