diff options
Diffstat (limited to 'compiler/rustc_interface/src')
| -rw-r--r-- | compiler/rustc_interface/src/passes.rs | 58 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/queries.rs | 165 |
2 files changed, 109 insertions, 114 deletions
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index a34fdf4ecc9..def9fdcd3c7 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -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>( @@ -275,7 +248,7 @@ fn configure_and_expand( rustc_ast_passes::ast_validation::check_crate(sess, &krate, resolver.lint_buffer()) }); - let crate_types = sess.crate_types(); + let crate_types = tcx.crate_types(); let is_executable_crate = crate_types.contains(&CrateType::Executable); let is_proc_macro_crate = crate_types.contains(&CrateType::ProcMacro); @@ -367,11 +340,12 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) { // Returns all the paths that correspond to generated files. fn generated_output_paths( - sess: &Session, + tcx: TyCtxt<'_>, outputs: &OutputFilenames, exact_name: bool, crate_name: Symbol, ) -> Vec<PathBuf> { + let sess = tcx.sess; let mut out_filenames = Vec::new(); for output_type in sess.opts.output_types.keys() { let out_filename = outputs.path(*output_type); @@ -380,7 +354,7 @@ fn generated_output_paths( // If the filename has been overridden using `-o`, it will not be modified // by appending `.rlib`, `.exe`, etc., so we can skip this transformation. OutputType::Exe if !exact_name => { - for crate_type in sess.crate_types().iter() { + for crate_type in tcx.crate_types().iter() { let p = filename_for_input(sess, *crate_type, crate_name, outputs); out_filenames.push(p.as_path().to_path_buf()); } @@ -613,7 +587,7 @@ fn output_filenames(tcx: TyCtxt<'_>, (): ()) -> Arc<OutputFilenames> { let outputs = util::build_output_filenames(&krate.attrs, sess); let output_paths = - generated_output_paths(sess, &outputs, sess.io.output_file.is_some(), crate_name); + generated_output_paths(tcx, &outputs, sess.io.output_file.is_some(), crate_name); // Ensure the source file isn't accidentally overwritten during compilation. if let Some(ref input_path) = sess.io.input.opt_path() { @@ -691,6 +665,8 @@ pub static DEFAULT_EXTERN_QUERY_PROVIDERS: LazyLock<ExternProviders> = LazyLock: pub fn create_global_ctxt<'tcx>( compiler: &'tcx Compiler, + crate_types: Vec<CrateType>, + stable_crate_id: StableCrateId, lint_store: Lrc<LintStore>, dep_graph: DepGraph, untracked: Untracked, @@ -723,6 +699,8 @@ pub fn create_global_ctxt<'tcx>( gcx_cell.get_or_init(move || { TyCtxt::create_global_ctxt( sess, + crate_types, + stable_crate_id, lint_store, arena, hir_arena, 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(), ) |
