diff options
Diffstat (limited to 'compiler/rustc_interface')
| -rw-r--r-- | compiler/rustc_interface/src/interface.rs | 13 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/passes.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/util.rs | 33 |
3 files changed, 34 insertions, 13 deletions
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 656c7ffae19..da2fb490a36 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -10,7 +10,9 @@ use rustc_data_structures::sync::Lrc; use rustc_errors::registry::Registry; use rustc_errors::{DiagCtxt, ErrorGuaranteed}; use rustc_lint::LintStore; + use rustc_middle::ty; +use rustc_middle::ty::CurrentGcx; use rustc_middle::util::Providers; use rustc_parse::maybe_new_parser_from_source_str; use rustc_query_impl::QueryCtxt; @@ -39,6 +41,7 @@ pub struct Compiler { pub sess: Session, pub codegen_backend: Box<dyn CodegenBackend>, pub(crate) override_queries: Option<fn(&Session, &mut Providers)>, + pub(crate) current_gcx: CurrentGcx, } /// Converts strings provided as `--cfg [cfgspec]` into a `Cfg`. @@ -336,7 +339,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se util::run_in_thread_pool_with_globals( config.opts.edition, config.opts.unstable_opts.threads, - || { + |current_gcx| { crate::callbacks::setup_callbacks(); let early_dcx = EarlyDiagCtxt::new(config.opts.error_format); @@ -430,8 +433,12 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se } sess.lint_store = Some(Lrc::new(lint_store)); - let compiler = - Compiler { sess, codegen_backend, override_queries: config.override_queries }; + let compiler = Compiler { + sess, + codegen_backend, + override_queries: config.override_queries, + current_gcx, + }; rustc_span::set_source_map(compiler.sess.psess.clone_source_map(), move || { // There are two paths out of `f`. diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 4b4c1d6cf67..d763a12f816 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -680,6 +680,7 @@ pub fn create_global_ctxt<'tcx>( incremental, ), providers.hooks, + compiler.current_gcx.clone(), ) }) }) diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index d09f8d7d7cf..d0f04fccc48 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -5,6 +5,7 @@ use rustc_codegen_ssa::traits::CodegenBackend; #[cfg(parallel_compiler)] use rustc_data_structures::sync; use rustc_metadata::{load_symbol_from_dylib, DylibError}; +use rustc_middle::ty::CurrentGcx; use rustc_parse::validate_attr; use rustc_session as session; use rustc_session::config::{Cfg, OutFileName, OutputFilenames, OutputTypes}; @@ -64,7 +65,7 @@ fn init_stack_size() -> usize { }) } -pub(crate) fn run_in_thread_with_globals<F: FnOnce() -> R + Send, R: Send>( +pub(crate) fn run_in_thread_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: Send>( edition: Edition, f: F, ) -> R { @@ -82,7 +83,9 @@ pub(crate) fn run_in_thread_with_globals<F: FnOnce() -> R + Send, R: Send>( // `unwrap` is ok here because `spawn_scoped` only panics if the thread // name contains null bytes. let r = builder - .spawn_scoped(s, move || rustc_span::create_session_globals_then(edition, f)) + .spawn_scoped(s, move || { + rustc_span::create_session_globals_then(edition, || f(CurrentGcx::new())) + }) .unwrap() .join(); @@ -94,7 +97,7 @@ pub(crate) fn run_in_thread_with_globals<F: FnOnce() -> R + Send, R: Send>( } #[cfg(not(parallel_compiler))] -pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>( +pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: Send>( edition: Edition, _threads: usize, f: F, @@ -103,7 +106,7 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>( } #[cfg(parallel_compiler)] -pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>( +pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: Send>( edition: Edition, threads: usize, f: F, @@ -117,24 +120,34 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>( let registry = sync::Registry::new(std::num::NonZero::new(threads).unwrap()); if !sync::is_dyn_thread_safe() { - return run_in_thread_with_globals(edition, || { + return run_in_thread_with_globals(edition, |current_gcx| { // Register the thread for use with the `WorkerLocal` type. registry.register(); - f() + f(current_gcx) }); } + let current_gcx = FromDyn::from(CurrentGcx::new()); + let current_gcx2 = current_gcx.clone(); + let builder = rayon::ThreadPoolBuilder::new() .thread_name(|_| "rustc".to_string()) .acquire_thread_handler(jobserver::acquire_thread) .release_thread_handler(jobserver::release_thread) .num_threads(threads) - .deadlock_handler(|| { + .deadlock_handler(move || { // On deadlock, creates a new thread and forwards information in thread // locals to it. The new thread runs the deadlock handler. - let query_map = - FromDyn::from(tls::with(|tcx| QueryCtxt::new(tcx).collect_active_jobs())); + + // Get a `GlobalCtxt` reference from `CurrentGcx` as we cannot rely on having a + // `TyCtxt` TLS reference here. + let query_map = current_gcx2.access(|gcx| { + tls::enter_context(&tls::ImplicitCtxt::new(gcx), || { + tls::with(|tcx| QueryCtxt::new(tcx).collect_active_jobs()) + }) + }); + let query_map = FromDyn::from(query_map); let registry = rayon_core::Registry::current(); thread::Builder::new() .name("rustc query cycle handler".to_string()) @@ -171,7 +184,7 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>( }) }, // Run `f` on the first thread in the thread pool. - move |pool: &rayon::ThreadPool| pool.install(f), + move |pool: &rayon::ThreadPool| pool.install(|| f(current_gcx.into_inner())), ) .unwrap() }) |
