use crate::proc_macro_decls;
use log::{info, warn, log_enabled};
+use rustc::arena::Arena;
use rustc::dep_graph::DepGraph;
use rustc::hir;
use rustc::hir::lowering::lower_crate;
use rustc_codegen_utils::codegen_backend::CodegenBackend;
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_data_structures::sync::{Lrc, Once, ParallelIterator, par_iter, WorkerLocal};
use rustc_errors::PResult;
use rustc_incremental;
use rustc_metadata::cstore;
use rustc_mir as mir;
use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str};
use rustc_passes::{self, ast_validation, hir_stats, layout_test};
-use rustc_plugin as plugin;
-use rustc_plugin::registry::Registry;
+use rustc_plugin_impl as plugin;
+use rustc_plugin_impl::registry::Registry;
use rustc_privacy;
use rustc_resolve::{Resolver, ResolverArenas};
use rustc_traits;
use rustc_typeck as typeck;
use syntax::{self, ast, visit};
use syntax::early_buffered_lints::BufferedEarlyLint;
-use syntax_expand::base::{NamedSyntaxExtension, ExtCtxt};
+use syntax_expand::base::ExtCtxt;
use syntax::mut_visit::MutVisitor;
use syntax::util::node_count::NodeCounter;
use syntax::symbol::Symbol;
metadata_loader: Box<MetadataLoaderDyn>,
krate: ast::Crate,
crate_name: &str,
- plugin_info: PluginInfo,
) -> Result<(ast::Crate, BoxedResolver)> {
// Currently, we ignore the name resolution data structures for the purposes of dependency
// tracking. Instead we will run name resolution and include its output in the hash of each
&crate_name,
&resolver_arenas,
&*metadata_loader,
- plugin_info,
);
let mut resolver = match res {
Err(v) => {
}
}
-pub struct PluginInfo {
- syntax_exts: Vec<NamedSyntaxExtension>,
-}
-
pub fn register_plugins<'a>(
sess: &'a Session,
metadata_loader: &'a dyn MetadataLoader,
register_lints: impl Fn(&Session, &mut lint::LintStore),
mut krate: ast::Crate,
crate_name: &str,
-) -> Result<(ast::Crate, PluginInfo, Lrc<lint::LintStore>)> {
+) -> Result<(ast::Crate, Lrc<lint::LintStore>)> {
krate = time(sess, "attributes injection", || {
syntax_ext::cmdline_attrs::inject(
krate, &sess.parse_sess, &sess.opts.debugging_opts.crate_attr
}
});
- let Registry {
- syntax_exts,
- llvm_passes,
- attributes,
- ..
- } = registry;
-
- *sess.plugin_llvm_passes.borrow_mut() = llvm_passes;
- *sess.plugin_attributes.borrow_mut() = attributes;
+ *sess.plugin_llvm_passes.borrow_mut() = registry.llvm_passes;
- Ok((krate, PluginInfo { syntax_exts }, Lrc::new(lint_store)))
+ Ok((krate, Lrc::new(lint_store)))
}
fn configure_and_expand_inner<'a>(
crate_name: &str,
resolver_arenas: &'a ResolverArenas<'a>,
metadata_loader: &'a MetadataLoaderDyn,
- plugin_info: PluginInfo,
) -> Result<(ast::Crate, Resolver<'a>)> {
time(sess, "pre-AST-expansion lint checks", || {
lint::check_ast_crate(
util::check_attr_crate_type(&krate.attrs, &mut resolver.lint_buffer());
- syntax_ext::plugin_macro_defs::inject(
- &mut krate, &mut resolver, plugin_info.syntax_exts, sess.edition()
- );
-
// Expand all macros
krate = time(sess, "expansion", || {
let _prof_timer = sess.prof.generic_activity("macro_expand_crate");
// If we're actually rustdoc then there's no need to actually compile
// anything, so switch everything to just looping
let mut should_loop = sess.opts.actually_rustdoc;
- if let Some((PpMode::PpmSource(PpSourceMode::PpmEveryBodyLoops), _)) = sess.opts.pretty {
+ if let Some(PpMode::PpmSource(PpSourceMode::PpmEveryBodyLoops)) = sess.opts.pretty {
should_loop |= true;
}
if should_loop {
rustc_codegen_ssa::provide_extern(providers);
}
-declare_box_region_type!(
- pub BoxedGlobalCtxt,
- for('tcx),
- (&'tcx GlobalCtxt<'tcx>) -> ((), ())
-);
+pub struct QueryContext<'tcx>(&'tcx GlobalCtxt<'tcx>);
-impl BoxedGlobalCtxt {
+impl<'tcx> QueryContext<'tcx> {
pub fn enter<F, R>(&mut self, f: F) -> R
where
- F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> R,
+ F: FnOnce(TyCtxt<'tcx>) -> R,
{
- self.access(|gcx| ty::tls::enter_global(gcx, |tcx| f(tcx)))
+ ty::tls::enter_global(self.0, |tcx| f(tcx))
+ }
+
+ pub fn print_stats(&self) {
+ self.0.queries.print_stats()
}
}
-pub fn create_global_ctxt(
- compiler: &Compiler,
+pub fn create_global_ctxt<'tcx>(
+ compiler: &'tcx Compiler,
lint_store: Lrc<lint::LintStore>,
- mut hir_forest: hir::map::Forest,
+ hir_forest: &'tcx hir::map::Forest,
mut resolver_outputs: ResolverOutputs,
outputs: OutputFilenames,
crate_name: &str,
-) -> BoxedGlobalCtxt {
- let sess = compiler.session().clone();
- let codegen_backend = compiler.codegen_backend().clone();
- let crate_name = crate_name.to_string();
+ global_ctxt: &'tcx Once<GlobalCtxt<'tcx>>,
+ arenas: &'tcx Once<AllArenas>,
+ local_arena: &'tcx WorkerLocal<Arena<'tcx>>,
+) -> QueryContext<'tcx> {
+ let sess = &compiler.session();
let defs = mem::take(&mut resolver_outputs.definitions);
- let override_queries = compiler.override_queries;
-
- let ((), result) = BoxedGlobalCtxt::new(static move || {
- let sess = &*sess;
-
- 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, &*resolver_outputs.cstore, &mut hir_forest, &defs)
- });
- let query_result_on_disk_cache = time(sess, "load query result cache", || {
- rustc_incremental::load_query_result_cache(sess)
- });
-
- let mut local_providers = ty::query::Providers::default();
- default_provide(&mut local_providers);
- codegen_backend.provide(&mut local_providers);
-
- let mut extern_providers = local_providers;
- default_provide_extern(&mut extern_providers);
- codegen_backend.provide_extern(&mut extern_providers);
+ // Construct the HIR map.
+ let hir_map = time(sess, "indexing HIR", || {
+ hir::map::map_crate(sess, &*resolver_outputs.cstore, &hir_forest, defs)
+ });
- if let Some(callback) = override_queries {
- callback(sess, &mut local_providers, &mut extern_providers);
- }
+ let query_result_on_disk_cache = time(sess, "load query result cache", || {
+ rustc_incremental::load_query_result_cache(sess)
+ });
- let gcx = TyCtxt::create_global_ctxt(
- sess,
- lint_store,
- local_providers,
- extern_providers,
- &arenas,
- resolver_outputs,
- hir_map,
- query_result_on_disk_cache,
- &crate_name,
- &outputs
- );
+ let codegen_backend = compiler.codegen_backend();
+ let mut local_providers = ty::query::Providers::default();
+ default_provide(&mut local_providers);
+ codegen_backend.provide(&mut local_providers);
- global_ctxt = Some(gcx);
- let gcx = global_ctxt.as_ref().unwrap();
+ let mut extern_providers = local_providers;
+ default_provide_extern(&mut extern_providers);
+ codegen_backend.provide_extern(&mut extern_providers);
- ty::tls::enter_global(gcx, |tcx| {
- // Do some initialization of the DepGraph that can only be done with the
- // tcx available.
- time(tcx.sess, "dep graph tcx init", || rustc_incremental::dep_graph_tcx_init(tcx));
- });
+ let override_queries = compiler.override_queries;
+ if let Some(callback) = override_queries {
+ callback(sess, &mut local_providers, &mut extern_providers);
+ }
- yield BoxedGlobalCtxt::initial_yield(());
- box_region_allow_access!(for('tcx), (&'tcx GlobalCtxt<'tcx>), (gcx));
+ let arenas = arenas.init_locking(|| AllArenas::new());
+ let gcx = global_ctxt.init_locking(|| TyCtxt::create_global_ctxt(
+ sess,
+ lint_store,
+ local_providers,
+ extern_providers,
+ &arenas,
+ local_arena,
+ resolver_outputs,
+ hir_map,
+ query_result_on_disk_cache,
+ &crate_name,
+ &outputs
+ ));
- if sess.opts.debugging_opts.query_stats {
- gcx.queries.print_stats();
- }
+ // Do some initialization of the DepGraph that can only be done with the tcx available.
+ ty::tls::enter_global(&gcx, |tcx| {
+ time(tcx.sess, "dep graph tcx init", || rustc_incremental::dep_graph_tcx_init(tcx));
});
- result
+ QueryContext(gcx)
}
/// Runs the resolution, type-checking, region checking and other