rustc_interface: Dismantle register_plugins
query
This commit is contained in:
parent
adb15a20ac
commit
b6ac576487
5 changed files with 119 additions and 132 deletions
|
@ -32,7 +32,7 @@ use rustc_feature::find_gated_cfg;
|
|||
use rustc_fluent_macro::fluent_messages;
|
||||
use rustc_interface::util::{self, collect_crate_types, get_codegen_backend};
|
||||
use rustc_interface::{interface, Queries};
|
||||
use rustc_lint::LintStore;
|
||||
use rustc_lint::{unerased_lint_store, LintStore};
|
||||
use rustc_metadata::locator;
|
||||
use rustc_session::config::{nightly_options, CG_OPTIONS, Z_OPTIONS};
|
||||
use rustc_session::config::{ErrorOutputType, Input, OutFileName, OutputType, TrimmedDefPaths};
|
||||
|
@ -411,15 +411,11 @@ fn run_compiler(
|
|||
return early_exit();
|
||||
}
|
||||
|
||||
{
|
||||
let plugins = queries.register_plugins()?;
|
||||
let (.., lint_store) = &*plugins.borrow();
|
||||
|
||||
// Lint plugins are registered; now we can process command line flags.
|
||||
if sess.opts.describe_lints {
|
||||
describe_lints(sess, lint_store, true);
|
||||
return early_exit();
|
||||
}
|
||||
if sess.opts.describe_lints {
|
||||
queries
|
||||
.global_ctxt()?
|
||||
.enter(|tcx| describe_lints(sess, unerased_lint_store(tcx), true));
|
||||
return early_exit();
|
||||
}
|
||||
|
||||
// Make sure name resolution and macro expansion is run.
|
||||
|
|
|
@ -12,7 +12,7 @@ use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
|
|||
use rustc_errors::PResult;
|
||||
use rustc_expand::base::{ExtCtxt, LintStoreExpand};
|
||||
use rustc_fs_util::try_canonicalize;
|
||||
use rustc_hir::def_id::{StableCrateId, LOCAL_CRATE};
|
||||
use rustc_hir::def_id::LOCAL_CRATE;
|
||||
use rustc_lint::{unerased_lint_store, BufferedEarlyLint, EarlyCheckNode, LintStore};
|
||||
use rustc_metadata::creader::CStore;
|
||||
use rustc_middle::arena::Arena;
|
||||
|
@ -72,43 +72,16 @@ fn count_nodes(krate: &ast::Crate) -> usize {
|
|||
counter.count
|
||||
}
|
||||
|
||||
pub fn register_plugins<'a>(
|
||||
sess: &'a Session,
|
||||
metadata_loader: &'a dyn MetadataLoader,
|
||||
register_lints: impl Fn(&Session, &mut LintStore),
|
||||
pub(crate) fn create_lint_store(
|
||||
sess: &Session,
|
||||
metadata_loader: &dyn MetadataLoader,
|
||||
register_lints: Option<impl Fn(&Session, &mut LintStore)>,
|
||||
pre_configured_attrs: &[ast::Attribute],
|
||||
crate_name: Symbol,
|
||||
) -> Result<LintStore> {
|
||||
// these need to be set "early" so that expansion sees `quote` if enabled.
|
||||
let features = rustc_expand::config::features(sess, pre_configured_attrs);
|
||||
sess.init_features(features);
|
||||
|
||||
let crate_types = util::collect_crate_types(sess, pre_configured_attrs);
|
||||
sess.init_crate_types(crate_types);
|
||||
|
||||
let stable_crate_id = StableCrateId::new(
|
||||
crate_name,
|
||||
sess.crate_types().contains(&CrateType::Executable),
|
||||
sess.opts.cg.metadata.clone(),
|
||||
sess.cfg_version,
|
||||
);
|
||||
sess.stable_crate_id.set(stable_crate_id).expect("not yet initialized");
|
||||
rustc_incremental::prepare_session_directory(sess, crate_name, stable_crate_id)?;
|
||||
|
||||
if sess.opts.incremental.is_some() {
|
||||
sess.time("incr_comp_garbage_collect_session_directories", || {
|
||||
if let Err(e) = rustc_incremental::garbage_collect_session_directories(sess) {
|
||||
warn!(
|
||||
"Error while trying to garbage collect incremental \
|
||||
compilation cache directory: {}",
|
||||
e
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
) -> LintStore {
|
||||
let mut lint_store = rustc_lint::new_lint_store(sess.enable_internal_lints());
|
||||
register_lints(sess, &mut lint_store);
|
||||
if let Some(register_lints) = register_lints {
|
||||
register_lints(sess, &mut lint_store);
|
||||
}
|
||||
|
||||
let registrars = sess.time("plugin_loading", || {
|
||||
plugin::load::load_plugins(sess, metadata_loader, pre_configured_attrs)
|
||||
|
@ -120,7 +93,7 @@ pub fn register_plugins<'a>(
|
|||
}
|
||||
});
|
||||
|
||||
Ok(lint_store)
|
||||
lint_store
|
||||
}
|
||||
|
||||
fn pre_expansion_lint<'a>(
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::errors::{FailedWritingFile, RustcErrorFatal, RustcErrorUnexpectedAnnotation};
|
||||
use crate::interface::{Compiler, Result};
|
||||
use crate::passes;
|
||||
use crate::{passes, util};
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_codegen_ssa::traits::CodegenBackend;
|
||||
|
@ -9,15 +9,14 @@ use rustc_data_structures::fx::FxIndexMap;
|
|||
use rustc_data_structures::steal::Steal;
|
||||
use rustc_data_structures::svh::Svh;
|
||||
use rustc_data_structures::sync::{AppendOnlyIndexVec, Lrc, OnceCell, RwLock, WorkerLocal};
|
||||
use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE};
|
||||
use rustc_hir::def_id::{StableCrateId, CRATE_DEF_ID, LOCAL_CRATE};
|
||||
use rustc_hir::definitions::Definitions;
|
||||
use rustc_incremental::DepGraphFuture;
|
||||
use rustc_lint::LintStore;
|
||||
use rustc_metadata::creader::CStore;
|
||||
use rustc_middle::arena::Arena;
|
||||
use rustc_middle::dep_graph::DepGraph;
|
||||
use rustc_middle::ty::{GlobalCtxt, TyCtxt};
|
||||
use rustc_session::config::{self, OutputFilenames, OutputType};
|
||||
use rustc_session::config::{self, CrateType, OutputFilenames, OutputType};
|
||||
use rustc_session::cstore::Untracked;
|
||||
use rustc_session::{output::find_crate_name, Session};
|
||||
use rustc_span::symbol::sym;
|
||||
|
@ -85,12 +84,11 @@ pub struct Queries<'tcx> {
|
|||
arena: WorkerLocal<Arena<'tcx>>,
|
||||
hir_arena: WorkerLocal<rustc_hir::Arena<'tcx>>,
|
||||
|
||||
dep_graph_future: Query<Option<DepGraphFuture>>,
|
||||
parse: Query<ast::Crate>,
|
||||
pre_configure: Query<(ast::Crate, ast::AttrVec)>,
|
||||
crate_name: Query<Symbol>,
|
||||
register_plugins: Query<(ast::Crate, ast::AttrVec, Lrc<LintStore>)>,
|
||||
dep_graph: Query<DepGraph>,
|
||||
crate_types: Query<Vec<CrateType>>,
|
||||
stable_crate_id: Query<StableCrateId>,
|
||||
// This just points to what's in `gcx_cell`.
|
||||
gcx: Query<&'tcx GlobalCtxt<'tcx>>,
|
||||
}
|
||||
|
@ -102,12 +100,11 @@ impl<'tcx> Queries<'tcx> {
|
|||
gcx_cell: OnceCell::new(),
|
||||
arena: WorkerLocal::new(|_| Arena::default()),
|
||||
hir_arena: WorkerLocal::new(|_| rustc_hir::Arena::default()),
|
||||
dep_graph_future: Default::default(),
|
||||
parse: Default::default(),
|
||||
pre_configure: Default::default(),
|
||||
crate_name: Default::default(),
|
||||
register_plugins: Default::default(),
|
||||
dep_graph: Default::default(),
|
||||
crate_types: Default::default(),
|
||||
stable_crate_id: Default::default(),
|
||||
gcx: Default::default(),
|
||||
}
|
||||
}
|
||||
|
@ -119,13 +116,6 @@ impl<'tcx> Queries<'tcx> {
|
|||
self.compiler.codegen_backend()
|
||||
}
|
||||
|
||||
fn dep_graph_future(&self) -> Result<QueryResult<'_, Option<DepGraphFuture>>> {
|
||||
self.dep_graph_future.compute(|| {
|
||||
let sess = self.session();
|
||||
Ok(sess.opts.build_dep_graph().then(|| rustc_incremental::load_dep_graph(sess)))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn parse(&self) -> Result<QueryResult<'_, ast::Crate>> {
|
||||
self.parse
|
||||
.compute(|| passes::parse(self.session()).map_err(|mut parse_error| parse_error.emit()))
|
||||
|
@ -148,84 +138,111 @@ impl<'tcx> Queries<'tcx> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn register_plugins(
|
||||
&self,
|
||||
) -> Result<QueryResult<'_, (ast::Crate, ast::AttrVec, Lrc<LintStore>)>> {
|
||||
self.register_plugins.compute(|| {
|
||||
let crate_name = *self.crate_name()?.borrow();
|
||||
let (krate, pre_configured_attrs) = self.pre_configure()?.steal();
|
||||
|
||||
let empty: &(dyn Fn(&Session, &mut LintStore) + Sync + Send) = &|_, _| {};
|
||||
let lint_store = passes::register_plugins(
|
||||
self.session(),
|
||||
&*self.codegen_backend().metadata_loader(),
|
||||
self.compiler.register_lints.as_deref().unwrap_or_else(|| empty),
|
||||
&pre_configured_attrs,
|
||||
crate_name,
|
||||
)?;
|
||||
|
||||
// Compute the dependency graph (in the background). We want to do
|
||||
// this as early as possible, to give the DepGraph maximum time to
|
||||
// load before dep_graph() is called, but it also can't happen
|
||||
// until after rustc_incremental::prepare_session_directory() is
|
||||
// called, which happens within passes::register_plugins().
|
||||
self.dep_graph_future().ok();
|
||||
|
||||
Ok((krate, pre_configured_attrs, Lrc::new(lint_store)))
|
||||
})
|
||||
}
|
||||
|
||||
fn crate_name(&self) -> Result<QueryResult<'_, Symbol>> {
|
||||
self.crate_name.compute(|| {
|
||||
Ok({
|
||||
let pre_configure_result = self.pre_configure()?;
|
||||
let (_, pre_configured_attrs) = &*pre_configure_result.borrow();
|
||||
// parse `#[crate_name]` even if `--crate-name` was passed, to make sure it matches.
|
||||
find_crate_name(self.session(), pre_configured_attrs)
|
||||
})
|
||||
let pre_configure_result = self.pre_configure()?;
|
||||
let (_, pre_configured_attrs) = &*pre_configure_result.borrow();
|
||||
// parse `#[crate_name]` even if `--crate-name` was passed, to make sure it matches.
|
||||
Ok(find_crate_name(self.session(), pre_configured_attrs))
|
||||
})
|
||||
}
|
||||
|
||||
fn dep_graph(&self) -> Result<QueryResult<'_, DepGraph>> {
|
||||
self.dep_graph.compute(|| {
|
||||
let sess = self.session();
|
||||
let future_opt = self.dep_graph_future()?.steal();
|
||||
let dep_graph = future_opt
|
||||
.and_then(|future| {
|
||||
let (prev_graph, mut prev_work_products) =
|
||||
sess.time("blocked_on_dep_graph_loading", || future.open().open(sess));
|
||||
// Convert from UnordMap to FxIndexMap by sorting
|
||||
let prev_work_product_ids =
|
||||
prev_work_products.items().map(|x| *x.0).into_sorted_stable_ord();
|
||||
let prev_work_products = prev_work_product_ids
|
||||
.into_iter()
|
||||
.map(|x| (x, prev_work_products.remove(&x).unwrap()))
|
||||
.collect::<FxIndexMap<_, _>>();
|
||||
rustc_incremental::build_dep_graph(sess, prev_graph, prev_work_products)
|
||||
})
|
||||
.unwrap_or_else(DepGraph::new_disabled);
|
||||
Ok(dep_graph)
|
||||
fn crate_types(&self) -> Result<QueryResult<'_, Vec<CrateType>>> {
|
||||
self.crate_types.compute(|| {
|
||||
let pre_configure_result = self.pre_configure()?;
|
||||
let (_, pre_configured_attrs) = &*pre_configure_result.borrow();
|
||||
Ok(util::collect_crate_types(&self.session(), &pre_configured_attrs))
|
||||
})
|
||||
}
|
||||
|
||||
fn stable_crate_id(&self) -> Result<QueryResult<'_, StableCrateId>> {
|
||||
self.stable_crate_id.compute(|| {
|
||||
let sess = self.session();
|
||||
Ok(StableCrateId::new(
|
||||
*self.crate_name()?.borrow(),
|
||||
self.crate_types()?.borrow().contains(&CrateType::Executable),
|
||||
sess.opts.cg.metadata.clone(),
|
||||
sess.cfg_version,
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
fn dep_graph_future(&self) -> Result<Option<DepGraphFuture>> {
|
||||
let sess = self.session();
|
||||
let crate_name = *self.crate_name()?.borrow();
|
||||
let stable_crate_id = *self.stable_crate_id()?.borrow();
|
||||
|
||||
// `load_dep_graph` can only be called after `prepare_session_directory`.
|
||||
rustc_incremental::prepare_session_directory(sess, crate_name, stable_crate_id)?;
|
||||
let res = sess.opts.build_dep_graph().then(|| rustc_incremental::load_dep_graph(sess));
|
||||
|
||||
if sess.opts.incremental.is_some() {
|
||||
sess.time("incr_comp_garbage_collect_session_directories", || {
|
||||
if let Err(e) = rustc_incremental::garbage_collect_session_directories(sess) {
|
||||
warn!(
|
||||
"Error while trying to garbage collect incremental \
|
||||
compilation cache directory: {}",
|
||||
e
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
fn dep_graph(&self, dep_graph_future: Option<DepGraphFuture>) -> DepGraph {
|
||||
dep_graph_future
|
||||
.and_then(|future| {
|
||||
let sess = self.session();
|
||||
let (prev_graph, mut prev_work_products) =
|
||||
sess.time("blocked_on_dep_graph_loading", || future.open().open(sess));
|
||||
// Convert from UnordMap to FxIndexMap by sorting
|
||||
let prev_work_product_ids =
|
||||
prev_work_products.items().map(|x| *x.0).into_sorted_stable_ord();
|
||||
let prev_work_products = prev_work_product_ids
|
||||
.into_iter()
|
||||
.map(|x| (x, prev_work_products.remove(&x).unwrap()))
|
||||
.collect::<FxIndexMap<_, _>>();
|
||||
rustc_incremental::build_dep_graph(sess, prev_graph, prev_work_products)
|
||||
})
|
||||
.unwrap_or_else(DepGraph::new_disabled)
|
||||
}
|
||||
|
||||
pub fn global_ctxt(&'tcx self) -> Result<QueryResult<'_, &'tcx GlobalCtxt<'tcx>>> {
|
||||
self.gcx.compute(|| {
|
||||
let crate_name = *self.crate_name()?.borrow();
|
||||
let (krate, pre_configured_attrs, lint_store) = self.register_plugins()?.steal();
|
||||
// Compute the dependency graph (in the background). We want to do this as early as
|
||||
// possible, to give the DepGraph maximum time to load before `dep_graph` is called.
|
||||
let dep_graph_future = self.dep_graph_future()?;
|
||||
|
||||
let crate_name = self.crate_name()?.steal();
|
||||
let crate_types = self.crate_types()?.steal();
|
||||
let stable_crate_id = self.stable_crate_id()?.steal();
|
||||
let (krate, pre_configured_attrs) = self.pre_configure()?.steal();
|
||||
|
||||
let sess = self.session();
|
||||
|
||||
let cstore = RwLock::new(Box::new(CStore::new(sess)) as _);
|
||||
let definitions = RwLock::new(Definitions::new(sess.local_stable_crate_id()));
|
||||
let lint_store = Lrc::new(passes::create_lint_store(
|
||||
sess,
|
||||
&*self.codegen_backend().metadata_loader(),
|
||||
self.compiler.register_lints.as_deref(),
|
||||
&pre_configured_attrs,
|
||||
));
|
||||
let cstore = RwLock::new(Box::new(CStore::new(stable_crate_id)) as _);
|
||||
let definitions = RwLock::new(Definitions::new(stable_crate_id));
|
||||
let source_span = AppendOnlyIndexVec::new();
|
||||
let _id = source_span.push(krate.spans.inner_span);
|
||||
debug_assert_eq!(_id, CRATE_DEF_ID);
|
||||
let untracked = Untracked { cstore, source_span, definitions };
|
||||
|
||||
// FIXME: Move these fields from session to tcx and make them immutable.
|
||||
sess.init_crate_types(crate_types);
|
||||
sess.stable_crate_id.set(stable_crate_id).expect("not yet initialized");
|
||||
sess.init_features(rustc_expand::config::features(sess, &pre_configured_attrs));
|
||||
|
||||
let qcx = passes::create_global_ctxt(
|
||||
self.compiler,
|
||||
lint_store,
|
||||
self.dep_graph()?.steal(),
|
||||
self.dep_graph(dep_graph_future),
|
||||
untracked,
|
||||
&self.gcx_cell,
|
||||
&self.arena,
|
||||
|
|
|
@ -20,7 +20,6 @@ use rustc_session::cstore::{CrateDepKind, CrateSource, ExternCrate};
|
|||
use rustc_session::lint;
|
||||
use rustc_session::output::validate_crate_name;
|
||||
use rustc_session::search_paths::PathKind;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
@ -262,9 +261,9 @@ impl CStore {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn new(sess: &Session) -> CStore {
|
||||
pub fn new(local_stable_crate_id: StableCrateId) -> CStore {
|
||||
let mut stable_crate_ids = StableCrateIdMap::default();
|
||||
stable_crate_ids.insert(sess.local_stable_crate_id(), LOCAL_CRATE);
|
||||
stable_crate_ids.insert(local_stable_crate_id, LOCAL_CRATE);
|
||||
CStore {
|
||||
// We add an empty entry for LOCAL_CRATE (which maps to zero) in
|
||||
// order to make array indices in `metas` match with the
|
||||
|
@ -544,6 +543,9 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
|
|||
self.sess,
|
||||
&**metadata_loader,
|
||||
name,
|
||||
// The all loop is because `--crate-type=rlib --crate-type=rlib` is
|
||||
// legal and produces both inside this type.
|
||||
self.sess.crate_types().iter().all(|c| *c == CrateType::Rlib),
|
||||
hash,
|
||||
extra_filename,
|
||||
false, // is_host
|
||||
|
|
|
@ -222,7 +222,7 @@ use rustc_data_structures::owned_slice::slice_owned;
|
|||
use rustc_data_structures::svh::Svh;
|
||||
use rustc_errors::{DiagnosticArgValue, FatalError, IntoDiagnosticArg};
|
||||
use rustc_fs_util::try_canonicalize;
|
||||
use rustc_session::config::{self, CrateType};
|
||||
use rustc_session::config;
|
||||
use rustc_session::cstore::{CrateSource, MetadataLoader};
|
||||
use rustc_session::filesearch::FileSearch;
|
||||
use rustc_session::search_paths::PathKind;
|
||||
|
@ -305,14 +305,12 @@ impl<'a> CrateLocator<'a> {
|
|||
sess: &'a Session,
|
||||
metadata_loader: &'a dyn MetadataLoader,
|
||||
crate_name: Symbol,
|
||||
is_rlib: bool,
|
||||
hash: Option<Svh>,
|
||||
extra_filename: Option<&'a str>,
|
||||
is_host: bool,
|
||||
path_kind: PathKind,
|
||||
) -> CrateLocator<'a> {
|
||||
// The all loop is because `--crate-type=rlib --crate-type=rlib` is
|
||||
// legal and produces both inside this type.
|
||||
let is_rlib = sess.crate_types().iter().all(|c| *c == CrateType::Rlib);
|
||||
let needs_object_code = sess.opts.output_types.should_codegen();
|
||||
// If we're producing an rlib, then we don't need object code.
|
||||
// Or, if we're not producing object code, then we don't need it either
|
||||
|
@ -883,9 +881,10 @@ fn find_plugin_registrar_impl<'a>(
|
|||
sess,
|
||||
metadata_loader,
|
||||
name,
|
||||
None, // hash
|
||||
None, // extra_filename
|
||||
true, // is_host
|
||||
false, // is_rlib
|
||||
None, // hash
|
||||
None, // extra_filename
|
||||
true, // is_host
|
||||
PathKind::Crate,
|
||||
);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue