diff options
Diffstat (limited to 'compiler/rustc_interface/src')
| -rw-r--r-- | compiler/rustc_interface/src/interface.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/lib.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/passes.rs | 111 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/proc_macro_decls.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/queries.rs | 120 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/tests.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/util.rs | 4 |
7 files changed, 74 insertions, 175 deletions
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 91f190c6a28..1456255ea14 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -22,9 +22,8 @@ use rustc_session::config::{self, Cfg, CheckCfg, ExpectedValues, Input, OutFileN use rustc_session::filesearch::{self, sysroot_candidates}; use rustc_session::parse::ParseSess; use rustc_session::{CompilerIO, EarlyDiagCtxt, Session, lint}; -use rustc_span::FileName; use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMapInputs}; -use rustc_span::symbol::sym; +use rustc_span::{FileName, sym}; use tracing::trace; use crate::util; diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs index 1c4dda2a436..a2a29612e48 100644 --- a/compiler/rustc_interface/src/lib.rs +++ b/compiler/rustc_interface/src/lib.rs @@ -8,7 +8,7 @@ // tidy-alphabetical-end mod callbacks; -mod errors; +pub mod errors; pub mod interface; pub mod passes; mod proc_macro_decls; @@ -17,8 +17,8 @@ pub mod util; pub use callbacks::setup_callbacks; pub use interface::{Config, run_compiler}; -pub use passes::DEFAULT_QUERY_PROVIDERS; -pub use queries::{Linker, Queries}; +pub use passes::{DEFAULT_QUERY_PROVIDERS, create_and_enter_global_ctxt, parse}; +pub use queries::Linker; #[cfg(test)] mod tests; diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 430bc7db077..02905e632ab 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -32,8 +32,7 @@ use rustc_session::cstore::Untracked; use rustc_session::output::{collect_crate_types, filename_for_input, find_crate_name}; use rustc_session::search_paths::PathKind; use rustc_session::{Limit, Session}; -use rustc_span::symbol::{Symbol, sym}; -use rustc_span::{ErrorGuaranteed, FileName, SourceFileHash, SourceFileHashAlgorithm}; +use rustc_span::{ErrorGuaranteed, FileName, SourceFileHash, SourceFileHashAlgorithm, Symbol, sym}; use rustc_target::spec::PanicStrategy; use rustc_trait_selection::traits; use tracing::{info, instrument}; @@ -41,7 +40,7 @@ use tracing::{info, instrument}; use crate::interface::Compiler; use crate::{errors, proc_macro_decls, util}; -pub(crate) fn parse<'a>(sess: &'a Session) -> ast::Crate { +pub fn parse<'a>(sess: &'a Session) -> ast::Crate { let krate = sess .time("parse_crate", || { let mut parser = unwrap_or_emit_fatal(match &sess.io.input { @@ -76,6 +75,7 @@ fn pre_expansion_lint<'a>( || { rustc_lint::check_ast_node( sess, + None, features, true, lint_store, @@ -310,6 +310,7 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) { let lint_store = unerased_lint_store(tcx.sess); rustc_lint::check_ast_node( sess, + Some(tcx), tcx.features(), false, lint_store, @@ -709,13 +710,11 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| { *providers }); -pub(crate) fn create_global_ctxt<'tcx>( - compiler: &'tcx Compiler, +pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>( + compiler: &Compiler, mut krate: rustc_ast::Crate, - gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>, - arena: &'tcx WorkerLocal<Arena<'tcx>>, - hir_arena: &'tcx WorkerLocal<rustc_hir::Arena<'tcx>>, -) -> &'tcx GlobalCtxt<'tcx> { + f: F, +) -> T { let sess = &compiler.sess; rustc_builtin_macros::cmdline_attrs::inject( @@ -763,44 +762,64 @@ pub(crate) fn create_global_ctxt<'tcx>( let incremental = dep_graph.is_fully_enabled(); - sess.time("setup_global_ctxt", || { - let qcx = gcx_cell.get_or_init(move || { - TyCtxt::create_global_ctxt( - sess, - crate_types, - stable_crate_id, - arena, - hir_arena, - untracked, - dep_graph, - rustc_query_impl::query_callbacks(arena), - rustc_query_impl::query_system( - providers.queries, - providers.extern_queries, - query_result_on_disk_cache, - incremental, - ), - providers.hooks, - compiler.current_gcx.clone(), - ) - }); - - qcx.enter(|tcx| { - let feed = tcx.create_crate_num(stable_crate_id).unwrap(); - assert_eq!(feed.key(), LOCAL_CRATE); - feed.crate_name(crate_name); + let gcx_cell = OnceLock::new(); + let arena = WorkerLocal::new(|_| Arena::default()); + let hir_arena = WorkerLocal::new(|_| rustc_hir::Arena::default()); + + // This closure is necessary to force rustc to perform the correct lifetime + // subtyping for GlobalCtxt::enter to be allowed. + let inner: Box< + dyn for<'tcx> FnOnce( + &'tcx Compiler, + &'tcx OnceLock<GlobalCtxt<'tcx>>, + &'tcx WorkerLocal<Arena<'tcx>>, + &'tcx WorkerLocal<rustc_hir::Arena<'tcx>>, + F, + ) -> T, + > = Box::new(move |compiler, gcx_cell, arena, hir_arena, f| { + let sess = &compiler.sess; + + TyCtxt::create_global_ctxt( + gcx_cell, + sess, + crate_types, + stable_crate_id, + arena, + hir_arena, + untracked, + dep_graph, + rustc_query_impl::query_callbacks(arena), + rustc_query_impl::query_system( + providers.queries, + providers.extern_queries, + query_result_on_disk_cache, + incremental, + ), + providers.hooks, + compiler.current_gcx.clone(), + |tcx| { + let feed = tcx.create_crate_num(stable_crate_id).unwrap(); + assert_eq!(feed.key(), LOCAL_CRATE); + feed.crate_name(crate_name); + + let feed = tcx.feed_unit_query(); + feed.features_query(tcx.arena.alloc(rustc_expand::config::features( + sess, + &pre_configured_attrs, + crate_name, + ))); + feed.crate_for_resolver(tcx.arena.alloc(Steal::new((krate, pre_configured_attrs)))); + feed.output_filenames(Arc::new(outputs)); + + let res = f(tcx); + // FIXME maybe run finish even when a fatal error occured? or at least tcx.alloc_self_profile_query_strings()? + tcx.finish(); + res + }, + ) + }); - let feed = tcx.feed_unit_query(); - feed.features_query(tcx.arena.alloc(rustc_expand::config::features( - sess, - &pre_configured_attrs, - crate_name, - ))); - feed.crate_for_resolver(tcx.arena.alloc(Steal::new((krate, pre_configured_attrs)))); - feed.output_filenames(Arc::new(outputs)); - }); - qcx - }) + inner(compiler, &gcx_cell, &arena, &hir_arena, f) } /// Runs all analyses that we guarantee to run, even if errors were reported in earlier analyses. diff --git a/compiler/rustc_interface/src/proc_macro_decls.rs b/compiler/rustc_interface/src/proc_macro_decls.rs index 2c8014d8b3a..82593dbc2b7 100644 --- a/compiler/rustc_interface/src/proc_macro_decls.rs +++ b/compiler/rustc_interface/src/proc_macro_decls.rs @@ -2,7 +2,7 @@ use rustc_ast::attr; use rustc_hir::def_id::LocalDefId; use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; -use rustc_span::symbol::sym; +use rustc_span::sym; fn proc_macro_decls_static(tcx: TyCtxt<'_>, (): ()) -> Option<LocalDefId> { let mut decls = None; diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index bb2ad3b3dd0..c8914c9be9c 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -1,117 +1,18 @@ use std::any::Any; -use std::cell::{RefCell, RefMut}; use std::sync::Arc; -use rustc_ast as ast; use rustc_codegen_ssa::CodegenResults; use rustc_codegen_ssa::traits::CodegenBackend; -use rustc_data_structures::steal::Steal; use rustc_data_structures::svh::Svh; -use rustc_data_structures::sync::{OnceLock, WorkerLocal}; use rustc_hir::def_id::LOCAL_CRATE; -use rustc_middle::arena::Arena; use rustc_middle::dep_graph::DepGraph; -use rustc_middle::ty::{GlobalCtxt, TyCtxt}; +use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_session::config::{self, OutputFilenames, OutputType}; use crate::errors::FailedWritingFile; -use crate::interface::Compiler; use crate::passes; -/// Represent the result of a query. -/// -/// This result can be stolen once with the [`steal`] method and generated with the [`compute`] method. -/// -/// [`steal`]: Steal::steal -/// [`compute`]: Self::compute -pub struct Query<T> { - /// `None` means no value has been computed yet. - result: RefCell<Option<Steal<T>>>, -} - -impl<T> Query<T> { - fn compute<F: FnOnce() -> T>(&self, f: F) -> QueryResult<'_, T> { - QueryResult(RefMut::map( - self.result.borrow_mut(), - |r: &mut Option<Steal<T>>| -> &mut Steal<T> { - r.get_or_insert_with(|| Steal::new(f())) - }, - )) - } -} - -pub struct QueryResult<'a, T>(RefMut<'a, Steal<T>>); - -impl<'a, T> std::ops::Deref for QueryResult<'a, T> { - type Target = RefMut<'a, Steal<T>>; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl<'a, T> std::ops::DerefMut for QueryResult<'a, T> { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -impl<'a, 'tcx> QueryResult<'a, &'tcx GlobalCtxt<'tcx>> { - pub fn enter<T>(&mut self, f: impl FnOnce(TyCtxt<'tcx>) -> T) -> T { - (*self.0).borrow().enter(f) - } -} - -pub struct Queries<'tcx> { - compiler: &'tcx Compiler, - gcx_cell: OnceLock<GlobalCtxt<'tcx>>, - - arena: WorkerLocal<Arena<'tcx>>, - hir_arena: WorkerLocal<rustc_hir::Arena<'tcx>>, - - parse: Query<ast::Crate>, - // This just points to what's in `gcx_cell`. - gcx: Query<&'tcx GlobalCtxt<'tcx>>, -} - -impl<'tcx> Queries<'tcx> { - pub fn new(compiler: &'tcx Compiler) -> Queries<'tcx> { - Queries { - compiler, - gcx_cell: OnceLock::new(), - arena: WorkerLocal::new(|_| Arena::default()), - hir_arena: WorkerLocal::new(|_| rustc_hir::Arena::default()), - parse: Query { result: RefCell::new(None) }, - gcx: Query { result: RefCell::new(None) }, - } - } - - pub fn finish(&'tcx self) { - if let Some(gcx) = self.gcx_cell.get() { - gcx.finish(); - } - } - - pub fn parse(&self) -> QueryResult<'_, ast::Crate> { - self.parse.compute(|| passes::parse(&self.compiler.sess)) - } - - pub fn global_ctxt(&'tcx self) -> QueryResult<'tcx, &'tcx GlobalCtxt<'tcx>> { - self.gcx.compute(|| { - let krate = self.parse().steal(); - - passes::create_global_ctxt( - self.compiler, - krate, - &self.gcx_cell, - &self.arena, - &self.hir_arena, - ) - }) - } -} - pub struct Linker { dep_graph: DepGraph, output_filenames: Arc<OutputFilenames>, @@ -186,22 +87,3 @@ impl Linker { codegen_backend.link(sess, codegen_results, &self.output_filenames) } } - -impl Compiler { - pub fn enter<F, T>(&self, f: F) -> T - where - F: for<'tcx> FnOnce(&'tcx Queries<'tcx>) -> T, - { - // Must declare `_timer` first so that it is dropped after `queries`. - let _timer; - let queries = Queries::new(self); - let ret = f(&queries); - - // The timer's lifetime spans the dropping of `queries`, which contains - // the global context. - _timer = self.sess.timer("free_global_ctxt"); - queries.finish(); - - ret - } -} diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index e76e9ca9f85..d103f7f45e2 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -23,8 +23,7 @@ use rustc_session::utils::{CanonicalizedPath, NativeLib, NativeLibKind}; use rustc_session::{CompilerIO, EarlyDiagCtxt, Session, build_session, filesearch, getopts}; use rustc_span::edition::{DEFAULT_EDITION, Edition}; use rustc_span::source_map::{RealFileLoader, SourceMapInputs}; -use rustc_span::symbol::sym; -use rustc_span::{FileName, SourceFileHashAlgorithm}; +use rustc_span::{FileName, SourceFileHashAlgorithm, sym}; use rustc_target::spec::{ CodeModel, FramePointer, LinkerFlavorCli, MergeFunctions, OnBrokenPipe, PanicStrategy, RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel, WasmCAbi, diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 2af25bfd3aa..984b8104f53 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -18,7 +18,7 @@ use rustc_session::{EarlyDiagCtxt, Session, filesearch}; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::edition::Edition; use rustc_span::source_map::SourceMapInputs; -use rustc_span::symbol::sym; +use rustc_span::sym; use rustc_target::spec::Target; use tracing::info; @@ -453,7 +453,7 @@ pub fn build_output_filenames(attrs: &[ast::Attribute], sess: &Session) -> Outpu .opts .crate_name .clone() - .or_else(|| rustc_attr::find_crate_name(attrs).map(|n| n.to_string())); + .or_else(|| rustc_attr_parsing::find_crate_name(attrs).map(|n| n.to_string())); match sess.io.output_file { None => { |
