about summary refs log tree commit diff
path: root/compiler/rustc_interface/src/queries.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_interface/src/queries.rs')
-rw-r--r--compiler/rustc_interface/src/queries.rs165
1 files changed, 91 insertions, 74 deletions
diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs
index 8c4cdc6696a..7687e83da76 100644
--- a/compiler/rustc_interface/src/queries.rs
+++ b/compiler/rustc_interface/src/queries.rs
@@ -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(|| {
+            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 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)
-            })
+    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 dep_graph(&self) -> Result<QueryResult<'_, DepGraph>> {
-        self.dep_graph.compute(|| {
+    fn stable_crate_id(&self) -> Result<QueryResult<'_, StableCrateId>> {
+        self.stable_crate_id.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)
+            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 sess = self.session();
+            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 cstore = RwLock::new(Box::new(CStore::new(sess)) as _);
-            let definitions = RwLock::new(Definitions::new(sess.local_stable_crate_id()));
+            let sess = self.session();
+            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 features from session to tcx and make them immutable.
+            sess.init_features(rustc_expand::config::features(sess, &pre_configured_attrs));
+
             let qcx = passes::create_global_ctxt(
                 self.compiler,
+                crate_types,
+                stable_crate_id,
                 lint_store,
-                self.dep_graph()?.steal(),
+                self.dep_graph(dep_graph_future),
                 untracked,
                 &self.gcx_cell,
                 &self.arena,
@@ -303,7 +320,7 @@ impl<'tcx> Queries<'tcx> {
 
         let (crate_hash, prepare_outputs, dep_graph) = self.global_ctxt()?.enter(|tcx| {
             (
-                if tcx.sess.needs_crate_hash() { Some(tcx.crate_hash(LOCAL_CRATE)) } else { None },
+                if tcx.needs_crate_hash() { Some(tcx.crate_hash(LOCAL_CRATE)) } else { None },
                 tcx.output_filenames(()).clone(),
                 tcx.dep_graph.clone(),
             )