From f7b3e39502783c82d4a8d9e02f59aa4268d15dbf Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 7 Feb 2023 16:11:40 +1100 Subject: [PATCH 1/4] Simplify `tls::enter_context`. --- compiler/rustc_interface/src/callbacks.rs | 2 +- compiler/rustc_interface/src/passes.rs | 2 +- compiler/rustc_middle/src/dep_graph/mod.rs | 2 +- compiler/rustc_middle/src/ty/context/tls.rs | 4 ++-- compiler/rustc_query_impl/src/plumbing.rs | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_interface/src/callbacks.rs b/compiler/rustc_interface/src/callbacks.rs index ee0552d77ce..bc6d7c20997 100644 --- a/compiler/rustc_interface/src/callbacks.rs +++ b/compiler/rustc_interface/src/callbacks.rs @@ -38,7 +38,7 @@ fn track_diagnostic(diagnostic: &mut Diagnostic, f: &mut dyn FnMut(&mut Diagnost // Diagnostics are tracked, we can ignore the dependency. let icx = tls::ImplicitCtxt { task_deps: TaskDepsRef::Ignore, ..icx.clone() }; - return tls::enter_context(&icx, move |_| (*f)(diagnostic)); + return tls::enter_context(&icx, move || (*f)(diagnostic)); } // In any other case, invoke diagnostics anyway. diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 2a373ebc132..304c3257456 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -748,7 +748,7 @@ pub fn enter(&mut self, f: F) -> R F: FnOnce(TyCtxt<'tcx>) -> R, { let icx = ty::tls::ImplicitCtxt::new(self.gcx); - ty::tls::enter_context(&icx, |_| f(icx.tcx)) + ty::tls::enter_context(&icx, || f(icx.tcx)) } } diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index 2e62bebc852..2e82efba192 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -55,7 +55,7 @@ fn with_deps(task_deps: TaskDepsRef<'_>, op: OP) -> R ty::tls::with_context(|icx| { let icx = ty::tls::ImplicitCtxt { task_deps, ..icx.clone() }; - ty::tls::enter_context(&icx, |_| op()) + ty::tls::enter_context(&icx, op) }) } diff --git a/compiler/rustc_middle/src/ty/context/tls.rs b/compiler/rustc_middle/src/ty/context/tls.rs index 71b025dc1be..4d1ddf0c7f1 100644 --- a/compiler/rustc_middle/src/ty/context/tls.rs +++ b/compiler/rustc_middle/src/ty/context/tls.rs @@ -110,9 +110,9 @@ unsafe fn downcast<'a, 'tcx>(context: *const ()) -> &'a ImplicitCtxt<'a, 'tcx> { #[inline] pub fn enter_context<'a, 'tcx, F, R>(context: &ImplicitCtxt<'a, 'tcx>, f: F) -> R where - F: FnOnce(&ImplicitCtxt<'a, 'tcx>) -> R, + F: FnOnce() -> R, { - tlv::with_tlv(erase(context), || f(&context)) + tlv::with_tlv(erase(context), f) } /// Allows access to the current `ImplicitCtxt` in a closure if one is available. diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 4dea03c1ef6..49309db564e 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -124,7 +124,7 @@ fn start_query( }; // Use the `ImplicitCtxt` while we execute the query. - tls::enter_context(&new_icx, |_| { + tls::enter_context(&new_icx, || { rustc_data_structures::stack::ensure_sufficient_stack(compute) }) }) From 18f751df6adc6342ee0814dd6bc36bf867ff0029 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 8 Feb 2023 16:24:57 +1100 Subject: [PATCH 2/4] Simplify `with_tlv`. --- compiler/rustc_middle/src/lib.rs | 1 + compiler/rustc_middle/src/ty/context/tls.rs | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 95148de2518..56df1a66f9d 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -34,6 +34,7 @@ #![feature(get_mut_unchecked)] #![feature(if_let_guard)] #![feature(iter_from_generator)] +#![feature(local_key_cell_methods)] #![feature(negative_impls)] #![feature(never_type)] #![feature(extern_types)] diff --git a/compiler/rustc_middle/src/ty/context/tls.rs b/compiler/rustc_middle/src/ty/context/tls.rs index 4d1ddf0c7f1..5426ac8d739 100644 --- a/compiler/rustc_middle/src/ty/context/tls.rs +++ b/compiler/rustc_middle/src/ty/context/tls.rs @@ -89,9 +89,8 @@ pub(super) fn get_tlv() -> *const () { /// This is used to set the pointer to the new `ImplicitCtxt`. #[inline] pub(super) fn with_tlv R, R>(value: *const (), f: F) -> R { - let old = get_tlv(); - let _reset = rustc_data_structures::OnDrop(move || TLV.with(|tlv| tlv.set(old))); - TLV.with(|tlv| tlv.set(value)); + let old = TLV.replace(value); + let _reset = rustc_data_structures::OnDrop(move || TLV.set(old)); f() } } From afbe167fbb683fc1ed1c7577ab2eaa12cc44a6bf Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 9 Feb 2023 10:51:29 +1100 Subject: [PATCH 3/4] Avoid some `tls::with` calls. These are in places where a `tcx` is easily obtained. --- .../rustc_const_eval/src/const_eval/eval_queries.rs | 2 +- .../rustc_infer/src/infer/canonical/canonicalizer.rs | 10 ++++------ .../src/traits/error_reporting/suggestions.rs | 7 +++---- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 18e01567ca3..b4a49e1df61 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -54,7 +54,7 @@ fn eval_body_using_ecx<'mir, 'tcx>( trace!( "eval_body_using_ecx: pushing stack frame for global: {}{}", - with_no_trimmed_paths!(ty::tls::with(|tcx| tcx.def_path_str(cid.instance.def_id()))), + with_no_trimmed_paths!(ecx.tcx.def_path_str(cid.instance.def_id())), cid.promoted.map_or_else(String::new, |p| format!("::promoted[{:?}]", p)) ); diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 87c6dfad5fa..1e2441d984a 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -203,12 +203,10 @@ fn canonicalize_free_region<'tcx>( // rust-lang/rust#57464: `impl Trait` can leak local // scopes (in manner violating typeck). Therefore, use // `delay_span_bug` to allow type error over an ICE. - ty::tls::with(|tcx| { - tcx.sess.delay_span_bug( - rustc_span::DUMMY_SP, - &format!("unexpected region in query response: `{:?}`", r), - ); - }); + canonicalizer.tcx.sess.delay_span_bug( + rustc_span::DUMMY_SP, + &format!("unexpected region in query response: `{:?}`", r), + ); r } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 59aef52910e..2b543520198 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -98,6 +98,7 @@ fn try_get_upvar_span( // obligation fn get_from_await_ty( &self, + tcx: TyCtxt<'tcx>, visitor: AwaitsVisitor, hir: map::Map<'tcx>, ty_matches: F, @@ -134,9 +135,7 @@ fn get_from_await_ty( .unwrap_or_else(|| { bug!( "node_type: no type for node {}", - ty::tls::with(|tcx| tcx - .hir() - .node_to_string(await_expr.hir_id)) + tcx.hir().node_to_string(await_expr.hir_id) ) }) }, @@ -2351,7 +2350,7 @@ fn maybe_note_obligation_cause_for_async_await( let mut interior_or_upvar_span = None; - let from_awaited_ty = generator_data.get_from_await_ty(visitor, hir, ty_matches); + let from_awaited_ty = generator_data.get_from_await_ty(self.tcx, visitor, hir, ty_matches); debug!(?from_awaited_ty); // The generator interior types share the same binders From 243944c6535867f2d4e3bc44f4a8b0e300dc83b9 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 7 Feb 2023 16:59:50 +1100 Subject: [PATCH 4/4] Remove `QueryContext`. There is a type `QueryCtxt`, which impls the trait `QueryContext`. Confusingly, there is another type `QueryContext`. The latter is (like `TyCtxt`) just a pointer to a `GlobalContext`. It's not used much, e.g. its `impl` block has a single method. This commit removes `QueryContext`, replacing its use with direct `GlobalCtxt` use. --- compiler/rustc_interface/src/passes.rs | 26 +++++------------------- compiler/rustc_interface/src/queries.rs | 27 +++++++++++++------------ compiler/rustc_middle/src/ty/context.rs | 12 +++++++++++ src/librustdoc/lib.rs | 4 ++-- 4 files changed, 33 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 304c3257456..33ebbb411ce 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -738,30 +738,16 @@ fn output_filenames(tcx: TyCtxt<'_>, (): ()) -> Arc { extern_providers }); -pub struct QueryContext<'tcx> { - gcx: &'tcx GlobalCtxt<'tcx>, -} - -impl<'tcx> QueryContext<'tcx> { - pub fn enter(&mut self, f: F) -> R - where - F: FnOnce(TyCtxt<'tcx>) -> R, - { - let icx = ty::tls::ImplicitCtxt::new(self.gcx); - ty::tls::enter_context(&icx, || f(icx.tcx)) - } -} - pub fn create_global_ctxt<'tcx>( compiler: &'tcx Compiler, lint_store: Lrc, dep_graph: DepGraph, untracked: Untracked, queries: &'tcx OnceCell>, - global_ctxt: &'tcx OnceCell>, + gcx_cell: &'tcx OnceCell>, arena: &'tcx WorkerLocal>, hir_arena: &'tcx WorkerLocal>, -) -> QueryContext<'tcx> { +) -> &'tcx GlobalCtxt<'tcx> { // We're constructing the HIR here; we don't care what we will // read, since we haven't even constructed the *input* to // incr. comp. yet. @@ -785,8 +771,8 @@ pub fn create_global_ctxt<'tcx>( TcxQueries::new(local_providers, extern_providers, query_result_on_disk_cache) }); - let gcx = sess.time("setup_global_ctxt", || { - global_ctxt.get_or_init(move || { + sess.time("setup_global_ctxt", || { + gcx_cell.get_or_init(move || { TyCtxt::create_global_ctxt( sess, lint_store, @@ -799,9 +785,7 @@ pub fn create_global_ctxt<'tcx>( rustc_query_impl::query_callbacks(arena), ) }) - }); - - QueryContext { gcx } + }) } /// Runs the resolution, type-checking, region checking and other diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 4b0180741c1..6512695873e 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::{self, BoxedResolver, QueryContext}; +use crate::passes::{self, BoxedResolver}; use rustc_ast as ast; use rustc_codegen_ssa::traits::CodegenBackend; @@ -64,7 +64,7 @@ fn deref_mut(&mut self) -> &mut Self::Target { } } -impl<'a, 'tcx> QueryResult<'a, QueryContext<'tcx>> { +impl<'a, 'tcx> QueryResult<'a, &'tcx GlobalCtxt<'tcx>> { pub fn enter(&mut self, f: impl FnOnce(TyCtxt<'tcx>) -> T) -> T { (*self.0).get_mut().enter(f) } @@ -78,7 +78,7 @@ fn default() -> Self { pub struct Queries<'tcx> { compiler: &'tcx Compiler, - gcx: OnceCell>, + gcx_cell: OnceCell>, queries: OnceCell>, arena: WorkerLocal>, @@ -90,7 +90,8 @@ pub struct Queries<'tcx> { register_plugins: Query<(ast::Crate, Lrc)>, expansion: Query<(Lrc, Rc>, Lrc)>, dep_graph: Query, - global_ctxt: Query>, + // This just points to what's in `gcx_cell`. + gcx: Query<&'tcx GlobalCtxt<'tcx>>, ongoing_codegen: Query>, } @@ -98,7 +99,7 @@ impl<'tcx> Queries<'tcx> { pub fn new(compiler: &'tcx Compiler) -> Queries<'tcx> { Queries { compiler, - gcx: OnceCell::new(), + gcx_cell: OnceCell::new(), queries: OnceCell::new(), arena: WorkerLocal::new(|_| Arena::default()), hir_arena: WorkerLocal::new(|_| rustc_hir::Arena::default()), @@ -108,7 +109,7 @@ pub fn new(compiler: &'tcx Compiler) -> Queries<'tcx> { register_plugins: Default::default(), expansion: Default::default(), dep_graph: Default::default(), - global_ctxt: Default::default(), + gcx: Default::default(), ongoing_codegen: Default::default(), } } @@ -207,8 +208,8 @@ fn dep_graph(&self) -> Result> { }) } - pub fn global_ctxt(&'tcx self) -> Result>> { - self.global_ctxt.compute(|| { + pub fn global_ctxt(&'tcx self) -> Result>> { + self.gcx.compute(|| { let crate_name = *self.crate_name()?.borrow(); let (krate, resolver, lint_store) = self.expansion()?.steal(); @@ -218,18 +219,18 @@ pub fn global_ctxt(&'tcx self) -> Result>> { ast_lowering: untracked_resolver_for_lowering, } = BoxedResolver::to_resolver_outputs(resolver); - let mut qcx = passes::create_global_ctxt( + let gcx = passes::create_global_ctxt( self.compiler, lint_store, self.dep_graph()?.steal(), untracked, &self.queries, - &self.gcx, + &self.gcx_cell, &self.arena, &self.hir_arena, ); - qcx.enter(|tcx| { + gcx.enter(|tcx| { let feed = tcx.feed_unit_query(); feed.resolver_for_lowering( tcx.arena.alloc(Steal::new((untracked_resolver_for_lowering, krate))), @@ -239,7 +240,7 @@ pub fn global_ctxt(&'tcx self) -> Result>> { let feed = tcx.feed_local_crate(); feed.crate_name(crate_name); }); - Ok(qcx) + Ok(gcx) }) } @@ -387,7 +388,7 @@ pub fn enter(&self, f: F) -> T // NOTE: intentionally does not compute the global context if it hasn't been built yet, // since that likely means there was a parse error. - if let Some(Ok(gcx)) = &mut *queries.global_ctxt.result.borrow_mut() { + if let Some(Ok(gcx)) = &mut *queries.gcx.result.borrow_mut() { let gcx = gcx.get_mut(); // We assume that no queries are run past here. If there are new queries // after this point, they'll show up as "" in self-profiling data. diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 9205a8a0ffe..d07d9190e01 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -468,6 +468,18 @@ pub struct GlobalCtxt<'tcx> { pub(crate) alloc_map: Lock>, } +impl<'tcx> GlobalCtxt<'tcx> { + /// Installs `self` in a `TyCtxt` and `ImplicitCtxt` for the duration of + /// `f`. + pub fn enter<'a: 'tcx, F, R>(&'a self, f: F) -> R + where + F: FnOnce(TyCtxt<'tcx>) -> R, + { + let icx = tls::ImplicitCtxt::new(self); + tls::enter_context(&icx, || f(icx.tcx)) + } +} + impl<'tcx> TyCtxt<'tcx> { /// Expects a body and returns its codegen attributes. /// diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 64108c88285..90d6388b70c 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -814,9 +814,9 @@ fn main_args(at_args: &[String]) -> MainResult { sess.fatal("Compilation failed, aborting rustdoc"); } - let mut global_ctxt = abort_on_err(queries.global_ctxt(), sess); + let mut gcx = abort_on_err(queries.global_ctxt(), sess); - global_ctxt.enter(|tcx| { + gcx.enter(|tcx| { let (krate, render_opts, mut cache) = sess.time("run_global_ctxt", || { core::run_global_ctxt( tcx,