From 7794fbb47839ed0749647be343c4e52e6564123b Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 9 Apr 2020 09:06:11 +0200 Subject: [PATCH 01/23] Group logic about the Providers struct. --- compiler/rustc_middle/src/ty/query/plumbing.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_middle/src/ty/query/plumbing.rs b/compiler/rustc_middle/src/ty/query/plumbing.rs index 0961d4d0091..1cb705c251c 100644 --- a/compiler/rustc_middle/src/ty/query/plumbing.rs +++ b/compiler/rustc_middle/src/ty/query/plumbing.rs @@ -529,11 +529,6 @@ macro_rules! define_queries { tcx: $tcx, input: ($(([$($modifiers)*] [$name] [$($K)*] [$V]))*) } - - impl Copy for Providers {} - impl Clone for Providers { - fn clone(&self) -> Self { *self } - } } } @@ -609,5 +604,10 @@ macro_rules! define_provider_struct { Providers { $($name),* } } } + + impl Copy for Providers {} + impl Clone for Providers { + fn clone(&self) -> Self { *self } + } }; } From 211b05aef3d71fab0df7aa2f9616286a693a5cd7 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 11 Oct 2020 10:34:50 +0200 Subject: [PATCH 02/23] Don't require a QueryContext to access the DepGraph. --- compiler/rustc_middle/src/dep_graph/mod.rs | 5 +++++ compiler/rustc_middle/src/ty/query/plumbing.rs | 5 ----- compiler/rustc_query_system/src/cache.rs | 7 +++---- compiler/rustc_query_system/src/dep_graph/dep_node.rs | 2 +- compiler/rustc_query_system/src/dep_graph/mod.rs | 3 +++ compiler/rustc_query_system/src/query/mod.rs | 5 +---- 6 files changed, 13 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index b88ffa2bb73..eaf414ccaa6 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -111,6 +111,11 @@ impl<'tcx> DepContext for TyCtxt<'tcx> { || self.sess.opts.debugging_opts.query_dep_graph } + #[inline] + fn dep_graph(&self) -> &DepGraph { + &self.dep_graph + } + fn try_force_from_dep_node(&self, dep_node: &DepNode) -> bool { // FIXME: This match is just a workaround for incremental bugs and should // be removed. https://github.com/rust-lang/rust/issues/62649 is one such diff --git a/compiler/rustc_middle/src/ty/query/plumbing.rs b/compiler/rustc_middle/src/ty/query/plumbing.rs index 1cb705c251c..891da797b34 100644 --- a/compiler/rustc_middle/src/ty/query/plumbing.rs +++ b/compiler/rustc_middle/src/ty/query/plumbing.rs @@ -2,7 +2,6 @@ //! generate the actual methods on tcx which find and execute the provider, //! manage the caches, and so forth. -use crate::dep_graph::DepGraph; use crate::ty::query::Query; use crate::ty::tls::{self, ImplicitCtxt}; use crate::ty::{self, TyCtxt}; @@ -30,10 +29,6 @@ impl QueryContext for TyCtxt<'tcx> { TyCtxt::def_path_str(*self, def_id) } - fn dep_graph(&self) -> &DepGraph { - &self.dep_graph - } - fn current_query_job(&self) -> Option> { tls::with_related_context(*self, |icx| icx.query) } diff --git a/compiler/rustc_query_system/src/cache.rs b/compiler/rustc_query_system/src/cache.rs index be3d3607728..c6dc7b4fe28 100644 --- a/compiler/rustc_query_system/src/cache.rs +++ b/compiler/rustc_query_system/src/cache.rs @@ -1,7 +1,6 @@ //! Cache for candidate selection. -use crate::dep_graph::DepNodeIndex; -use crate::query::QueryContext; +use crate::dep_graph::{DepContext, DepNodeIndex}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::HashMapExt; @@ -28,7 +27,7 @@ impl Cache { } impl Cache { - pub fn get(&self, key: &Key, tcx: CTX) -> Option { + pub fn get(&self, key: &Key, tcx: CTX) -> Option { Some(self.hashmap.borrow().get(key)?.get(tcx)) } @@ -55,7 +54,7 @@ impl WithDepNode { WithDepNode { dep_node, cached_value } } - pub fn get(&self, tcx: CTX) -> T { + pub fn get(&self, tcx: CTX) -> T { tcx.dep_graph().read_index(self.dep_node); self.cached_value.clone() } diff --git a/compiler/rustc_query_system/src/dep_graph/dep_node.rs b/compiler/rustc_query_system/src/dep_graph/dep_node.rs index 64aba870502..1319a31b8f5 100644 --- a/compiler/rustc_query_system/src/dep_graph/dep_node.rs +++ b/compiler/rustc_query_system/src/dep_graph/dep_node.rs @@ -79,7 +79,7 @@ impl DepNode { pub fn construct(tcx: Ctxt, kind: K, arg: &Key) -> DepNode where - Ctxt: crate::query::QueryContext, + Ctxt: super::DepContext, Key: DepNodeParams, { let hash = arg.to_fingerprint(tcx); diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs index b1c901633a7..5c1444ad6c4 100644 --- a/compiler/rustc_query_system/src/dep_graph/mod.rs +++ b/compiler/rustc_query_system/src/dep_graph/mod.rs @@ -29,6 +29,9 @@ pub trait DepContext: Copy { fn debug_dep_tasks(&self) -> bool; fn debug_dep_node(&self) -> bool; + /// Access the DepGraph. + fn dep_graph(&self) -> &DepGraph; + /// Try to force a dep node to execute and see if it's green. fn try_force_from_dep_node(&self, dep_node: &DepNode) -> bool; diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index da45565dbe6..84d4b406c84 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -14,7 +14,7 @@ pub use self::caches::{ mod config; pub use self::config::{QueryAccessors, QueryConfig, QueryDescription}; -use crate::dep_graph::{DepContext, DepGraph}; +use crate::dep_graph::DepContext; use crate::query::job::QueryMap; use rustc_data_structures::stable_hasher::HashStable; @@ -32,9 +32,6 @@ pub trait QueryContext: DepContext { /// Get string representation from DefPath. fn def_path_str(&self, def_id: DefId) -> String; - /// Access the DepGraph. - fn dep_graph(&self) -> &DepGraph; - /// Get the query information from the TLS context. fn current_query_job(&self) -> Option>; From 6f048830231380011badb15eee30eb1655485d62 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 18 Oct 2020 21:00:24 +0200 Subject: [PATCH 03/23] Remove QueryAccessors::to_dep_node. --- compiler/rustc_query_system/src/query/config.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/compiler/rustc_query_system/src/query/config.rs b/compiler/rustc_query_system/src/query/config.rs index fecd75049fb..23b1ab09722 100644 --- a/compiler/rustc_query_system/src/query/config.rs +++ b/compiler/rustc_query_system/src/query/config.rs @@ -80,13 +80,6 @@ pub trait QueryAccessors: QueryConfig { where CTX: 'a; - fn to_dep_node(tcx: CTX, key: &Self::Key) -> DepNode - where - Self::Key: crate::dep_graph::DepNodeParams, - { - DepNode::construct(tcx, Self::DEP_KIND, key) - } - // Don't use this method to compute query results, instead use the methods on TyCtxt fn compute(tcx: CTX, key: Self::Key) -> Self::Value; From 49c1b07a9e09af5d01150c53b50676a5bc2e402d Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 18 Oct 2020 21:01:36 +0200 Subject: [PATCH 04/23] Decouple QueryContext from DepContext. --- .../rustc_middle/src/ty/query/plumbing.rs | 4 +- .../rustc_query_system/src/dep_graph/graph.rs | 13 +-- .../rustc_query_system/src/dep_graph/mod.rs | 21 +++++ .../rustc_query_system/src/query/config.rs | 4 +- compiler/rustc_query_system/src/query/job.rs | 5 +- compiler/rustc_query_system/src/query/mod.rs | 6 +- .../rustc_query_system/src/query/plumbing.rs | 87 +++++++++++-------- 7 files changed, 87 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_middle/src/ty/query/plumbing.rs b/compiler/rustc_middle/src/ty/query/plumbing.rs index 891da797b34..ea889549e43 100644 --- a/compiler/rustc_middle/src/ty/query/plumbing.rs +++ b/compiler/rustc_middle/src/ty/query/plumbing.rs @@ -48,7 +48,7 @@ impl QueryContext for TyCtxt<'tcx> { &self, token: QueryJobId, diagnostics: Option<&Lock>>, - compute: impl FnOnce(Self) -> R, + compute: impl FnOnce() -> R, ) -> R { // The `TyCtxt` stored in TLS has the same global interner lifetime // as `self`, so we use `with_related_context` to relate the 'tcx lifetimes @@ -65,7 +65,7 @@ impl QueryContext for TyCtxt<'tcx> { // Use the `ImplicitCtxt` while we execute the query. tls::enter_context(&new_icx, |_| { - rustc_data_structures::stack::ensure_sufficient_stack(|| compute(*self)) + rustc_data_structures::stack::ensure_sufficient_stack(compute) }) }) } diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index b13aa2f6ccb..9b0810e03f7 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -23,7 +23,7 @@ use super::debug::EdgeFilter; use super::prev::PreviousDepGraph; use super::query::DepGraphQuery; use super::serialized::SerializedDepNodeIndex; -use super::{DepContext, DepKind, DepNode, WorkProductId}; +use super::{DepContext, DepKind, DepNode, HasDepContext, WorkProductId}; #[derive(Clone)] pub struct DepGraph { @@ -235,7 +235,7 @@ impl DepGraph { /// `arg` parameter. /// /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/incremental-compilation.html - pub fn with_task, A, R>( + pub fn with_task, A, R>( &self, key: DepNode, cx: Ctxt, @@ -261,7 +261,7 @@ impl DepGraph { ) } - fn with_task_impl, A, R>( + fn with_task_impl, A, R>( &self, key: DepNode, cx: Ctxt, @@ -271,14 +271,15 @@ impl DepGraph { hash_result: impl FnOnce(&mut Ctxt::StableHashingContext, &R) -> Option, ) -> (R, DepNodeIndex) { if let Some(ref data) = self.data { + let dcx = cx.dep_context(); let task_deps = create_task(key).map(Lock::new); let result = K::with_deps(task_deps.as_ref(), || task(cx, arg)); let edges = task_deps.map_or_else(|| smallvec![], |lock| lock.into_inner().reads); - let mut hcx = cx.create_stable_hashing_context(); + let mut hcx = dcx.create_stable_hashing_context(); let current_fingerprint = hash_result(&mut hcx, &result); - let print_status = cfg!(debug_assertions) && cx.debug_dep_tasks(); + let print_status = cfg!(debug_assertions) && dcx.debug_dep_tasks(); // Intern the new `DepNode`. let dep_node_index = if let Some(prev_index) = data.previous.node_to_index_opt(&key) { @@ -408,7 +409,7 @@ impl DepGraph { /// Executes something within an "eval-always" task which is a task /// that runs whenever anything changes. - pub fn with_eval_always_task, A, R>( + pub fn with_eval_always_task, A, R>( &self, key: DepNode, cx: Ctxt, diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs index 5c1444ad6c4..db192d1cfe7 100644 --- a/compiler/rustc_query_system/src/dep_graph/mod.rs +++ b/compiler/rustc_query_system/src/dep_graph/mod.rs @@ -63,6 +63,27 @@ pub trait DepContext: Copy { fn profiler(&self) -> &SelfProfilerRef; } +pub trait HasDepContext: Copy { + type DepKind: self::DepKind; + type StableHashingContext; + type DepContext: self::DepContext< + DepKind = Self::DepKind, + StableHashingContext = Self::StableHashingContext, + >; + + fn dep_context(&self) -> &Self::DepContext; +} + +impl HasDepContext for T { + type DepKind = T::DepKind; + type StableHashingContext = T::StableHashingContext; + type DepContext = Self; + + fn dep_context(&self) -> &Self::DepContext { + self + } +} + /// Describe the different families of dependency nodes. pub trait DepKind: Copy + fmt::Debug + Eq + Hash { const NULL: Self; diff --git a/compiler/rustc_query_system/src/query/config.rs b/compiler/rustc_query_system/src/query/config.rs index 23b1ab09722..3873b47d4d4 100644 --- a/compiler/rustc_query_system/src/query/config.rs +++ b/compiler/rustc_query_system/src/query/config.rs @@ -33,9 +33,9 @@ pub(crate) struct QueryVtable { } impl QueryVtable { - pub(crate) fn to_dep_node(&self, tcx: CTX, key: &K) -> DepNode + pub(crate) fn to_dep_node(&self, tcx: CTX::DepContext, key: &K) -> DepNode where - K: crate::dep_graph::DepNodeParams, + K: crate::dep_graph::DepNodeParams, { DepNode::construct(tcx, self.dep_kind, key) } diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index 5fed500390b..0ecc2694a79 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -10,7 +10,8 @@ use std::num::NonZeroU32; #[cfg(parallel_compiler)] use { - super::QueryContext, + crate::dep_graph::DepContext, + crate::query::QueryContext, parking_lot::{Condvar, Mutex}, rustc_data_structures::fx::FxHashSet, rustc_data_structures::stable_hasher::{HashStable, StableHasher}, @@ -432,7 +433,7 @@ where { // Deterministically pick an entry point // FIXME: Sort this instead - let mut hcx = tcx.create_stable_hashing_context(); + let mut hcx = tcx.dep_context().create_stable_hashing_context(); queries .iter() .min_by_key(|v| { diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index 84d4b406c84..2d678035d4d 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -14,7 +14,7 @@ pub use self::caches::{ mod config; pub use self::config::{QueryAccessors, QueryConfig, QueryDescription}; -use crate::dep_graph::DepContext; +use crate::dep_graph::HasDepContext; use crate::query::job::QueryMap; use rustc_data_structures::stable_hasher::HashStable; @@ -23,7 +23,7 @@ use rustc_data_structures::thin_vec::ThinVec; use rustc_errors::Diagnostic; use rustc_span::def_id::DefId; -pub trait QueryContext: DepContext { +pub trait QueryContext: HasDepContext { type Query: Clone + HashStable; fn incremental_verify_ich(&self) -> bool; @@ -44,6 +44,6 @@ pub trait QueryContext: DepContext { &self, token: QueryJobId, diagnostics: Option<&Lock>>, - compute: impl FnOnce(Self) -> R, + compute: impl FnOnce() -> R, ) -> R; } diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 4242324b968..89f1e6511e3 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -2,7 +2,7 @@ //! generate the actual methods on tcx which find and execute the provider, //! manage the caches, and so forth. -use crate::dep_graph::{DepKind, DepNode}; +use crate::dep_graph::{DepContext, DepKind, DepNode}; use crate::dep_graph::{DepNodeIndex, SerializedDepNodeIndex}; use crate::query::caches::QueryCache; use crate::query::config::{QueryDescription, QueryVtable, QueryVtableExt}; @@ -204,7 +204,7 @@ where // in another thread has completed. Record how long we wait in the // self-profiler. let _query_blocked_prof_timer = if cfg!(parallel_compiler) { - Some(tcx.profiler().query_blocked()) + Some(tcx.dep_context().profiler().query_blocked()) } else { None }; @@ -266,8 +266,8 @@ where let cached = cache .cache .lookup(cache, &key, |value, index| { - if unlikely!(tcx.profiler().enabled()) { - tcx.profiler().query_cache_hit(index.into()); + if unlikely!(tcx.dep_context().profiler().enabled()) { + tcx.dep_context().profiler().query_cache_hit(index.into()); } #[cfg(debug_assertions)] { @@ -395,7 +395,7 @@ pub fn try_get_cached<'a, CTX, C, R, OnHit>( ) -> Result where C: QueryCache, - CTX: QueryContext, + CTX: DepContext, OnHit: FnOnce(&C::Stored) -> R, { cache.cache.lookup(cache, &key, |value, index| { @@ -422,7 +422,7 @@ fn try_execute_query( ) -> C::Stored where C: QueryCache, - C::Key: crate::dep_graph::DepNodeParams, + C::Key: crate::dep_graph::DepNodeParams, CTX: QueryContext, { let job = match JobOwner::<'_, CTX::DepKind, CTX::Query, C>::try_start( @@ -432,46 +432,51 @@ where TryGetJob::Cycle(result) => return result, #[cfg(parallel_compiler)] TryGetJob::JobCompleted((v, index)) => { - tcx.dep_graph().read_index(index); + tcx.dep_context().dep_graph().read_index(index); return v; } }; // Fast path for when incr. comp. is off. `to_dep_node` is // expensive for some `DepKind`s. - if !tcx.dep_graph().is_fully_enabled() { + if !tcx.dep_context().dep_graph().is_fully_enabled() { let null_dep_node = DepNode::new_no_params(DepKind::NULL); return force_query_with_job(tcx, key, job, null_dep_node, query).0; } if query.anon { - let prof_timer = tcx.profiler().query_provider(); + let prof_timer = tcx.dep_context().profiler().query_provider(); let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| { - tcx.start_query(job.id, diagnostics, |tcx| { - tcx.dep_graph().with_anon_task(query.dep_kind, || query.compute(tcx, key)) + tcx.start_query(job.id, diagnostics, || { + tcx.dep_context() + .dep_graph() + .with_anon_task(query.dep_kind, || query.compute(tcx, key)) }) }); prof_timer.finish_with_query_invocation_id(dep_node_index.into()); - tcx.dep_graph().read_index(dep_node_index); + tcx.dep_context().dep_graph().read_index(dep_node_index); if unlikely!(!diagnostics.is_empty()) { - tcx.store_diagnostics_for_anon_node(dep_node_index, diagnostics); + tcx.dep_context().store_diagnostics_for_anon_node(dep_node_index, diagnostics); } return job.complete(result, dep_node_index); } - let dep_node = query.to_dep_node(tcx, &key); + let dep_node = query.to_dep_node(*tcx.dep_context(), &key); if !query.eval_always { // The diagnostics for this query will be // promoted to the current session during // `try_mark_green()`, so we can ignore them here. - let loaded = tcx.start_query(job.id, None, |tcx| { - let marked = tcx.dep_graph().try_mark_green_and_read(tcx, &dep_node); + let loaded = tcx.start_query(job.id, None, || { + let marked = tcx + .dep_context() + .dep_graph() + .try_mark_green_and_read(*tcx.dep_context(), &dep_node); marked.map(|(prev_dep_node_index, dep_node_index)| { ( load_from_disk_and_cache_in_memory( @@ -492,7 +497,7 @@ where } let (result, dep_node_index) = force_query_with_job(tcx, key, job, dep_node, query); - tcx.dep_graph().read_index(dep_node_index); + tcx.dep_context().dep_graph().read_index(dep_node_index); result } @@ -510,11 +515,11 @@ where // Note this function can be called concurrently from the same query // We must ensure that this is handled correctly. - debug_assert!(tcx.dep_graph().is_green(dep_node)); + debug_assert!(tcx.dep_context().dep_graph().is_green(dep_node)); // First we try to load the result from the on-disk cache. let result = if query.cache_on_disk(tcx, &key, None) { - let prof_timer = tcx.profiler().incr_cache_loading(); + let prof_timer = tcx.dep_context().profiler().incr_cache_loading(); let result = query.try_load_from_disk(tcx, prev_dep_node_index); prof_timer.finish_with_query_invocation_id(dep_node_index.into()); @@ -536,10 +541,10 @@ where } else { // We could not load a result from the on-disk cache, so // recompute. - let prof_timer = tcx.profiler().query_provider(); + let prof_timer = tcx.dep_context().profiler().query_provider(); // The dep-graph for this computation is already in-place. - let result = tcx.dep_graph().with_ignore(|| query.compute(tcx, key)); + let result = tcx.dep_context().dep_graph().with_ignore(|| query.compute(tcx, key)); prof_timer.finish_with_query_invocation_id(dep_node_index.into()); @@ -549,7 +554,7 @@ where // If `-Zincremental-verify-ich` is specified, re-hash results from // the cache and make sure that they have the expected fingerprint. if unlikely!(tcx.incremental_verify_ich()) { - incremental_verify_ich(tcx, &result, dep_node, dep_node_index, query); + incremental_verify_ich(*tcx.dep_context(), &result, dep_node, dep_node_index, query); } result @@ -558,7 +563,7 @@ where #[inline(never)] #[cold] fn incremental_verify_ich( - tcx: CTX, + tcx: CTX::DepContext, result: &V, dep_node: &DepNode, dep_node_index: DepNodeIndex, @@ -601,7 +606,7 @@ where // 2. Two distinct query keys get mapped to the same `DepNode` // (see for example #48923). assert!( - !tcx.dep_graph().dep_node_exists(&dep_node), + !tcx.dep_context().dep_graph().dep_node_exists(&dep_node), "forcing query with already existing `DepNode`\n\ - query-key: {:?}\n\ - dep-node: {:?}", @@ -609,12 +614,12 @@ where dep_node ); - let prof_timer = tcx.profiler().query_provider(); + let prof_timer = tcx.dep_context().profiler().query_provider(); let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| { - tcx.start_query(job.id, diagnostics, |tcx| { + tcx.start_query(job.id, diagnostics, || { if query.eval_always { - tcx.dep_graph().with_eval_always_task( + tcx.dep_context().dep_graph().with_eval_always_task( dep_node, tcx, key, @@ -622,7 +627,13 @@ where query.hash_result, ) } else { - tcx.dep_graph().with_task(dep_node, tcx, key, query.compute, query.hash_result) + tcx.dep_context().dep_graph().with_task( + dep_node, + tcx, + key, + query.compute, + query.hash_result, + ) } }) }); @@ -630,7 +641,7 @@ where prof_timer.finish_with_query_invocation_id(dep_node_index.into()); if unlikely!(!diagnostics.is_empty()) && dep_node.kind != DepKind::NULL { - tcx.store_diagnostics(dep_node_index, diagnostics); + tcx.dep_context().store_diagnostics(dep_node_index, diagnostics); } let result = job.complete(result, dep_node_index); @@ -651,7 +662,7 @@ fn get_query_impl( where CTX: QueryContext, C: QueryCache, - C::Key: crate::dep_graph::DepNodeParams, + C::Key: crate::dep_graph::DepNodeParams, { try_execute_query(tcx, state, cache, span, key, lookup, query) } @@ -665,9 +676,9 @@ where /// /// Note: The optimization is only available during incr. comp. #[inline(never)] -fn ensure_must_run(tcx: CTX, key: &K, query: &QueryVtable) -> bool +fn ensure_must_run(tcx: CTX::DepContext, key: &K, query: &QueryVtable) -> bool where - K: crate::dep_graph::DepNodeParams, + K: crate::dep_graph::DepNodeParams, CTX: QueryContext, { if query.eval_always { @@ -707,14 +718,14 @@ fn force_query_impl( query: &QueryVtable, ) where C: QueryCache, - C::Key: crate::dep_graph::DepNodeParams, + C::Key: crate::dep_graph::DepNodeParams, CTX: QueryContext, { // We may be concurrently trying both execute and force a query. // Ensure that only one of them runs the query. let cached = cache.cache.lookup(cache, &key, |_, index| { - if unlikely!(tcx.profiler().enabled()) { - tcx.profiler().query_cache_hit(index.into()); + if unlikely!(tcx.dep_context().profiler().enabled()) { + tcx.dep_context().profiler().query_cache_hit(index.into()); } #[cfg(debug_assertions)] { @@ -752,12 +763,12 @@ pub fn get_query( ) -> Option where Q: QueryDescription, - Q::Key: crate::dep_graph::DepNodeParams, + Q::Key: crate::dep_graph::DepNodeParams, CTX: QueryContext, { let query = &Q::VTABLE; if let QueryMode::Ensure = mode { - if !ensure_must_run(tcx, &key, query) { + if !ensure_must_run(*tcx.dep_context(), &key, query) { return None; } } @@ -771,7 +782,7 @@ where pub fn force_query(tcx: CTX, key: Q::Key, span: Span, dep_node: DepNode) where Q: QueryDescription, - Q::Key: crate::dep_graph::DepNodeParams, + Q::Key: crate::dep_graph::DepNodeParams, CTX: QueryContext, { force_query_impl(tcx, Q::query_state(tcx), Q::query_cache(tcx), key, span, dep_node, &Q::VTABLE) From dab9b89221472d36fb5375d0c474c794706d2ae8 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 4 Jan 2021 23:38:20 +0100 Subject: [PATCH 05/23] Decouple the on-disk cache from the query engine. --- compiler/rustc_macros/src/query.rs | 4 ++-- compiler/rustc_middle/src/dep_graph/dep_node.rs | 7 ++----- compiler/rustc_middle/src/dep_graph/mod.rs | 9 ++++----- compiler/rustc_middle/src/query/mod.rs | 7 +------ compiler/rustc_middle/src/ty/context.rs | 15 +++++++++++---- .../rustc_middle/src/ty/query/on_disk_cache.rs | 1 - compiler/rustc_middle/src/ty/query/plumbing.rs | 8 -------- 7 files changed, 20 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index bd20c7689ea..48b74bdaf1e 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -97,7 +97,7 @@ impl Parse for QueryModifier { Ok(QueryModifier::Cache(args, block)) } else if modifier == "load_cached" { // Parse a load_cached modifier like: - // `load_cached(tcx, id) { tcx.queries.on_disk_cache.try_load_query_result(tcx, id) }` + // `load_cached(tcx, id) { tcx.on_disk_cache.try_load_query_result(tcx, id) }` let args; parenthesized!(args in input); let tcx = args.parse()?; @@ -368,7 +368,7 @@ fn add_query_description_impl( tcx: TyCtxt<'tcx>, id: SerializedDepNodeIndex ) -> Option { - tcx.queries.on_disk_cache.as_ref().and_then(|c| c.try_load_query_result(tcx, id)) + tcx.on_disk_cache.as_ref()?.try_load_query_result(tcx, id) } } }; diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 1cb75757379..669d7ea8d36 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -414,10 +414,7 @@ impl DepNodeExt for DepNode { /// has been removed. fn extract_def_id(&self, tcx: TyCtxt<'tcx>) -> Option { if self.kind.can_reconstruct_query_key() { - tcx.queries - .on_disk_cache - .as_ref()? - .def_path_hash_to_def_id(tcx, DefPathHash(self.hash.into())) + tcx.on_disk_cache.as_ref()?.def_path_hash_to_def_id(tcx, DefPathHash(self.hash.into())) } else { None } @@ -472,7 +469,7 @@ impl<'tcx> DepNodeParams> for DefId { // we will use the old DefIndex as an initial guess for // a lookup into the crate metadata. if !self.is_local() { - if let Some(cache) = &tcx.queries.on_disk_cache { + if let Some(cache) = &tcx.on_disk_cache { cache.store_foreign_def_id_hash(*self, hash); } } diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index eaf414ccaa6..4746004cfca 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -94,7 +94,7 @@ impl<'tcx> DepContext for TyCtxt<'tcx> { type StableHashingContext = StableHashingContext<'tcx>; fn register_reused_dep_node(&self, dep_node: &DepNode) { - if let Some(cache) = self.queries.on_disk_cache.as_ref() { + if let Some(cache) = self.on_disk_cache.as_ref() { cache.register_reused_dep_node(*self, dep_node) } } @@ -185,15 +185,14 @@ impl<'tcx> DepContext for TyCtxt<'tcx> { } fn load_diagnostics(&self, prev_dep_node_index: SerializedDepNodeIndex) -> Vec { - self.queries - .on_disk_cache + self.on_disk_cache .as_ref() .map(|c| c.load_diagnostics(*self, prev_dep_node_index)) .unwrap_or_default() } fn store_diagnostics(&self, dep_node_index: DepNodeIndex, diagnostics: ThinVec) { - if let Some(c) = self.queries.on_disk_cache.as_ref() { + if let Some(c) = self.on_disk_cache.as_ref() { c.store_diagnostics(dep_node_index, diagnostics) } } @@ -203,7 +202,7 @@ impl<'tcx> DepContext for TyCtxt<'tcx> { dep_node_index: DepNodeIndex, diagnostics: ThinVec, ) { - if let Some(c) = self.queries.on_disk_cache.as_ref() { + if let Some(c) = self.on_disk_cache.as_ref() { c.store_diagnostics_for_anon_node(dep_node_index, diagnostics) } } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 475f47c65bd..47b77bed906 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -125,11 +125,6 @@ rustc_queries! { desc { |tcx| "computing generics of `{}`", tcx.def_path_str(key) } storage(ArenaCacheSelector<'tcx>) cache_on_disk_if { key.is_local() } - load_cached(tcx, id) { - let generics: Option = tcx.queries.on_disk_cache.as_ref() - .and_then(|c| c.try_load_query_result(tcx, id)); - generics - } } /// Maps from the `DefId` of an item (trait/struct/enum/fn) to the @@ -702,7 +697,7 @@ rustc_queries! { cache_on_disk_if { true } load_cached(tcx, id) { let typeck_results: Option> = tcx - .queries.on_disk_cache.as_ref() + .on_disk_cache.as_ref() .and_then(|c| c.try_load_query_result(tcx, id)); typeck_results.map(|x| &*tcx.arena.alloc(x)) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 4654a842470..fa176193a93 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -14,7 +14,7 @@ use crate::middle::stability; use crate::mir::interpret::{self, Allocation, ConstValue, Scalar}; use crate::mir::{Body, Field, Local, Place, PlaceElem, ProjectionKind, Promoted}; use crate::traits; -use crate::ty::query::{self, TyCtxtAt}; +use crate::ty::query::{self, OnDiskCache, TyCtxtAt}; use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSubsts}; use crate::ty::TyKind::*; use crate::ty::{ @@ -962,6 +962,12 @@ pub struct GlobalCtxt<'tcx> { pub(crate) untracked_crate: &'tcx hir::Crate<'tcx>, pub(crate) definitions: &'tcx Definitions, + /// This provides access to the incremental compilation on-disk cache for query results. + /// Do not access this directly. It is only meant to be used by + /// `DepGraph::try_mark_green()` and the query infrastructure. + /// This is `None` if we are not incremental compilation mode + pub(crate) on_disk_cache: Option>, + pub queries: query::Queries<'tcx>, pub query_caches: query::QueryCaches<'tcx>, @@ -1110,7 +1116,7 @@ impl<'tcx> TyCtxt<'tcx> { krate: &'tcx hir::Crate<'tcx>, definitions: &'tcx Definitions, dep_graph: DepGraph, - on_disk_query_result_cache: Option>, + on_disk_cache: Option>, crate_name: &str, output_filenames: &OutputFilenames, ) -> GlobalCtxt<'tcx> { @@ -1154,7 +1160,8 @@ impl<'tcx> TyCtxt<'tcx> { extern_prelude: resolutions.extern_prelude, untracked_crate: krate, definitions, - queries: query::Queries::new(providers, extern_providers, on_disk_query_result_cache), + on_disk_cache, + queries: query::Queries::new(providers, extern_providers), query_caches: query::QueryCaches::default(), ty_rcache: Default::default(), pred_rcache: Default::default(), @@ -1320,7 +1327,7 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn serialize_query_result_cache(self, encoder: &mut FileEncoder) -> FileEncodeResult { - self.queries.on_disk_cache.as_ref().map_or(Ok(()), |c| c.serialize(self, encoder)) + self.on_disk_cache.as_ref().map_or(Ok(()), |c| c.serialize(self, encoder)) } /// If `true`, we should use the MIR-based borrowck, but also diff --git a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs index efe04786933..9f9f6bc4c51 100644 --- a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs @@ -918,7 +918,6 @@ impl<'a, 'tcx> Decodable> for DefId { // which means that the definition with this hash is guaranteed to // still exist in the current compilation session. Ok(d.tcx() - .queries .on_disk_cache .as_ref() .unwrap() diff --git a/compiler/rustc_middle/src/ty/query/plumbing.rs b/compiler/rustc_middle/src/ty/query/plumbing.rs index ea889549e43..8eb060a39a5 100644 --- a/compiler/rustc_middle/src/ty/query/plumbing.rs +++ b/compiler/rustc_middle/src/ty/query/plumbing.rs @@ -534,12 +534,6 @@ macro_rules! define_queries_struct { (tcx: $tcx:tt, input: ($(([$($modifiers:tt)*] [$($attr:tt)*] [$name:ident]))*)) => { pub struct Queries<$tcx> { - /// This provides access to the incremental compilation on-disk cache for query results. - /// Do not access this directly. It is only meant to be used by - /// `DepGraph::try_mark_green()` and the query infrastructure. - /// This is `None` if we are not incremental compilation mode - pub(crate) on_disk_cache: Option>, - providers: IndexVec, fallback_extern_providers: Box, @@ -554,12 +548,10 @@ macro_rules! define_queries_struct { pub(crate) fn new( providers: IndexVec, fallback_extern_providers: Providers, - on_disk_cache: Option>, ) -> Self { Queries { providers, fallback_extern_providers: Box::new(fallback_extern_providers), - on_disk_cache, $($name: Default::default()),* } } From 2db2776589eced747c35e030aa185f3a4fc93ffa Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 8 Apr 2020 17:03:34 +0200 Subject: [PATCH 06/23] Wrap TyCtxt inside a QueryCtxt for queries. --- compiler/rustc_macros/src/query.rs | 26 ++++---- .../rustc_middle/src/dep_graph/dep_node.rs | 5 +- compiler/rustc_middle/src/query/mod.rs | 1 + compiler/rustc_middle/src/ty/query/job.rs | 5 +- compiler/rustc_middle/src/ty/query/mod.rs | 1 + .../src/ty/query/on_disk_cache.rs | 7 +- .../rustc_middle/src/ty/query/plumbing.rs | 65 +++++++++++++------ compiler/rustc_middle/src/ty/query/stats.rs | 6 +- compiler/rustc_middle/src/ty/query/values.rs | 15 +++-- 9 files changed, 82 insertions(+), 49 deletions(-) diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index 48b74bdaf1e..1ac71824faf 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -354,9 +354,10 @@ fn add_query_description_impl( quote! { #[inline] fn try_load_from_disk( - #tcx: TyCtxt<'tcx>, - #id: SerializedDepNodeIndex + tcx: QueryCtxt<'tcx>, + id: SerializedDepNodeIndex ) -> Option { + let (#tcx, #id) = (*tcx, id); #block } } @@ -365,10 +366,10 @@ fn add_query_description_impl( quote! { #[inline] fn try_load_from_disk( - tcx: TyCtxt<'tcx>, + tcx: QueryCtxt<'tcx>, id: SerializedDepNodeIndex ) -> Option { - tcx.on_disk_cache.as_ref()?.try_load_query_result(tcx, id) + tcx.on_disk_cache.as_ref()?.try_load_query_result(*tcx, id) } } }; @@ -393,10 +394,11 @@ fn add_query_description_impl( #[inline] #[allow(unused_variables, unused_braces)] fn cache_on_disk( - #tcx: TyCtxt<'tcx>, - #key: &Self::Key, - #value: Option<&Self::Value> + tcx: QueryCtxt<'tcx>, + key: &Self::Key, + value: Option<&Self::Value> ) -> bool { + let (#tcx, #key, #value) = (*tcx, key, value); #expr } @@ -414,16 +416,14 @@ fn add_query_description_impl( let desc = quote! { #[allow(unused_variables)] - fn describe( - #tcx: TyCtxt<'tcx>, - #key: #arg, - ) -> String { - ::rustc_middle::ty::print::with_no_trimmed_paths(|| format!(#desc)) + fn describe(tcx: QueryCtxt<'tcx>, key: #arg) -> String { + let (#tcx, #key) = (*tcx, key); + ::rustc_middle::ty::print::with_no_trimmed_paths(|| format!(#desc).into()) } }; impls.extend(quote! { - impl<'tcx> QueryDescription> for queries::#name<'tcx> { + impl<'tcx> QueryDescription> for queries::#name<'tcx> { #desc #cache } diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 669d7ea8d36..ea1376e41c9 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -55,6 +55,7 @@ //! //! [dependency graph]: https://rustc-dev-guide.rust-lang.org/query.html +use crate::ty::query::QueryCtxt; use crate::ty::TyCtxt; use rustc_data_structures::fingerprint::Fingerprint; @@ -261,7 +262,7 @@ pub mod dep_kind { if let Some(key) = recover(tcx, dep_node) { force_query::, _>( - tcx, + QueryCtxt(tcx), key, DUMMY_SP, *dep_node @@ -287,7 +288,7 @@ pub mod dep_kind { .unwrap_or(false)); let key = recover(tcx, dep_node).unwrap_or_else(|| panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash)); - if queries::$variant::cache_on_disk(tcx, &key, None) { + if queries::$variant::cache_on_disk(QueryCtxt(tcx), &key, None) { let _ = tcx.$variant(key); } } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 47b77bed906..0f7728d48d9 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -7,6 +7,7 @@ use crate::traits::query::{ CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal, }; use crate::ty::query::queries; +use crate::ty::query::QueryCtxt; use crate::ty::subst::{GenericArg, SubstsRef}; use crate::ty::{self, ParamEnvAnd, Ty, TyCtxt}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; diff --git a/compiler/rustc_middle/src/ty/query/job.rs b/compiler/rustc_middle/src/ty/query/job.rs index bd2e7747b7d..0ea8bcc9d9d 100644 --- a/compiler/rustc_middle/src/ty/query/job.rs +++ b/compiler/rustc_middle/src/ty/query/job.rs @@ -1,3 +1,4 @@ +use crate::ty::query::QueryCtxt; use crate::ty::tls; use rustc_query_system::query::deadlock; @@ -20,7 +21,7 @@ pub unsafe fn handle_deadlock() { thread::spawn(move || { tls::enter_context(icx, |_| { rustc_span::SESSION_GLOBALS - .set(session_globals, || tls::with(|tcx| deadlock(tcx, ®istry))) - }) + .set(session_globals, || tls::with(|tcx| deadlock(QueryCtxt(tcx), ®istry))) + }); }); } diff --git a/compiler/rustc_middle/src/ty/query/mod.rs b/compiler/rustc_middle/src/ty/query/mod.rs index 804c045a690..88d1efffea7 100644 --- a/compiler/rustc_middle/src/ty/query/mod.rs +++ b/compiler/rustc_middle/src/ty/query/mod.rs @@ -60,6 +60,7 @@ use std::sync::Arc; #[macro_use] mod plumbing; +pub use plumbing::QueryCtxt; pub(crate) use rustc_query_system::query::CycleError; use rustc_query_system::query::*; diff --git a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs index 9f9f6bc4c51..5e862afae37 100644 --- a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs @@ -3,6 +3,7 @@ use crate::mir::interpret::{AllocDecodingSession, AllocDecodingState}; use crate::mir::{self, interpret}; use crate::ty::codec::{RefDecodable, TyDecoder, TyEncoder}; use crate::ty::context::TyCtxt; +use crate::ty::query::QueryCtxt; use crate::ty::{self, Ty}; use rustc_data_structures::fingerprint::{Fingerprint, FingerprintDecoder, FingerprintEncoder}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; @@ -312,7 +313,7 @@ impl<'sess> OnDiskCache<'sess> { ($($query:ident,)*) => { $( encode_query_results::>( - tcx, + QueryCtxt(tcx), enc, qri )?; @@ -1230,12 +1231,12 @@ impl<'a> Decodable> for IntEncodedWithFixedSize { } fn encode_query_results<'a, 'tcx, Q>( - tcx: TyCtxt<'tcx>, + tcx: QueryCtxt<'tcx>, encoder: &mut CacheEncoder<'a, 'tcx, FileEncoder>, query_result_index: &mut EncodedQueryResultIndex, ) -> FileEncodeResult where - Q: super::QueryDescription> + super::QueryAccessors>, + Q: super::QueryDescription> + super::QueryAccessors>, Q::Value: Encodable>, { let _timer = tcx diff --git a/compiler/rustc_middle/src/ty/query/plumbing.rs b/compiler/rustc_middle/src/ty/query/plumbing.rs index 8eb060a39a5..91a267e38d5 100644 --- a/compiler/rustc_middle/src/ty/query/plumbing.rs +++ b/compiler/rustc_middle/src/ty/query/plumbing.rs @@ -5,6 +5,7 @@ use crate::ty::query::Query; use crate::ty::tls::{self, ImplicitCtxt}; use crate::ty::{self, TyCtxt}; +use rustc_query_system::dep_graph::HasDepContext; use rustc_query_system::query::QueryContext; use rustc_query_system::query::{CycleError, QueryJobId, QueryJobInfo}; @@ -15,7 +16,29 @@ use rustc_errors::{struct_span_err, Diagnostic, DiagnosticBuilder, Handler, Leve use rustc_span::def_id::DefId; use rustc_span::Span; -impl QueryContext for TyCtxt<'tcx> { +#[derive(Copy, Clone)] +pub struct QueryCtxt<'tcx>(pub TyCtxt<'tcx>); + +impl<'tcx> std::ops::Deref for QueryCtxt<'tcx> { + type Target = TyCtxt<'tcx>; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl HasDepContext for QueryCtxt<'tcx> { + type DepKind = crate::dep_graph::DepKind; + type StableHashingContext = crate::ich::StableHashingContext<'tcx>; + type DepContext = TyCtxt<'tcx>; + + #[inline] + fn dep_context(&self) -> &Self::DepContext { + &self.0 + } +} + +impl QueryContext for QueryCtxt<'tcx> { type Query = Query<'tcx>; fn incremental_verify_ich(&self) -> bool { @@ -26,11 +49,11 @@ impl QueryContext for TyCtxt<'tcx> { } fn def_path_str(&self, def_id: DefId) -> String { - TyCtxt::def_path_str(*self, def_id) + self.0.def_path_str(def_id) } fn current_query_job(&self) -> Option> { - tls::with_related_context(*self, |icx| icx.query) + tls::with_related_context(**self, |icx| icx.query) } fn try_collect_active_jobs( @@ -53,10 +76,10 @@ impl QueryContext for TyCtxt<'tcx> { // The `TyCtxt` stored in TLS has the same global interner lifetime // as `self`, so we use `with_related_context` to relate the 'tcx lifetimes // when accessing the `ImplicitCtxt`. - tls::with_related_context(*self, move |current_icx| { + tls::with_related_context(**self, move |current_icx| { // Update the `ImplicitCtxt` to point to our new query job. let new_icx = ImplicitCtxt { - tcx: *self, + tcx: **self, query: Some(token), diagnostics, layout_depth: current_icx.layout_depth, @@ -71,7 +94,7 @@ impl QueryContext for TyCtxt<'tcx> { } } -impl<'tcx> TyCtxt<'tcx> { +impl<'tcx> QueryCtxt<'tcx> { #[inline(never)] #[cold] pub(super) fn report_cycle( @@ -81,7 +104,7 @@ impl<'tcx> TyCtxt<'tcx> { assert!(!stack.is_empty()); let fix_span = |span: Span, query: &Query<'tcx>| { - self.sess.source_map().guess_head_span(query.default_span(self, span)) + self.sess.source_map().guess_head_span(query.default_span(*self, span)) }; // Disable naming impls with types in this path, since that @@ -119,7 +142,9 @@ impl<'tcx> TyCtxt<'tcx> { err }) } +} +impl<'tcx> TyCtxt<'tcx> { pub fn try_print_query_stack(handler: &Handler, num_frames: Option) { eprintln!("query stack during panic:"); @@ -149,7 +174,7 @@ impl<'tcx> TyCtxt<'tcx> { "#{} [{}] {}", i, query_info.info.query.name(), - query_info.info.query.describe(icx.tcx) + query_info.info.query.describe(QueryCtxt(icx.tcx)) ), ); diag.span = @@ -272,7 +297,7 @@ macro_rules! define_queries { } } - pub fn describe(&self, tcx: TyCtxt<$tcx>) -> String { + pub(crate) fn describe(&self, tcx: QueryCtxt<$tcx>) -> String { let (r, name) = match *self { $(Query::$name(key) => { (queries::$name::describe(tcx, key), stringify!($name)) @@ -362,7 +387,7 @@ macro_rules! define_queries { const NAME: &'static str = stringify!($name); } - impl<$tcx> QueryAccessors> for queries::$name<$tcx> { + impl<$tcx> QueryAccessors> for queries::$name<$tcx> { const ANON: bool = is_anon!([$($modifiers)*]); const EVAL_ALWAYS: bool = is_eval_always!([$($modifiers)*]); const DEP_KIND: dep_graph::DepKind = dep_graph::DepKind::$name; @@ -370,19 +395,19 @@ macro_rules! define_queries { type Cache = query_storage::$name<$tcx>; #[inline(always)] - fn query_state<'a>(tcx: TyCtxt<$tcx>) -> &'a QueryState, Self::Key> { + fn query_state<'a>(tcx: QueryCtxt<$tcx>) -> &'a QueryState, Self::Key> { &tcx.queries.$name } #[inline(always)] - fn query_cache<'a>(tcx: TyCtxt<$tcx>) -> &'a QueryCacheStore + fn query_cache<'a>(tcx: QueryCtxt<$tcx>) -> &'a QueryCacheStore where 'tcx:'a { &tcx.query_caches.$name } #[inline] - fn compute(tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value { + fn compute(tcx: QueryCtxt<'tcx>, key: Self::Key) -> Self::Value { let provider = tcx.queries.providers.get(key.query_crate()) // HACK(eddyb) it's possible crates may be loaded after // the query engine is created, and because crate loading @@ -390,7 +415,7 @@ macro_rules! define_queries { // would be missing appropriate entries in `providers`. .unwrap_or(&tcx.queries.fallback_extern_providers) .$name; - provider(tcx, key) + provider(*tcx, key) } fn hash_result( @@ -401,7 +426,7 @@ macro_rules! define_queries { } fn handle_cycle_error( - tcx: TyCtxt<'tcx>, + tcx: QueryCtxt<'tcx>, error: CycleError> ) -> Self::Value { handle_cycle_error!([$($modifiers)*][tcx, error]) @@ -425,7 +450,8 @@ macro_rules! define_queries { Err(lookup) => lookup, }; - get_query::, _>(self.tcx, DUMMY_SP, key, lookup, QueryMode::Ensure); + let qcx = QueryCtxt(self.tcx); + get_query::, _>(qcx, DUMMY_SP, key, lookup, QueryMode::Ensure); })* } @@ -516,7 +542,8 @@ macro_rules! define_queries { Err(lookup) => lookup, }; - get_query::, _>(self.tcx, self.span, key, lookup, QueryMode::Get).unwrap() + let qcx = QueryCtxt(self.tcx); + get_query::, _>(qcx, self.span, key, lookup, QueryMode::Get).unwrap() })* } @@ -558,12 +585,12 @@ macro_rules! define_queries_struct { pub(crate) fn try_collect_active_jobs( &self - ) -> Option, QueryJobInfo as QueryContext>::Query>>> { + ) -> Option, QueryJobInfo>>> { let mut jobs = FxHashMap::default(); $( self.$name.try_collect_active_jobs( - as QueryAccessors>>::DEP_KIND, + as QueryAccessors>>::DEP_KIND, Query::$name, &mut jobs, )?; diff --git a/compiler/rustc_middle/src/ty/query/stats.rs b/compiler/rustc_middle/src/ty/query/stats.rs index 29ec9c132a8..47cbc7e43d2 100644 --- a/compiler/rustc_middle/src/ty/query/stats.rs +++ b/compiler/rustc_middle/src/ty/query/stats.rs @@ -1,7 +1,7 @@ -use crate::ty::query::queries; +use crate::ty::query::query_storage; use crate::ty::TyCtxt; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; -use rustc_query_system::query::{QueryAccessors, QueryCache, QueryCacheStore}; +use rustc_query_system::query::{QueryCache, QueryCacheStore}; use std::any::type_name; use std::mem; @@ -125,7 +125,7 @@ macro_rules! print_stats { $( queries.push(stats::< - as QueryAccessors>>::Cache, + query_storage::$name<'_>, >( stringify!($name), &tcx.query_caches.$name, diff --git a/compiler/rustc_middle/src/ty/query/values.rs b/compiler/rustc_middle/src/ty/query/values.rs index f28b0f499f0..fa15395db4e 100644 --- a/compiler/rustc_middle/src/ty/query/values.rs +++ b/compiler/rustc_middle/src/ty/query/values.rs @@ -1,18 +1,19 @@ -use crate::ty::{self, AdtSizedConstraint, Ty, TyCtxt, TyS}; +use crate::ty::query::QueryCtxt; +use crate::ty::{self, AdtSizedConstraint, Ty, TyS}; pub(super) trait Value<'tcx>: Sized { - fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self; + fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self; } impl<'tcx, T> Value<'tcx> for T { - default fn from_cycle_error(tcx: TyCtxt<'tcx>) -> T { + default fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> T { tcx.sess.abort_if_errors(); bug!("Value::from_cycle_error called without errors"); } } impl<'tcx> Value<'tcx> for &'_ TyS<'_> { - fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self { + fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self { // SAFETY: This is never called when `Self` is not `Ty<'tcx>`. // FIXME: Represent the above fact in the trait system somehow. unsafe { std::mem::transmute::, Ty<'_>>(tcx.ty_error()) } @@ -20,19 +21,19 @@ impl<'tcx> Value<'tcx> for &'_ TyS<'_> { } impl<'tcx> Value<'tcx> for ty::SymbolName<'_> { - fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self { + fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self { // SAFETY: This is never called when `Self` is not `SymbolName<'tcx>`. // FIXME: Represent the above fact in the trait system somehow. unsafe { std::mem::transmute::, ty::SymbolName<'_>>(ty::SymbolName::new( - tcx, "", + *tcx, "", )) } } } impl<'tcx> Value<'tcx> for AdtSizedConstraint<'_> { - fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self { + fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self { // SAFETY: This is never called when `Self` is not `AdtSizedConstraint<'tcx>`. // FIXME: Represent the above fact in the trait system somehow. unsafe { From 3f868b1791587e6af77e3b42a3b941f7fef03bcc Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 17 Jan 2021 14:58:34 +0100 Subject: [PATCH 07/23] Opacify query invocation. --- .../rustc_middle/src/ty/query/plumbing.rs | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_middle/src/ty/query/plumbing.rs b/compiler/rustc_middle/src/ty/query/plumbing.rs index 91a267e38d5..b084fd01327 100644 --- a/compiler/rustc_middle/src/ty/query/plumbing.rs +++ b/compiler/rustc_middle/src/ty/query/plumbing.rs @@ -450,8 +450,7 @@ macro_rules! define_queries { Err(lookup) => lookup, }; - let qcx = QueryCtxt(self.tcx); - get_query::, _>(qcx, DUMMY_SP, key, lookup, QueryMode::Ensure); + self.tcx.queries.$name(self.tcx, DUMMY_SP, key, lookup, QueryMode::Ensure); })* } @@ -542,8 +541,7 @@ macro_rules! define_queries { Err(lookup) => lookup, }; - let qcx = QueryCtxt(self.tcx); - get_query::, _>(qcx, self.span, key, lookup, QueryMode::Get).unwrap() + self.tcx.queries.$name(self.tcx, self.span, key, lookup, QueryMode::Get).unwrap() })* } @@ -598,6 +596,20 @@ macro_rules! define_queries_struct { Some(jobs) } + + $($(#[$attr])* + #[inline(always)] + fn $name( + &self, + tcx: TyCtxt<$tcx>, + span: Span, + key: query_keys::$name<$tcx>, + lookup: QueryLookup, + mode: QueryMode, + ) -> Option> { + let qcx = QueryCtxt(tcx); + get_query::, _>(qcx, span, key, lookup, mode) + })* } }; } From 5d71b99690b68ddb5b7b65b71fe900d6c74f570e Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 11 Oct 2020 10:34:13 +0200 Subject: [PATCH 08/23] Make QueryEngine opaque to TyCtxt. --- Cargo.lock | 1 + compiler/rustc_interface/Cargo.toml | 1 + compiler/rustc_interface/src/passes.rs | 26 +++++--- compiler/rustc_interface/src/queries.rs | 6 +- compiler/rustc_macros/src/query.rs | 12 ++-- .../rustc_middle/src/dep_graph/dep_node.rs | 5 +- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 13 ++-- compiler/rustc_middle/src/ty/query/job.rs | 5 +- compiler/rustc_middle/src/ty/query/mod.rs | 1 + .../src/ty/query/on_disk_cache.rs | 27 ++------ .../rustc_middle/src/ty/query/plumbing.rs | 63 ++++++++++++++++--- 12 files changed, 99 insertions(+), 63 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9f43f5a8b36..ba76b310b2b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3890,6 +3890,7 @@ dependencies = [ "rustc_expand", "rustc_hir", "rustc_incremental", + "rustc_index", "rustc_lint", "rustc_metadata", "rustc_middle", diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml index f3e4aab941b..210ba32bc1d 100644 --- a/compiler/rustc_interface/Cargo.toml +++ b/compiler/rustc_interface/Cargo.toml @@ -30,6 +30,7 @@ rustc_codegen_ssa = { path = "../rustc_codegen_ssa" } rustc_symbol_mangling = { path = "../rustc_symbol_mangling" } rustc_codegen_llvm = { path = "../rustc_codegen_llvm", optional = true } rustc_hir = { path = "../rustc_hir" } +rustc_index = { path = "../rustc_index" } rustc_metadata = { path = "../rustc_metadata" } rustc_mir = { path = "../rustc_mir" } rustc_mir_build = { path = "../rustc_mir_build" } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index ed5061125ba..76d988815ff 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -15,11 +15,13 @@ use rustc_expand::base::ExtCtxt; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_hir::definitions::Definitions; use rustc_hir::Crate; +use rustc_index::vec::IndexVec; use rustc_lint::LintStore; use rustc_middle::arena::Arena; use rustc_middle::dep_graph::DepGraph; use rustc_middle::middle; use rustc_middle::middle::cstore::{CrateStore, MetadataLoader, MetadataLoaderDyn}; +use rustc_middle::ty::query; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, GlobalCtxt, ResolverOutputs, TyCtxt}; use rustc_mir as mir; @@ -738,20 +740,18 @@ pub static DEFAULT_EXTERN_QUERY_PROVIDERS: SyncLazy = SyncLazy::new(| extern_providers }); -pub struct QueryContext<'tcx>(&'tcx GlobalCtxt<'tcx>); +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.0); + let icx = ty::tls::ImplicitCtxt::new(self.gcx); ty::tls::enter_context(&icx, |_| f(icx.tcx)) } - - pub fn print_stats(&mut self) { - self.enter(ty::query::print_stats) - } } pub fn create_global_ctxt<'tcx>( @@ -762,6 +762,7 @@ pub fn create_global_ctxt<'tcx>( mut resolver_outputs: ResolverOutputs, outputs: OutputFilenames, crate_name: &str, + queries: &'tcx OnceCell>, global_ctxt: &'tcx OnceCell>, arena: &'tcx WorkerLocal>, ) -> QueryContext<'tcx> { @@ -785,26 +786,33 @@ pub fn create_global_ctxt<'tcx>( callback(sess, &mut local_providers, &mut extern_providers); } + let queries = { + let crates = resolver_outputs.cstore.crates_untracked(); + let max_cnum = crates.iter().map(|c| c.as_usize()).max().unwrap_or(0); + let mut providers = IndexVec::from_elem_n(extern_providers, max_cnum + 1); + providers[LOCAL_CRATE] = local_providers; + queries.get_or_init(|| query::Queries::new(providers, extern_providers)) + }; + let gcx = sess.time("setup_global_ctxt", || { global_ctxt.get_or_init(|| { TyCtxt::create_global_ctxt( sess, lint_store, - local_providers, - extern_providers, arena, resolver_outputs, krate, defs, dep_graph, query_result_on_disk_cache, + queries, &crate_name, &outputs, ) }) }); - QueryContext(gcx) + 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 ac6b6d03115..86d78d7e9ca 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -13,6 +13,7 @@ use rustc_incremental::DepGraphFuture; use rustc_lint::LintStore; use rustc_middle::arena::Arena; use rustc_middle::dep_graph::DepGraph; +use rustc_middle::ty::query; use rustc_middle::ty::{GlobalCtxt, ResolverOutputs, TyCtxt}; use rustc_serialize::json; use rustc_session::config::{self, OutputFilenames, OutputType}; @@ -71,6 +72,7 @@ impl Default for Query { pub struct Queries<'tcx> { compiler: &'tcx Compiler, gcx: OnceCell>, + queries: OnceCell>, arena: WorkerLocal>, hir_arena: WorkerLocal>, @@ -92,6 +94,7 @@ impl<'tcx> Queries<'tcx> { Queries { compiler, gcx: OnceCell::new(), + queries: OnceCell::new(), arena: WorkerLocal::new(|_| Arena::default()), hir_arena: WorkerLocal::new(|_| rustc_ast_lowering::Arena::default()), dep_graph_future: Default::default(), @@ -265,6 +268,7 @@ impl<'tcx> Queries<'tcx> { resolver_outputs.steal(), outputs, &crate_name, + &self.queries, &self.gcx, &self.arena, )) @@ -429,7 +433,7 @@ impl Compiler { } if self.session().opts.debugging_opts.query_stats { - gcx.print_stats(); + gcx.enter(query::print_stats); } } diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index 1ac71824faf..e387020d828 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -354,10 +354,9 @@ fn add_query_description_impl( quote! { #[inline] fn try_load_from_disk( - tcx: QueryCtxt<'tcx>, - id: SerializedDepNodeIndex + #tcx: QueryCtxt<'tcx>, + #id: SerializedDepNodeIndex ) -> Option { - let (#tcx, #id) = (*tcx, id); #block } } @@ -394,11 +393,10 @@ fn add_query_description_impl( #[inline] #[allow(unused_variables, unused_braces)] fn cache_on_disk( - tcx: QueryCtxt<'tcx>, - key: &Self::Key, - value: Option<&Self::Value> + #tcx: QueryCtxt<'tcx>, + #key: &Self::Key, + #value: Option<&Self::Value> ) -> bool { - let (#tcx, #key, #value) = (*tcx, key, value); #expr } diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index ea1376e41c9..94a17f4645a 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -262,7 +262,7 @@ pub mod dep_kind { if let Some(key) = recover(tcx, dep_node) { force_query::, _>( - QueryCtxt(tcx), + QueryCtxt { tcx, queries: tcx.queries }, key, DUMMY_SP, *dep_node @@ -288,7 +288,8 @@ pub mod dep_kind { .unwrap_or(false)); let key = recover(tcx, dep_node).unwrap_or_else(|| panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash)); - if queries::$variant::cache_on_disk(QueryCtxt(tcx), &key, None) { + let qcx = QueryCtxt { tcx, queries: tcx.queries }; + if queries::$variant::cache_on_disk(qcx, &key, None) { let _ = tcx.$variant(key); } } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 0f7728d48d9..343ae66c07a 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -699,7 +699,7 @@ rustc_queries! { load_cached(tcx, id) { let typeck_results: Option> = tcx .on_disk_cache.as_ref() - .and_then(|c| c.try_load_query_result(tcx, id)); + .and_then(|c| c.try_load_query_result(*tcx, id)); typeck_results.map(|x| &*tcx.arena.alloc(x)) } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index fa176193a93..ec680eeb30f 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -14,7 +14,7 @@ use crate::middle::stability; use crate::mir::interpret::{self, Allocation, ConstValue, Scalar}; use crate::mir::{Body, Field, Local, Place, PlaceElem, ProjectionKind, Promoted}; use crate::traits; -use crate::ty::query::{self, OnDiskCache, TyCtxtAt}; +use crate::ty::query::{self, OnDiskCache, Queries, TyCtxtAt}; use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSubsts}; use crate::ty::TyKind::*; use crate::ty::{ @@ -968,7 +968,7 @@ pub struct GlobalCtxt<'tcx> { /// This is `None` if we are not incremental compilation mode pub(crate) on_disk_cache: Option>, - pub queries: query::Queries<'tcx>, + pub queries: &'tcx query::Queries<'tcx>, pub query_caches: query::QueryCaches<'tcx>, maybe_unused_trait_imports: FxHashSet, @@ -1109,14 +1109,13 @@ impl<'tcx> TyCtxt<'tcx> { pub fn create_global_ctxt( s: &'tcx Session, lint_store: Lrc, - local_providers: ty::query::Providers, - extern_providers: ty::query::Providers, arena: &'tcx WorkerLocal>, resolutions: ty::ResolverOutputs, krate: &'tcx hir::Crate<'tcx>, definitions: &'tcx Definitions, dep_graph: DepGraph, on_disk_cache: Option>, + queries: &'tcx Queries<'tcx>, crate_name: &str, output_filenames: &OutputFilenames, ) -> GlobalCtxt<'tcx> { @@ -1128,10 +1127,6 @@ impl<'tcx> TyCtxt<'tcx> { let common_lifetimes = CommonLifetimes::new(&interners); let common_consts = CommonConsts::new(&interners, &common_types); let cstore = resolutions.cstore; - let crates = cstore.crates_untracked(); - let max_cnum = crates.iter().map(|c| c.as_usize()).max().unwrap_or(0); - let mut providers = IndexVec::from_elem_n(extern_providers, max_cnum + 1); - providers[LOCAL_CRATE] = local_providers; let mut trait_map: FxHashMap<_, FxHashMap<_, _>> = FxHashMap::default(); for (hir_id, v) in krate.trait_map.iter() { @@ -1161,7 +1156,7 @@ impl<'tcx> TyCtxt<'tcx> { untracked_crate: krate, definitions, on_disk_cache, - queries: query::Queries::new(providers, extern_providers), + queries, query_caches: query::QueryCaches::default(), ty_rcache: Default::default(), pred_rcache: Default::default(), diff --git a/compiler/rustc_middle/src/ty/query/job.rs b/compiler/rustc_middle/src/ty/query/job.rs index 0ea8bcc9d9d..668109693a8 100644 --- a/compiler/rustc_middle/src/ty/query/job.rs +++ b/compiler/rustc_middle/src/ty/query/job.rs @@ -1,7 +1,4 @@ -use crate::ty::query::QueryCtxt; use crate::ty::tls; - -use rustc_query_system::query::deadlock; use rustc_rayon_core as rayon_core; use std::thread; @@ -21,7 +18,7 @@ pub unsafe fn handle_deadlock() { thread::spawn(move || { tls::enter_context(icx, |_| { rustc_span::SESSION_GLOBALS - .set(session_globals, || tls::with(|tcx| deadlock(QueryCtxt(tcx), ®istry))) + .set(session_globals, || tls::with(|tcx| tcx.queries.deadlock(tcx, ®istry))) }); }); } diff --git a/compiler/rustc_middle/src/ty/query/mod.rs b/compiler/rustc_middle/src/ty/query/mod.rs index 88d1efffea7..4c0b5846741 100644 --- a/compiler/rustc_middle/src/ty/query/mod.rs +++ b/compiler/rustc_middle/src/ty/query/mod.rs @@ -44,6 +44,7 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId}; use rustc_hir::lang_items::{LangItem, LanguageItems}; use rustc_hir::{Crate, ItemLocalId, TraitCandidate}; use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec}; +use rustc_serialize::opaque; use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion}; use rustc_session::utils::NativeLibKind; use rustc_session::CrateDisambiguator; diff --git a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs index 5e862afae37..db3449ed2e2 100644 --- a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs @@ -133,7 +133,7 @@ struct Footer { foreign_def_path_hashes: UnhashMap, } -type EncodedQueryResultIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>; +pub type EncodedQueryResultIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>; type EncodedDiagnosticsIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>; type EncodedDiagnostics = Vec; @@ -141,7 +141,7 @@ type EncodedDiagnostics = Vec; struct SourceFileIndex(u32); #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Encodable, Decodable)] -struct AbsoluteBytePos(u32); +pub struct AbsoluteBytePos(u32); impl AbsoluteBytePos { fn new(pos: usize) -> AbsoluteBytePos { @@ -308,22 +308,7 @@ impl<'sess> OnDiskCache<'sess> { tcx.sess.time("encode_query_results", || -> FileEncodeResult { let enc = &mut encoder; let qri = &mut query_result_index; - - macro_rules! encode_queries { - ($($query:ident,)*) => { - $( - encode_query_results::>( - QueryCtxt(tcx), - enc, - qri - )?; - )* - } - } - - rustc_cached_queries!(encode_queries!); - - Ok(()) + tcx.queries.encode_query_results(tcx, enc, qri) })?; // Encode diagnostics. @@ -973,7 +958,7 @@ impl<'a, 'tcx> Decodable> for &'tcx [Span] { //- ENCODING ------------------------------------------------------------------- -trait OpaqueEncoder: Encoder { +pub trait OpaqueEncoder: Encoder { fn position(&self) -> usize; } @@ -985,7 +970,7 @@ impl OpaqueEncoder for FileEncoder { } /// An encoder that can write to the incremental compilation cache. -struct CacheEncoder<'a, 'tcx, E: OpaqueEncoder> { +pub struct CacheEncoder<'a, 'tcx, E: OpaqueEncoder> { tcx: TyCtxt<'tcx>, encoder: &'a mut E, type_shorthands: FxHashMap, usize>, @@ -1230,7 +1215,7 @@ impl<'a> Decodable> for IntEncodedWithFixedSize { } } -fn encode_query_results<'a, 'tcx, Q>( +pub fn encode_query_results<'a, 'tcx, Q>( tcx: QueryCtxt<'tcx>, encoder: &mut CacheEncoder<'a, 'tcx, FileEncoder>, query_result_index: &mut EncodedQueryResultIndex, diff --git a/compiler/rustc_middle/src/ty/query/plumbing.rs b/compiler/rustc_middle/src/ty/query/plumbing.rs index b084fd01327..1d4be770005 100644 --- a/compiler/rustc_middle/src/ty/query/plumbing.rs +++ b/compiler/rustc_middle/src/ty/query/plumbing.rs @@ -2,7 +2,7 @@ //! generate the actual methods on tcx which find and execute the provider, //! manage the caches, and so forth. -use crate::ty::query::Query; +use crate::ty::query::{on_disk_cache, Query}; use crate::ty::tls::{self, ImplicitCtxt}; use crate::ty::{self, TyCtxt}; use rustc_query_system::dep_graph::HasDepContext; @@ -13,17 +13,21 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lock; use rustc_data_structures::thin_vec::ThinVec; use rustc_errors::{struct_span_err, Diagnostic, DiagnosticBuilder, Handler, Level}; +use rustc_serialize::opaque; use rustc_span::def_id::DefId; use rustc_span::Span; #[derive(Copy, Clone)] -pub struct QueryCtxt<'tcx>(pub TyCtxt<'tcx>); +pub struct QueryCtxt<'tcx> { + pub tcx: TyCtxt<'tcx>, + pub queries: &'tcx super::Queries<'tcx>, +} impl<'tcx> std::ops::Deref for QueryCtxt<'tcx> { type Target = TyCtxt<'tcx>; fn deref(&self) -> &Self::Target { - &self.0 + &self.tcx } } @@ -34,7 +38,7 @@ impl HasDepContext for QueryCtxt<'tcx> { #[inline] fn dep_context(&self) -> &Self::DepContext { - &self.0 + &self.tcx } } @@ -49,7 +53,7 @@ impl QueryContext for QueryCtxt<'tcx> { } fn def_path_str(&self, def_id: DefId) -> String { - self.0.def_path_str(def_id) + self.tcx.def_path_str(def_id) } fn current_query_job(&self) -> Option> { @@ -142,6 +146,28 @@ impl<'tcx> QueryCtxt<'tcx> { err }) } + + pub(super) fn encode_query_results( + self, + encoder: &mut on_disk_cache::CacheEncoder<'a, 'tcx, opaque::FileEncoder>, + query_result_index: &mut on_disk_cache::EncodedQueryResultIndex, + ) -> opaque::FileEncodeResult { + macro_rules! encode_queries { + ($($query:ident,)*) => { + $( + on_disk_cache::encode_query_results::>( + self, + encoder, + query_result_index + )?; + )* + } + } + + rustc_cached_queries!(encode_queries!); + + Ok(()) + } } impl<'tcx> TyCtxt<'tcx> { @@ -174,7 +200,10 @@ impl<'tcx> TyCtxt<'tcx> { "#{} [{}] {}", i, query_info.info.query.name(), - query_info.info.query.describe(QueryCtxt(icx.tcx)) + query_info + .info + .query + .describe(QueryCtxt { tcx: icx.tcx, queries: icx.tcx.queries }) ), ); diag.span = @@ -570,7 +599,7 @@ macro_rules! define_queries_struct { } impl<$tcx> Queries<$tcx> { - pub(crate) fn new( + pub fn new( providers: IndexVec, fallback_extern_providers: Providers, ) -> Self { @@ -597,17 +626,33 @@ macro_rules! define_queries_struct { Some(jobs) } + #[cfg(parallel_compiler)] + unsafe fn deadlock(&'tcx self, tcx: TyCtxt<'tcx>, registry: &rustc_rayon_core::Registry) { + let tcx = QueryCtxt { tcx, queries: self }; + rustc_query_system::query::deadlock(tcx, registry) + } + + pub(crate) fn encode_query_results( + &'tcx self, + tcx: TyCtxt<'tcx>, + encoder: &mut on_disk_cache::CacheEncoder<'a, 'tcx, opaque::FileEncoder>, + query_result_index: &mut on_disk_cache::EncodedQueryResultIndex, + ) -> opaque::FileEncodeResult { + let tcx = QueryCtxt { tcx, queries: self }; + tcx.encode_query_results(encoder, query_result_index) + } + $($(#[$attr])* #[inline(always)] fn $name( - &self, + &'tcx self, tcx: TyCtxt<$tcx>, span: Span, key: query_keys::$name<$tcx>, lookup: QueryLookup, mode: QueryMode, ) -> Option> { - let qcx = QueryCtxt(tcx); + let qcx = QueryCtxt { tcx, queries: self }; get_query::, _>(qcx, span, key, lookup, mode) })* } From 0e9cac40a66ad8c18409890673150d8a4eacf039 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 17 Jan 2021 14:57:34 +0100 Subject: [PATCH 09/23] Make alloc_self_profile_query_strings a standalone function. --- compiler/rustc_interface/src/queries.rs | 2 +- compiler/rustc_middle/src/ty/query/mod.rs | 2 +- .../rustc_middle/src/ty/query/plumbing.rs | 29 ------------ .../src/ty/query/profiling_support.rs | 46 ++++++++++++++++--- 4 files changed, 41 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 86d78d7e9ca..f70701257e2 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -429,7 +429,7 @@ impl Compiler { { let _prof_timer = queries.session().prof.generic_activity("self_profile_alloc_query_strings"); - gcx.enter(|tcx| tcx.alloc_self_profile_query_strings()); + gcx.enter(query::alloc_self_profile_query_strings); } if self.session().opts.debugging_opts.query_stats { diff --git a/compiler/rustc_middle/src/ty/query/mod.rs b/compiler/rustc_middle/src/ty/query/mod.rs index 4c0b5846741..dd0723f200f 100644 --- a/compiler/rustc_middle/src/ty/query/mod.rs +++ b/compiler/rustc_middle/src/ty/query/mod.rs @@ -88,7 +88,7 @@ mod on_disk_cache; pub use self::on_disk_cache::OnDiskCache; mod profiling_support; -pub use self::profiling_support::{IntoSelfProfilingString, QueryKeyStringBuilder}; +pub use self::profiling_support::alloc_self_profile_query_strings; // Each of these queries corresponds to a function pointer field in the // `Providers` struct for requesting a value of that type, and a method diff --git a/compiler/rustc_middle/src/ty/query/plumbing.rs b/compiler/rustc_middle/src/ty/query/plumbing.rs index 1d4be770005..a17fc71fd5c 100644 --- a/compiler/rustc_middle/src/ty/query/plumbing.rs +++ b/compiler/rustc_middle/src/ty/query/plumbing.rs @@ -524,35 +524,6 @@ macro_rules! define_queries { { self.at(DUMMY_SP).$name(key) })* - - /// All self-profiling events generated by the query engine use - /// virtual `StringId`s for their `event_id`. This method makes all - /// those virtual `StringId`s point to actual strings. - /// - /// If we are recording only summary data, the ids will point to - /// just the query names. If we are recording query keys too, we - /// allocate the corresponding strings here. - pub fn alloc_self_profile_query_strings(self) { - use crate::ty::query::profiling_support::{ - alloc_self_profile_query_strings_for_query_cache, - QueryKeyStringCache, - }; - - if !self.prof.enabled() { - return; - } - - let mut string_cache = QueryKeyStringCache::new(); - - $({ - alloc_self_profile_query_strings_for_query_cache( - self, - stringify!($name), - &self.query_caches.$name, - &mut string_cache, - ); - })* - } } impl TyCtxtAt<$tcx> { diff --git a/compiler/rustc_middle/src/ty/query/profiling_support.rs b/compiler/rustc_middle/src/ty/query/profiling_support.rs index 9976e788509..aab5fd9e8a1 100644 --- a/compiler/rustc_middle/src/ty/query/profiling_support.rs +++ b/compiler/rustc_middle/src/ty/query/profiling_support.rs @@ -9,24 +9,24 @@ use rustc_query_system::query::{QueryCache, QueryCacheStore}; use std::fmt::Debug; use std::io::Write; -pub struct QueryKeyStringCache { +struct QueryKeyStringCache { def_id_cache: FxHashMap, } impl QueryKeyStringCache { - pub fn new() -> QueryKeyStringCache { + fn new() -> QueryKeyStringCache { QueryKeyStringCache { def_id_cache: Default::default() } } } -pub struct QueryKeyStringBuilder<'p, 'c, 'tcx> { +struct QueryKeyStringBuilder<'p, 'c, 'tcx> { profiler: &'p SelfProfiler, tcx: TyCtxt<'tcx>, string_cache: &'c mut QueryKeyStringCache, } impl<'p, 'c, 'tcx> QueryKeyStringBuilder<'p, 'c, 'tcx> { - pub fn new( + fn new( profiler: &'p SelfProfiler, tcx: TyCtxt<'tcx>, string_cache: &'c mut QueryKeyStringCache, @@ -98,7 +98,7 @@ impl<'p, 'c, 'tcx> QueryKeyStringBuilder<'p, 'c, 'tcx> { } } -pub trait IntoSelfProfilingString { +trait IntoSelfProfilingString { fn to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_, '_>) -> StringId; } @@ -123,7 +123,7 @@ impl IntoSelfProfilingString for T { } #[rustc_specialization_trait] -pub trait SpecIntoSelfProfilingString: Debug { +trait SpecIntoSelfProfilingString: Debug { fn spec_to_self_profile_string( &self, builder: &mut QueryKeyStringBuilder<'_, '_, '_>, @@ -227,7 +227,7 @@ where /// Allocate the self-profiling query strings for a single query cache. This /// method is called from `alloc_self_profile_query_strings` which knows all /// the queries via macro magic. -pub(super) fn alloc_self_profile_query_strings_for_query_cache<'tcx, C>( +fn alloc_self_profile_query_strings_for_query_cache<'tcx, C>( tcx: TyCtxt<'tcx>, query_name: &'static str, query_cache: &QueryCacheStore, @@ -287,3 +287,35 @@ pub(super) fn alloc_self_profile_query_strings_for_query_cache<'tcx, C>( } }); } + +/// All self-profiling events generated by the query engine use +/// virtual `StringId`s for their `event_id`. This method makes all +/// those virtual `StringId`s point to actual strings. +/// +/// If we are recording only summary data, the ids will point to +/// just the query names. If we are recording query keys too, we +/// allocate the corresponding strings here. +pub fn alloc_self_profile_query_strings(tcx: TyCtxt<'tcx>) { + if !tcx.prof.enabled() { + return; + } + + let mut string_cache = QueryKeyStringCache::new(); + + macro_rules! alloc_once { + (<$tcx:tt> + $($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident($K:ty) -> $V:ty,)* + ) => { + $({ + alloc_self_profile_query_strings_for_query_cache( + tcx, + stringify!($name), + &tcx.query_caches.$name, + &mut string_cache, + ); + })* + } + } + + rustc_query_append! { [alloc_once!][<'tcx>] } +} From 4dbf83a2091bea4027f0e6eae43c991f06ff46b9 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 8 Apr 2020 20:47:36 +0200 Subject: [PATCH 10/23] Move try_print_query_stack to rustc_interface. --- compiler/rustc_driver/src/lib.rs | 3 +- compiler/rustc_interface/src/interface.rs | 23 +++++- .../rustc_middle/src/ty/query/plumbing.rs | 82 ++++++++----------- src/tools/clippy/src/driver.rs | 4 +- 4 files changed, 60 insertions(+), 52 deletions(-) diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index cad5a87bb13..07c7278a2f4 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -27,7 +27,6 @@ use rustc_interface::{interface, Queries}; use rustc_lint::LintStore; use rustc_metadata::locator; use rustc_middle::middle::cstore::MetadataLoader; -use rustc_middle::ty::TyCtxt; use rustc_save_analysis as save; use rustc_save_analysis::DumpHandler; use rustc_serialize::json::{self, ToJson}; @@ -1232,7 +1231,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { let num_frames = if backtrace { None } else { Some(2) }; - TyCtxt::try_print_query_stack(&handler, num_frames); + interface::try_print_query_stack(&handler, num_frames); #[cfg(windows)] unsafe { diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 28eb1fed6a0..502e7155c2e 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -8,7 +8,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lrc; use rustc_data_structures::OnDrop; use rustc_errors::registry::Registry; -use rustc_errors::ErrorReported; +use rustc_errors::{ErrorReported, Handler}; use rustc_lint::LintStore; use rustc_middle::ty; use rustc_parse::new_parser_from_source_str; @@ -213,3 +213,24 @@ pub fn run_compiler(mut config: Config, f: impl FnOnce(&Compiler) -> R || create_compiler_and_run(config, f), ) } + +pub fn try_print_query_stack(handler: &Handler, num_frames: Option) { + eprintln!("query stack during panic:"); + + // Be careful relying on global state here: this code is called from + // a panic hook, which means that the global `Handler` may be in a weird + // state if it was responsible for triggering the panic. + let i = ty::tls::with_context_opt(|icx| { + if let Some(icx) = icx { + icx.tcx.queries.try_print_query_stack(icx.tcx, icx.query, handler, num_frames) + } else { + 0 + } + }); + + if num_frames == None || num_frames >= Some(i) { + eprintln!("end of query stack"); + } else { + eprintln!("we're just showing a limited slice of the query stack"); + } +} diff --git a/compiler/rustc_middle/src/ty/query/plumbing.rs b/compiler/rustc_middle/src/ty/query/plumbing.rs index a17fc71fd5c..6aa9d88798f 100644 --- a/compiler/rustc_middle/src/ty/query/plumbing.rs +++ b/compiler/rustc_middle/src/ty/query/plumbing.rs @@ -2,7 +2,8 @@ //! generate the actual methods on tcx which find and execute the provider, //! manage the caches, and so forth. -use crate::ty::query::{on_disk_cache, Query}; +use crate::dep_graph; +use crate::ty::query::{on_disk_cache, Queries, Query}; use crate::ty::tls::{self, ImplicitCtxt}; use crate::ty::{self, TyCtxt}; use rustc_query_system::dep_graph::HasDepContext; @@ -170,57 +171,46 @@ impl<'tcx> QueryCtxt<'tcx> { } } -impl<'tcx> TyCtxt<'tcx> { - pub fn try_print_query_stack(handler: &Handler, num_frames: Option) { - eprintln!("query stack during panic:"); +impl<'tcx> Queries<'tcx> { + pub fn try_print_query_stack( + &'tcx self, + tcx: TyCtxt<'tcx>, + query: Option>, + handler: &Handler, + num_frames: Option, + ) -> usize { + let query_map = self.try_collect_active_jobs(); - // Be careful relying on global state here: this code is called from - // a panic hook, which means that the global `Handler` may be in a weird - // state if it was responsible for triggering the panic. + let mut current_query = query; let mut i = 0; - ty::tls::with_context_opt(|icx| { - if let Some(icx) = icx { - let query_map = icx.tcx.queries.try_collect_active_jobs(); - let mut current_query = icx.query; - - while let Some(query) = current_query { - if Some(i) == num_frames { - break; - } - let query_info = - if let Some(info) = query_map.as_ref().and_then(|map| map.get(&query)) { - info - } else { - break; - }; - let mut diag = Diagnostic::new( - Level::FailureNote, - &format!( - "#{} [{}] {}", - i, - query_info.info.query.name(), - query_info - .info - .query - .describe(QueryCtxt { tcx: icx.tcx, queries: icx.tcx.queries }) - ), - ); - diag.span = - icx.tcx.sess.source_map().guess_head_span(query_info.info.span).into(); - handler.force_print_diagnostic(diag); - - current_query = query_info.job.parent; - i += 1; - } + while let Some(query) = current_query { + if Some(i) == num_frames { + break; } - }); + let query_info = if let Some(info) = query_map.as_ref().and_then(|map| map.get(&query)) + { + info + } else { + break; + }; + let mut diag = Diagnostic::new( + Level::FailureNote, + &format!( + "#{} [{}] {}", + i, + query_info.info.query.name(), + query_info.info.query.describe(QueryCtxt { tcx, queries: self }) + ), + ); + diag.span = tcx.sess.source_map().guess_head_span(query_info.info.span).into(); + handler.force_print_diagnostic(diag); - if num_frames == None || num_frames >= Some(i) { - eprintln!("end of query stack"); - } else { - eprintln!("we're just showing a limited slice of the query stack"); + current_query = query_info.job.parent; + i += 1; } + + i } } diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index f5f6c09ed8e..d5143e1438e 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -11,10 +11,8 @@ extern crate rustc_driver; extern crate rustc_errors; extern crate rustc_interface; -extern crate rustc_middle; use rustc_interface::interface; -use rustc_middle::ty::TyCtxt; use rustc_tools_util::VersionInfo; use std::borrow::Cow; @@ -168,7 +166,7 @@ fn report_clippy_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { let num_frames = if backtrace { None } else { Some(2) }; - TyCtxt::try_print_query_stack(&handler, num_frames); + interface::try_print_query_stack(&handler, num_frames); } fn toolchain_path(home: Option, toolchain: Option) -> Option { From ea3d465c95ce027aabfe7423c3d9f2161bdc2eb1 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 5 Jan 2021 18:37:42 +0100 Subject: [PATCH 11/23] Move try_load_from_on_disk_cache to the QueryContext. --- compiler/rustc_middle/src/dep_graph/dep_node.rs | 9 ++++----- compiler/rustc_middle/src/dep_graph/mod.rs | 4 ---- compiler/rustc_middle/src/ty/query/on_disk_cache.rs | 2 +- compiler/rustc_middle/src/ty/query/plumbing.rs | 9 +++++++++ compiler/rustc_query_system/src/dep_graph/graph.rs | 6 ++++-- compiler/rustc_query_system/src/dep_graph/mod.rs | 3 --- compiler/rustc_query_system/src/query/mod.rs | 5 ++++- 7 files changed, 22 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 94a17f4645a..14a10e84e9c 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -138,7 +138,7 @@ pub struct DepKindStruct { pub(super) force_from_dep_node: fn(tcx: TyCtxt<'_>, dep_node: &DepNode) -> bool, /// Invoke a query to put the on-disk cached value in memory. - pub(super) try_load_from_on_disk_cache: fn(TyCtxt<'_>, &DepNode), + pub(crate) try_load_from_on_disk_cache: fn(QueryCtxt<'_>, &DepNode), } impl std::ops::Deref for DepKind { @@ -273,7 +273,7 @@ pub mod dep_kind { false } - fn try_load_from_on_disk_cache(tcx: TyCtxt<'_>, dep_node: &DepNode) { + fn try_load_from_on_disk_cache(tcx: QueryCtxt<'_>, dep_node: &DepNode) { if is_anon { return } @@ -287,9 +287,8 @@ pub mod dep_kind { .map(|c| c.is_green()) .unwrap_or(false)); - let key = recover(tcx, dep_node).unwrap_or_else(|| panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash)); - let qcx = QueryCtxt { tcx, queries: tcx.queries }; - if queries::$variant::cache_on_disk(qcx, &key, None) { + let key = recover(*tcx, dep_node).unwrap_or_else(|| panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash)); + if queries::$variant::cache_on_disk(tcx, &key, None) { let _ = tcx.$variant(key); } } diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index 4746004cfca..193bf3c9131 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -180,10 +180,6 @@ impl<'tcx> DepContext for TyCtxt<'tcx> { } // Interactions with on_disk_cache - fn try_load_from_on_disk_cache(&self, dep_node: &DepNode) { - (dep_node.kind.try_load_from_on_disk_cache)(*self, dep_node) - } - fn load_diagnostics(&self, prev_dep_node_index: SerializedDepNodeIndex) -> Vec { self.on_disk_cache .as_ref() diff --git a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs index db3449ed2e2..69352df1527 100644 --- a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs @@ -285,7 +285,7 @@ impl<'sess> OnDiskCache<'sess> { // Do this *before* we clone 'latest_foreign_def_path_hashes', since // loading existing queries may cause us to create new DepNodes, which // may in turn end up invoking `store_foreign_def_id_hash` - tcx.dep_graph.exec_cache_promotions(tcx); + tcx.queries.exec_cache_promotions(tcx); let latest_foreign_def_path_hashes = self.latest_foreign_def_path_hashes.lock().clone(); let hygiene_encode_context = HygieneEncodeContext::default(); diff --git a/compiler/rustc_middle/src/ty/query/plumbing.rs b/compiler/rustc_middle/src/ty/query/plumbing.rs index 6aa9d88798f..83dbe4875cf 100644 --- a/compiler/rustc_middle/src/ty/query/plumbing.rs +++ b/compiler/rustc_middle/src/ty/query/plumbing.rs @@ -68,6 +68,10 @@ impl QueryContext for QueryCtxt<'tcx> { self.queries.try_collect_active_jobs() } + fn try_load_from_on_disk_cache(&self, dep_node: &dep_graph::DepNode) { + (dep_node.kind.try_load_from_on_disk_cache)(*self, dep_node) + } + /// Executes a job by changing the `ImplicitCtxt` to point to the /// new query job while it executes. It returns the diagnostics /// captured during execution and the actual result. @@ -603,6 +607,11 @@ macro_rules! define_queries_struct { tcx.encode_query_results(encoder, query_result_index) } + fn exec_cache_promotions(&'tcx self, tcx: TyCtxt<'tcx>) { + let tcx = QueryCtxt { tcx, queries: self }; + tcx.dep_graph.exec_cache_promotions(tcx) + } + $($(#[$attr])* #[inline(always)] fn $name( diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 9b0810e03f7..8b0ab33f3f5 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -24,6 +24,7 @@ use super::prev::PreviousDepGraph; use super::query::DepGraphQuery; use super::serialized::SerializedDepNodeIndex; use super::{DepContext, DepKind, DepNode, HasDepContext, WorkProductId}; +use crate::query::QueryContext; #[derive(Clone)] pub struct DepGraph { @@ -875,7 +876,8 @@ impl DepGraph { // // This method will only load queries that will end up in the disk cache. // Other queries will not be executed. - pub fn exec_cache_promotions>(&self, tcx: Ctxt) { + pub fn exec_cache_promotions>(&self, qcx: Ctxt) { + let tcx = qcx.dep_context(); let _prof_timer = tcx.profiler().generic_activity("incr_comp_query_cache_promotion"); let data = self.data.as_ref().unwrap(); @@ -883,7 +885,7 @@ impl DepGraph { match data.colors.get(prev_index) { Some(DepNodeColor::Green(_)) => { let dep_node = data.previous.index_to_node(prev_index); - tcx.try_load_from_on_disk_cache(&dep_node); + qcx.try_load_from_on_disk_cache(&dep_node); } None | Some(DepNodeColor::Red) => { // We can skip red nodes because a node can only be marked diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs index db192d1cfe7..a1a6ca9dacc 100644 --- a/compiler/rustc_query_system/src/dep_graph/mod.rs +++ b/compiler/rustc_query_system/src/dep_graph/mod.rs @@ -43,9 +43,6 @@ pub trait DepContext: Copy { /// Return the diagnostic handler. fn diagnostic(&self) -> &rustc_errors::Handler; - /// Load data from the on-disk cache. - fn try_load_from_on_disk_cache(&self, dep_node: &DepNode); - /// Load diagnostics associated to the node in the previous session. fn load_diagnostics(&self, prev_dep_node_index: SerializedDepNodeIndex) -> Vec; diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index 2d678035d4d..8d5c9d7bea7 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -14,7 +14,7 @@ pub use self::caches::{ mod config; pub use self::config::{QueryAccessors, QueryConfig, QueryDescription}; -use crate::dep_graph::HasDepContext; +use crate::dep_graph::{DepNode, HasDepContext}; use crate::query::job::QueryMap; use rustc_data_structures::stable_hasher::HashStable; @@ -37,6 +37,9 @@ pub trait QueryContext: HasDepContext { fn try_collect_active_jobs(&self) -> Option>; + /// Load data from the on-disk cache. + fn try_load_from_on_disk_cache(&self, dep_node: &DepNode); + /// Executes a job by changing the `ImplicitCtxt` to point to the /// new query job while it executes. It returns the diagnostics /// captured during execution and the actual result. From a4b1158f7845fe237053876abe1e690333c39bbe Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 18 Nov 2020 19:02:31 +0100 Subject: [PATCH 12/23] Move handle_deadlock where it is used. --- Cargo.lock | 1 + compiler/rustc_interface/Cargo.toml | 1 + compiler/rustc_interface/src/util.rs | 32 ++++++++++++++++--- compiler/rustc_middle/src/ty/query/job.rs | 24 -------------- compiler/rustc_middle/src/ty/query/mod.rs | 4 --- .../rustc_middle/src/ty/query/plumbing.rs | 2 +- 6 files changed, 31 insertions(+), 33 deletions(-) delete mode 100644 compiler/rustc_middle/src/ty/query/job.rs diff --git a/Cargo.lock b/Cargo.lock index ba76b310b2b..b78bf583205 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3878,6 +3878,7 @@ version = "0.0.0" dependencies = [ "libc", "rustc-rayon", + "rustc-rayon-core", "rustc_ast", "rustc_ast_lowering", "rustc_ast_passes", diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml index 210ba32bc1d..a1ac155d57a 100644 --- a/compiler/rustc_interface/Cargo.toml +++ b/compiler/rustc_interface/Cargo.toml @@ -10,6 +10,7 @@ doctest = false [dependencies] libc = "0.2" tracing = "0.1" +rustc-rayon-core = "0.3.0" rayon = { version = "0.3.0", package = "rustc-rayon" } smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } rustc_ast = { path = "../rustc_ast" } diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index b7dc539c6d6..798996263c7 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -10,6 +10,8 @@ use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::sync::Lrc; use rustc_errors::registry::Registry; use rustc_metadata::dynamic_lib::DynamicLibrary; +#[cfg(parallel_compiler)] +use rustc_middle::ty::tls; use rustc_resolve::{self, Resolver}; use rustc_session as session; use rustc_session::config::{self, CrateType}; @@ -29,11 +31,12 @@ use std::io; use std::lazy::SyncOnceCell; use std::mem; use std::ops::DerefMut; +#[cfg(not(parallel_compiler))] +use std::panic; use std::path::{Path, PathBuf}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex, Once}; -#[cfg(not(parallel_compiler))] -use std::{panic, thread}; +use std::thread; use tracing::info; /// Adds `target_feature = "..."` cfgs for a variety of platform @@ -156,6 +159,28 @@ pub fn setup_callbacks_and_run_in_thread_pool_with_globals R + Se scoped_thread(cfg, main_handler) } +/// Creates a new thread and forwards information in thread locals to it. +/// The new thread runs the deadlock handler. +/// Must only be called when a deadlock is about to happen. +#[cfg(parallel_compiler)] +unsafe fn handle_deadlock() { + let registry = rustc_rayon_core::Registry::current(); + + let context = tls::get_tlv(); + assert!(context != 0); + rustc_data_structures::sync::assert_sync::>(); + let icx: &tls::ImplicitCtxt<'_, '_> = &*(context as *const tls::ImplicitCtxt<'_, '_>); + + let session_globals = rustc_span::SESSION_GLOBALS.with(|sg| sg as *const _); + let session_globals = &*session_globals; + thread::spawn(move || { + tls::enter_context(icx, |_| { + rustc_span::SESSION_GLOBALS + .set(session_globals, || tls::with(|tcx| tcx.queries.deadlock(tcx, ®istry))) + }); + }); +} + #[cfg(parallel_compiler)] pub fn setup_callbacks_and_run_in_thread_pool_with_globals R + Send, R: Send>( edition: Edition, @@ -163,7 +188,6 @@ pub fn setup_callbacks_and_run_in_thread_pool_with_globals R + Se stderr: &Option>>>, f: F, ) -> R { - use rustc_middle::ty; crate::callbacks::setup_callbacks(); let mut config = rayon::ThreadPoolBuilder::new() @@ -171,7 +195,7 @@ pub fn setup_callbacks_and_run_in_thread_pool_with_globals R + Se .acquire_thread_handler(jobserver::acquire_thread) .release_thread_handler(jobserver::release_thread) .num_threads(threads) - .deadlock_handler(|| unsafe { ty::query::handle_deadlock() }); + .deadlock_handler(|| unsafe { handle_deadlock() }); if let Some(size) = get_stack_size() { config = config.stack_size(size); diff --git a/compiler/rustc_middle/src/ty/query/job.rs b/compiler/rustc_middle/src/ty/query/job.rs deleted file mode 100644 index 668109693a8..00000000000 --- a/compiler/rustc_middle/src/ty/query/job.rs +++ /dev/null @@ -1,24 +0,0 @@ -use crate::ty::tls; -use rustc_rayon_core as rayon_core; -use std::thread; - -/// Creates a new thread and forwards information in thread locals to it. -/// The new thread runs the deadlock handler. -/// Must only be called when a deadlock is about to happen. -pub unsafe fn handle_deadlock() { - let registry = rayon_core::Registry::current(); - - let context = tls::get_tlv(); - assert!(context != 0); - rustc_data_structures::sync::assert_sync::>(); - let icx: &tls::ImplicitCtxt<'_, '_> = &*(context as *const tls::ImplicitCtxt<'_, '_>); - - let session_globals = rustc_span::SESSION_GLOBALS.with(|sg| sg as *const _); - let session_globals = &*session_globals; - thread::spawn(move || { - tls::enter_context(icx, |_| { - rustc_span::SESSION_GLOBALS - .set(session_globals, || tls::with(|tcx| tcx.queries.deadlock(tcx, ®istry))) - }); - }); -} diff --git a/compiler/rustc_middle/src/ty/query/mod.rs b/compiler/rustc_middle/src/ty/query/mod.rs index dd0723f200f..5a2c51f88cd 100644 --- a/compiler/rustc_middle/src/ty/query/mod.rs +++ b/compiler/rustc_middle/src/ty/query/mod.rs @@ -68,10 +68,6 @@ use rustc_query_system::query::*; mod stats; pub use self::stats::print_stats; -#[cfg(parallel_compiler)] -mod job; -#[cfg(parallel_compiler)] -pub use self::job::handle_deadlock; pub use rustc_query_system::query::{QueryInfo, QueryJob, QueryJobId}; mod keys; diff --git a/compiler/rustc_middle/src/ty/query/plumbing.rs b/compiler/rustc_middle/src/ty/query/plumbing.rs index 83dbe4875cf..8d006ad6564 100644 --- a/compiler/rustc_middle/src/ty/query/plumbing.rs +++ b/compiler/rustc_middle/src/ty/query/plumbing.rs @@ -592,7 +592,7 @@ macro_rules! define_queries_struct { } #[cfg(parallel_compiler)] - unsafe fn deadlock(&'tcx self, tcx: TyCtxt<'tcx>, registry: &rustc_rayon_core::Registry) { + pub unsafe fn deadlock(&'tcx self, tcx: TyCtxt<'tcx>, registry: &rustc_rayon_core::Registry) { let tcx = QueryCtxt { tcx, queries: self }; rustc_query_system::query::deadlock(tcx, registry) } From 6e4af4a2d19fe3a1e01c8acf23b6e3a4c0c6bd18 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 18 Jan 2021 22:21:29 +0100 Subject: [PATCH 13/23] Move definition of callbacks to parent module. --- compiler/rustc_middle/src/ty/query/mod.rs | 88 +++++++++++++++++++ .../rustc_middle/src/ty/query/plumbing.rs | 83 ----------------- 2 files changed, 88 insertions(+), 83 deletions(-) diff --git a/compiler/rustc_middle/src/ty/query/mod.rs b/compiler/rustc_middle/src/ty/query/mod.rs index 5a2c51f88cd..c090e2de1f4 100644 --- a/compiler/rustc_middle/src/ty/query/mod.rs +++ b/compiler/rustc_middle/src/ty/query/mod.rs @@ -86,6 +86,93 @@ pub use self::on_disk_cache::OnDiskCache; mod profiling_support; pub use self::profiling_support::alloc_self_profile_query_strings; +#[derive(Copy, Clone)] +pub struct TyCtxtAt<'tcx> { + pub tcx: TyCtxt<'tcx>, + pub span: Span, +} + +impl Deref for TyCtxtAt<'tcx> { + type Target = TyCtxt<'tcx>; + #[inline(always)] + fn deref(&self) -> &Self::Target { + &self.tcx + } +} + +#[derive(Copy, Clone)] +pub struct TyCtxtEnsure<'tcx> { + pub tcx: TyCtxt<'tcx>, +} + +impl TyCtxt<'tcx> { + /// Returns a transparent wrapper for `TyCtxt`, which ensures queries + /// are executed instead of just returning their results. + #[inline(always)] + pub fn ensure(self) -> TyCtxtEnsure<'tcx> { + TyCtxtEnsure { tcx: self } + } + + /// Returns a transparent wrapper for `TyCtxt` which uses + /// `span` as the location of queries performed through it. + #[inline(always)] + pub fn at(self, span: Span) -> TyCtxtAt<'tcx> { + TyCtxtAt { tcx: self, span } + } +} + +macro_rules! define_callbacks { + (<$tcx:tt> + $($(#[$attr:meta])* + [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => { + + impl TyCtxtEnsure<$tcx> { + $($(#[$attr])* + #[inline(always)] + pub fn $name(self, key: query_helper_param_ty!($($K)*)) { + let key = key.into_query_param(); + let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, |_| {}); + + let lookup = match cached { + Ok(()) => return, + Err(lookup) => lookup, + }; + + self.tcx.queries.$name(self.tcx, DUMMY_SP, key, lookup, QueryMode::Ensure); + })* + } + + impl TyCtxt<$tcx> { + $($(#[$attr])* + #[inline(always)] + #[must_use] + pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<$tcx> + { + self.at(DUMMY_SP).$name(key) + })* + } + + impl TyCtxtAt<$tcx> { + $($(#[$attr])* + #[inline(always)] + pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<$tcx> + { + let key = key.into_query_param(); + let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, |value| { + value.clone() + }); + + let lookup = match cached { + Ok(value) => return value, + Err(lookup) => lookup, + }; + + self.tcx.queries.$name(self.tcx, self.span, key, lookup, QueryMode::Get).unwrap() + })* + } + } +} + // Each of these queries corresponds to a function pointer field in the // `Providers` struct for requesting a value of that type, and a method // on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way @@ -99,6 +186,7 @@ pub use self::profiling_support::alloc_self_profile_query_strings; // as they will raise an fatal error on query cycles instead. rustc_query_append! { [define_queries!][<'tcx>] } +rustc_query_append! { [define_callbacks!][<'tcx>] } mod sealed { use super::{DefId, LocalDefId}; diff --git a/compiler/rustc_middle/src/ty/query/plumbing.rs b/compiler/rustc_middle/src/ty/query/plumbing.rs index 8d006ad6564..0f38de35e51 100644 --- a/compiler/rustc_middle/src/ty/query/plumbing.rs +++ b/compiler/rustc_middle/src/ty/query/plumbing.rs @@ -456,89 +456,6 @@ macro_rules! define_queries { } })* - #[derive(Copy, Clone)] - pub struct TyCtxtEnsure<'tcx> { - pub tcx: TyCtxt<'tcx>, - } - - impl TyCtxtEnsure<$tcx> { - $($(#[$attr])* - #[inline(always)] - pub fn $name(self, key: query_helper_param_ty!($($K)*)) { - let key = key.into_query_param(); - let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, |_| {}); - - let lookup = match cached { - Ok(()) => return, - Err(lookup) => lookup, - }; - - self.tcx.queries.$name(self.tcx, DUMMY_SP, key, lookup, QueryMode::Ensure); - })* - } - - #[derive(Copy, Clone)] - pub struct TyCtxtAt<'tcx> { - pub tcx: TyCtxt<'tcx>, - pub span: Span, - } - - impl Deref for TyCtxtAt<'tcx> { - type Target = TyCtxt<'tcx>; - #[inline(always)] - fn deref(&self) -> &Self::Target { - &self.tcx - } - } - - impl TyCtxt<$tcx> { - /// Returns a transparent wrapper for `TyCtxt`, which ensures queries - /// are executed instead of just returning their results. - #[inline(always)] - pub fn ensure(self) -> TyCtxtEnsure<$tcx> { - TyCtxtEnsure { - tcx: self, - } - } - - /// Returns a transparent wrapper for `TyCtxt` which uses - /// `span` as the location of queries performed through it. - #[inline(always)] - pub fn at(self, span: Span) -> TyCtxtAt<$tcx> { - TyCtxtAt { - tcx: self, - span - } - } - - $($(#[$attr])* - #[inline(always)] - #[must_use] - pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<$tcx> - { - self.at(DUMMY_SP).$name(key) - })* - } - - impl TyCtxtAt<$tcx> { - $($(#[$attr])* - #[inline(always)] - pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<$tcx> - { - let key = key.into_query_param(); - let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, |value| { - value.clone() - }); - - let lookup = match cached { - Ok(value) => return value, - Err(lookup) => lookup, - }; - - self.tcx.queries.$name(self.tcx, self.span, key, lookup, QueryMode::Get).unwrap() - })* - } - define_provider_struct! { tcx: $tcx, input: ($(([$($modifiers)*] [$name] [$($K)*] [$V]))*) From 3bd14c7bbee10aaff2466014ae1c2455010dfafe Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 18 Nov 2020 18:45:16 +0100 Subject: [PATCH 14/23] Select caching strategy per query. The per-Key choice was not used. --- compiler/rustc_middle/src/ty/query/keys.rs | 69 ------------------- .../rustc_middle/src/ty/query/plumbing.rs | 2 +- 2 files changed, 1 insertion(+), 70 deletions(-) diff --git a/compiler/rustc_middle/src/ty/query/keys.rs b/compiler/rustc_middle/src/ty/query/keys.rs index 6b4714b1bb8..2f76237e8fb 100644 --- a/compiler/rustc_middle/src/ty/query/keys.rs +++ b/compiler/rustc_middle/src/ty/query/keys.rs @@ -6,15 +6,12 @@ use crate::ty::fast_reject::SimplifiedType; use crate::ty::subst::{GenericArg, SubstsRef}; use crate::ty::{self, Ty, TyCtxt}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; -use rustc_query_system::query::DefaultCacheSelector; use rustc_span::symbol::{Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; /// The `Key` trait controls what types can legally be used as the key /// for a query. pub trait Key { - type CacheSelector; - /// Given an instance of this key, what crate is it referring to? /// This is used to find the provider. fn query_crate(&self) -> CrateNum; @@ -25,8 +22,6 @@ pub trait Key { } impl<'tcx> Key for ty::InstanceDef<'tcx> { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { LOCAL_CRATE } @@ -37,8 +32,6 @@ impl<'tcx> Key for ty::InstanceDef<'tcx> { } impl<'tcx> Key for ty::Instance<'tcx> { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { LOCAL_CRATE } @@ -49,8 +42,6 @@ impl<'tcx> Key for ty::Instance<'tcx> { } impl<'tcx> Key for mir::interpret::GlobalId<'tcx> { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { self.instance.query_crate() } @@ -61,8 +52,6 @@ impl<'tcx> Key for mir::interpret::GlobalId<'tcx> { } impl<'tcx> Key for mir::interpret::LitToConstInput<'tcx> { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { LOCAL_CRATE } @@ -73,8 +62,6 @@ impl<'tcx> Key for mir::interpret::LitToConstInput<'tcx> { } impl Key for CrateNum { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { *self } @@ -84,8 +71,6 @@ impl Key for CrateNum { } impl Key for LocalDefId { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { self.to_def_id().query_crate() } @@ -95,8 +80,6 @@ impl Key for LocalDefId { } impl Key for DefId { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { self.krate } @@ -106,8 +89,6 @@ impl Key for DefId { } impl Key for ty::WithOptConstParam { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { self.did.query_crate() } @@ -117,8 +98,6 @@ impl Key for ty::WithOptConstParam { } impl Key for (DefId, DefId) { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { self.0.krate } @@ -128,8 +107,6 @@ impl Key for (DefId, DefId) { } impl Key for (ty::Instance<'tcx>, LocalDefId) { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { self.0.query_crate() } @@ -139,8 +116,6 @@ impl Key for (ty::Instance<'tcx>, LocalDefId) { } impl Key for (DefId, LocalDefId) { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { self.0.krate } @@ -150,8 +125,6 @@ impl Key for (DefId, LocalDefId) { } impl Key for (LocalDefId, DefId) { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { LOCAL_CRATE } @@ -161,8 +134,6 @@ impl Key for (LocalDefId, DefId) { } impl Key for (DefId, Option) { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { self.0.krate } @@ -172,8 +143,6 @@ impl Key for (DefId, Option) { } impl Key for (DefId, LocalDefId, Ident) { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { self.0.krate } @@ -183,8 +152,6 @@ impl Key for (DefId, LocalDefId, Ident) { } impl Key for (CrateNum, DefId) { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { self.0 } @@ -194,8 +161,6 @@ impl Key for (CrateNum, DefId) { } impl Key for (DefId, SimplifiedType) { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { self.0.krate } @@ -205,8 +170,6 @@ impl Key for (DefId, SimplifiedType) { } impl<'tcx> Key for SubstsRef<'tcx> { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { LOCAL_CRATE } @@ -216,8 +179,6 @@ impl<'tcx> Key for SubstsRef<'tcx> { } impl<'tcx> Key for (DefId, SubstsRef<'tcx>) { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { self.0.krate } @@ -232,8 +193,6 @@ impl<'tcx> Key (ty::WithOptConstParam, SubstsRef<'tcx>), ) { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { (self.0).0.did.krate } @@ -243,8 +202,6 @@ impl<'tcx> Key } impl<'tcx> Key for (LocalDefId, DefId, SubstsRef<'tcx>) { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { LOCAL_CRATE } @@ -254,8 +211,6 @@ impl<'tcx> Key for (LocalDefId, DefId, SubstsRef<'tcx>) { } impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { self.1.def_id().krate } @@ -265,8 +220,6 @@ impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) { } impl<'tcx> Key for (&'tcx ty::Const<'tcx>, mir::Field) { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { LOCAL_CRATE } @@ -276,8 +229,6 @@ impl<'tcx> Key for (&'tcx ty::Const<'tcx>, mir::Field) { } impl<'tcx> Key for ty::PolyTraitRef<'tcx> { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { self.def_id().krate } @@ -287,8 +238,6 @@ impl<'tcx> Key for ty::PolyTraitRef<'tcx> { } impl<'tcx> Key for GenericArg<'tcx> { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { LOCAL_CRATE } @@ -298,8 +247,6 @@ impl<'tcx> Key for GenericArg<'tcx> { } impl<'tcx> Key for &'tcx ty::Const<'tcx> { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { LOCAL_CRATE } @@ -309,8 +256,6 @@ impl<'tcx> Key for &'tcx ty::Const<'tcx> { } impl<'tcx> Key for Ty<'tcx> { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { LOCAL_CRATE } @@ -320,8 +265,6 @@ impl<'tcx> Key for Ty<'tcx> { } impl<'tcx> Key for &'tcx ty::List> { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { LOCAL_CRATE } @@ -331,8 +274,6 @@ impl<'tcx> Key for &'tcx ty::List> { } impl<'tcx> Key for ty::ParamEnv<'tcx> { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { LOCAL_CRATE } @@ -342,8 +283,6 @@ impl<'tcx> Key for ty::ParamEnv<'tcx> { } impl<'tcx, T: Key> Key for ty::ParamEnvAnd<'tcx, T> { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { self.value.query_crate() } @@ -353,8 +292,6 @@ impl<'tcx, T: Key> Key for ty::ParamEnvAnd<'tcx, T> { } impl Key for Symbol { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { LOCAL_CRATE } @@ -366,8 +303,6 @@ impl Key for Symbol { /// Canonical query goals correspond to abstract trait operations that /// are not tied to any crate in particular. impl<'tcx, T> Key for Canonical<'tcx, T> { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { LOCAL_CRATE } @@ -378,8 +313,6 @@ impl<'tcx, T> Key for Canonical<'tcx, T> { } impl Key for (Symbol, u32, u32) { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { LOCAL_CRATE } @@ -390,8 +323,6 @@ impl Key for (Symbol, u32, u32) { } impl<'tcx> Key for (DefId, Ty<'tcx>, SubstsRef<'tcx>, ty::ParamEnv<'tcx>) { - type CacheSelector = DefaultCacheSelector; - fn query_crate(&self) -> CrateNum { LOCAL_CRATE } diff --git a/compiler/rustc_middle/src/ty/query/plumbing.rs b/compiler/rustc_middle/src/ty/query/plumbing.rs index 0f38de35e51..c1068528a18 100644 --- a/compiler/rustc_middle/src/ty/query/plumbing.rs +++ b/compiler/rustc_middle/src/ty/query/plumbing.rs @@ -263,7 +263,7 @@ macro_rules! is_eval_always { macro_rules! query_storage { ([][$K:ty, $V:ty]) => { - <<$K as Key>::CacheSelector as CacheSelector<$K, $V>>::Cache + >::Cache }; ([storage($ty:ty) $($rest:tt)*][$K:ty, $V:ty]) => { <$ty as CacheSelector<$K, $V>>::Cache From b27266fdb20dd6f6d58428bcf15771dbaeb18d01 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 18 Jan 2021 23:53:42 +0100 Subject: [PATCH 15/23] Use a QueryContext for try_mark_green. --- .../rustc_codegen_cranelift/src/driver/aot.rs | 6 +- compiler/rustc_codegen_ssa/src/base.rs | 2 +- .../rustc_middle/src/dep_graph/dep_node.rs | 2 +- compiler/rustc_middle/src/dep_graph/mod.rs | 95 ------------------- compiler/rustc_middle/src/ty/query/mod.rs | 5 + .../rustc_middle/src/ty/query/plumbing.rs | 91 +++++++++++++++++- .../rustc_query_system/src/dep_graph/graph.rs | 8 +- .../rustc_query_system/src/dep_graph/mod.rs | 24 ----- compiler/rustc_query_system/src/query/mod.rs | 24 ++++- .../rustc_query_system/src/query/plumbing.rs | 19 ++-- 10 files changed, 133 insertions(+), 143 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index c9e503a43b9..39781e2482a 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -465,9 +465,5 @@ fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> CguR cgu.name() ); - if tcx.dep_graph.try_mark_green(tcx, &dep_node).is_some() { - CguReuse::PreLto - } else { - CguReuse::No - } + if tcx.try_mark_green(&dep_node) { CguReuse::PreLto } else { CguReuse::No } } diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 658ad3c375d..08e31c3b37f 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -867,7 +867,7 @@ fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> CguR cgu.name() ); - if tcx.dep_graph.try_mark_green(tcx, &dep_node).is_some() { + if tcx.try_mark_green(&dep_node) { // We can re-use either the pre- or the post-thinlto state. If no LTO is // being performed then we can use post-LTO artifacts, otherwise we must // reuse pre-LTO artifacts diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 14a10e84e9c..823bcebe23b 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -135,7 +135,7 @@ pub struct DepKindStruct { /// then `force_from_dep_node()` should not fail for it. Otherwise, you can just /// add it to the "We don't have enough information to reconstruct..." group in /// the match below. - pub(super) force_from_dep_node: fn(tcx: TyCtxt<'_>, dep_node: &DepNode) -> bool, + pub(crate) force_from_dep_node: fn(tcx: TyCtxt<'_>, dep_node: &DepNode) -> bool, /// Invoke a query to put the on-disk cached value in memory. pub(crate) try_load_from_on_disk_cache: fn(QueryCtxt<'_>, &DepNode), diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index 193bf3c9131..da9b0b7e48a 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -2,9 +2,6 @@ use crate::ich::StableHashingContext; use crate::ty::{self, TyCtxt}; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sync::Lock; -use rustc_data_structures::thin_vec::ThinVec; -use rustc_errors::Diagnostic; -use rustc_hir::def_id::LocalDefId; mod dep_node; @@ -116,99 +113,7 @@ impl<'tcx> DepContext for TyCtxt<'tcx> { &self.dep_graph } - fn try_force_from_dep_node(&self, dep_node: &DepNode) -> bool { - // FIXME: This match is just a workaround for incremental bugs and should - // be removed. https://github.com/rust-lang/rust/issues/62649 is one such - // bug that must be fixed before removing this. - match dep_node.kind { - DepKind::hir_owner | DepKind::hir_owner_nodes => { - if let Some(def_id) = dep_node.extract_def_id(*self) { - if !def_id_corresponds_to_hir_dep_node(*self, def_id.expect_local()) { - // This `DefPath` does not have a - // corresponding `DepNode` (e.g. a - // struct field), and the ` DefPath` - // collided with the `DefPath` of a - // proper item that existed in the - // previous compilation session. - // - // Since the given `DefPath` does not - // denote the item that previously - // existed, we just fail to mark green. - return false; - } - } else { - // If the node does not exist anymore, we - // just fail to mark green. - return false; - } - } - _ => { - // For other kinds of nodes it's OK to be - // forced. - } - } - - debug!("try_force_from_dep_node({:?}) --- trying to force", dep_node); - - // We must avoid ever having to call `force_from_dep_node()` for a - // `DepNode::codegen_unit`: - // Since we cannot reconstruct the query key of a `DepNode::codegen_unit`, we - // would always end up having to evaluate the first caller of the - // `codegen_unit` query that *is* reconstructible. This might very well be - // the `compile_codegen_unit` query, thus re-codegenning the whole CGU just - // to re-trigger calling the `codegen_unit` query with the right key. At - // that point we would already have re-done all the work we are trying to - // avoid doing in the first place. - // The solution is simple: Just explicitly call the `codegen_unit` query for - // each CGU, right after partitioning. This way `try_mark_green` will always - // hit the cache instead of having to go through `force_from_dep_node`. - // This assertion makes sure, we actually keep applying the solution above. - debug_assert!( - dep_node.kind != DepKind::codegen_unit, - "calling force_from_dep_node() on DepKind::codegen_unit" - ); - - (dep_node.kind.force_from_dep_node)(*self, dep_node) - } - - fn has_errors_or_delayed_span_bugs(&self) -> bool { - self.sess.has_errors_or_delayed_span_bugs() - } - - fn diagnostic(&self) -> &rustc_errors::Handler { - self.sess.diagnostic() - } - - // Interactions with on_disk_cache - fn load_diagnostics(&self, prev_dep_node_index: SerializedDepNodeIndex) -> Vec { - self.on_disk_cache - .as_ref() - .map(|c| c.load_diagnostics(*self, prev_dep_node_index)) - .unwrap_or_default() - } - - fn store_diagnostics(&self, dep_node_index: DepNodeIndex, diagnostics: ThinVec) { - if let Some(c) = self.on_disk_cache.as_ref() { - c.store_diagnostics(dep_node_index, diagnostics) - } - } - - fn store_diagnostics_for_anon_node( - &self, - dep_node_index: DepNodeIndex, - diagnostics: ThinVec, - ) { - if let Some(c) = self.on_disk_cache.as_ref() { - c.store_diagnostics_for_anon_node(dep_node_index, diagnostics) - } - } - fn profiler(&self) -> &SelfProfilerRef { &self.prof } } - -fn def_id_corresponds_to_hir_dep_node(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { - let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - def_id == hir_id.owner -} diff --git a/compiler/rustc_middle/src/ty/query/mod.rs b/compiler/rustc_middle/src/ty/query/mod.rs index c090e2de1f4..970deb659fa 100644 --- a/compiler/rustc_middle/src/ty/query/mod.rs +++ b/compiler/rustc_middle/src/ty/query/mod.rs @@ -119,6 +119,11 @@ impl TyCtxt<'tcx> { pub fn at(self, span: Span) -> TyCtxtAt<'tcx> { TyCtxtAt { tcx: self, span } } + + pub fn try_mark_green(self, dep_node: &dep_graph::DepNode) -> bool { + let qcx = QueryCtxt { tcx: self, queries: self.queries }; + self.dep_graph.try_mark_green(qcx, dep_node).is_some() + } } macro_rules! define_callbacks { diff --git a/compiler/rustc_middle/src/ty/query/plumbing.rs b/compiler/rustc_middle/src/ty/query/plumbing.rs index c1068528a18..23eb7ce3248 100644 --- a/compiler/rustc_middle/src/ty/query/plumbing.rs +++ b/compiler/rustc_middle/src/ty/query/plumbing.rs @@ -2,7 +2,7 @@ //! generate the actual methods on tcx which find and execute the provider, //! manage the caches, and so forth. -use crate::dep_graph; +use crate::dep_graph::{self, DepKind, DepNode, DepNodeExt, DepNodeIndex, SerializedDepNodeIndex}; use crate::ty::query::{on_disk_cache, Queries, Query}; use crate::ty::tls::{self, ImplicitCtxt}; use crate::ty::{self, TyCtxt}; @@ -72,6 +72,95 @@ impl QueryContext for QueryCtxt<'tcx> { (dep_node.kind.try_load_from_on_disk_cache)(*self, dep_node) } + fn try_force_from_dep_node(&self, dep_node: &DepNode) -> bool { + // FIXME: This match is just a workaround for incremental bugs and should + // be removed. https://github.com/rust-lang/rust/issues/62649 is one such + // bug that must be fixed before removing this. + match dep_node.kind { + DepKind::hir_owner | DepKind::hir_owner_nodes => { + if let Some(def_id) = dep_node.extract_def_id(**self) { + let def_id = def_id.expect_local(); + let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id); + if def_id != hir_id.owner { + // This `DefPath` does not have a + // corresponding `DepNode` (e.g. a + // struct field), and the ` DefPath` + // collided with the `DefPath` of a + // proper item that existed in the + // previous compilation session. + // + // Since the given `DefPath` does not + // denote the item that previously + // existed, we just fail to mark green. + return false; + } + } else { + // If the node does not exist anymore, we + // just fail to mark green. + return false; + } + } + _ => { + // For other kinds of nodes it's OK to be + // forced. + } + } + + debug!("try_force_from_dep_node({:?}) --- trying to force", dep_node); + + // We must avoid ever having to call `force_from_dep_node()` for a + // `DepNode::codegen_unit`: + // Since we cannot reconstruct the query key of a `DepNode::codegen_unit`, we + // would always end up having to evaluate the first caller of the + // `codegen_unit` query that *is* reconstructible. This might very well be + // the `compile_codegen_unit` query, thus re-codegenning the whole CGU just + // to re-trigger calling the `codegen_unit` query with the right key. At + // that point we would already have re-done all the work we are trying to + // avoid doing in the first place. + // The solution is simple: Just explicitly call the `codegen_unit` query for + // each CGU, right after partitioning. This way `try_mark_green` will always + // hit the cache instead of having to go through `force_from_dep_node`. + // This assertion makes sure, we actually keep applying the solution above. + debug_assert!( + dep_node.kind != DepKind::codegen_unit, + "calling force_from_dep_node() on DepKind::codegen_unit" + ); + + (dep_node.kind.force_from_dep_node)(**self, dep_node) + } + + fn has_errors_or_delayed_span_bugs(&self) -> bool { + self.sess.has_errors_or_delayed_span_bugs() + } + + fn diagnostic(&self) -> &rustc_errors::Handler { + self.sess.diagnostic() + } + + // Interactions with on_disk_cache + fn load_diagnostics(&self, prev_dep_node_index: SerializedDepNodeIndex) -> Vec { + self.on_disk_cache + .as_ref() + .map(|c| c.load_diagnostics(**self, prev_dep_node_index)) + .unwrap_or_default() + } + + fn store_diagnostics(&self, dep_node_index: DepNodeIndex, diagnostics: ThinVec) { + if let Some(c) = self.on_disk_cache.as_ref() { + c.store_diagnostics(dep_node_index, diagnostics) + } + } + + fn store_diagnostics_for_anon_node( + &self, + dep_node_index: DepNodeIndex, + diagnostics: ThinVec, + ) { + if let Some(c) = self.on_disk_cache.as_ref() { + c.store_diagnostics_for_anon_node(dep_node_index, diagnostics) + } + } + /// Executes a job by changing the `ImplicitCtxt` to point to the /// new query job while it executes. It returns the diagnostics /// captured during execution and the actual result. diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 8b0ab33f3f5..f579052c106 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -587,7 +587,7 @@ impl DepGraph { /// A node will have an index, when it's already been marked green, or when we can mark it /// green. This function will mark the current task as a reader of the specified node, when /// a node index can be found for that node. - pub fn try_mark_green_and_read>( + pub fn try_mark_green_and_read>( &self, tcx: Ctxt, dep_node: &DepNode, @@ -599,7 +599,7 @@ impl DepGraph { }) } - pub fn try_mark_green>( + pub fn try_mark_green>( &self, tcx: Ctxt, dep_node: &DepNode, @@ -627,7 +627,7 @@ impl DepGraph { } /// Try to mark a dep-node which existed in the previous compilation session as green. - fn try_mark_previous_green>( + fn try_mark_previous_green>( &self, tcx: Ctxt, data: &DepGraphData, @@ -811,7 +811,7 @@ impl DepGraph { /// This may be called concurrently on multiple threads for the same dep node. #[cold] #[inline(never)] - fn emit_diagnostics>( + fn emit_diagnostics>( &self, tcx: Ctxt, data: &DepGraphData, diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs index a1a6ca9dacc..a647381fb03 100644 --- a/compiler/rustc_query_system/src/dep_graph/mod.rs +++ b/compiler/rustc_query_system/src/dep_graph/mod.rs @@ -13,8 +13,6 @@ pub use serialized::{SerializedDepGraph, SerializedDepNodeIndex}; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sync::Lock; -use rustc_data_structures::thin_vec::ThinVec; -use rustc_errors::Diagnostic; use std::fmt; use std::hash::Hash; @@ -32,30 +30,8 @@ pub trait DepContext: Copy { /// Access the DepGraph. fn dep_graph(&self) -> &DepGraph; - /// Try to force a dep node to execute and see if it's green. - fn try_force_from_dep_node(&self, dep_node: &DepNode) -> bool; - fn register_reused_dep_node(&self, dep_node: &DepNode); - /// Return whether the current session is tainted by errors. - fn has_errors_or_delayed_span_bugs(&self) -> bool; - - /// Return the diagnostic handler. - fn diagnostic(&self) -> &rustc_errors::Handler; - - /// Load diagnostics associated to the node in the previous session. - fn load_diagnostics(&self, prev_dep_node_index: SerializedDepNodeIndex) -> Vec; - - /// Register diagnostics for the given node, for use in next session. - fn store_diagnostics(&self, dep_node_index: DepNodeIndex, diagnostics: ThinVec); - - /// Register diagnostics for the given node, for use in next session. - fn store_diagnostics_for_anon_node( - &self, - dep_node_index: DepNodeIndex, - diagnostics: ThinVec, - ); - /// Access the profiler. fn profiler(&self) -> &SelfProfilerRef; } diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index 8d5c9d7bea7..c935e1b9c5c 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -14,7 +14,7 @@ pub use self::caches::{ mod config; pub use self::config::{QueryAccessors, QueryConfig, QueryDescription}; -use crate::dep_graph::{DepNode, HasDepContext}; +use crate::dep_graph::{DepNode, DepNodeIndex, HasDepContext, SerializedDepNodeIndex}; use crate::query::job::QueryMap; use rustc_data_structures::stable_hasher::HashStable; @@ -40,6 +40,28 @@ pub trait QueryContext: HasDepContext { /// Load data from the on-disk cache. fn try_load_from_on_disk_cache(&self, dep_node: &DepNode); + /// Try to force a dep node to execute and see if it's green. + fn try_force_from_dep_node(&self, dep_node: &DepNode) -> bool; + + /// Return whether the current session is tainted by errors. + fn has_errors_or_delayed_span_bugs(&self) -> bool; + + /// Return the diagnostic handler. + fn diagnostic(&self) -> &rustc_errors::Handler; + + /// Load diagnostics associated to the node in the previous session. + fn load_diagnostics(&self, prev_dep_node_index: SerializedDepNodeIndex) -> Vec; + + /// Register diagnostics for the given node, for use in next session. + fn store_diagnostics(&self, dep_node_index: DepNodeIndex, diagnostics: ThinVec); + + /// Register diagnostics for the given node, for use in next session. + fn store_diagnostics_for_anon_node( + &self, + dep_node_index: DepNodeIndex, + diagnostics: ThinVec, + ); + /// Executes a job by changing the `ImplicitCtxt` to point to the /// new query job while it executes. It returns the diagnostics /// captured during execution and the actual result. diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 89f1e6511e3..bd22ee2c18b 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -460,7 +460,7 @@ where tcx.dep_context().dep_graph().read_index(dep_node_index); if unlikely!(!diagnostics.is_empty()) { - tcx.dep_context().store_diagnostics_for_anon_node(dep_node_index, diagnostics); + tcx.store_diagnostics_for_anon_node(dep_node_index, diagnostics); } return job.complete(result, dep_node_index); @@ -473,10 +473,7 @@ where // promoted to the current session during // `try_mark_green()`, so we can ignore them here. let loaded = tcx.start_query(job.id, None, || { - let marked = tcx - .dep_context() - .dep_graph() - .try_mark_green_and_read(*tcx.dep_context(), &dep_node); + let marked = tcx.dep_context().dep_graph().try_mark_green_and_read(tcx, &dep_node); marked.map(|(prev_dep_node_index, dep_node_index)| { ( load_from_disk_and_cache_in_memory( @@ -641,7 +638,7 @@ where prof_timer.finish_with_query_invocation_id(dep_node_index.into()); if unlikely!(!diagnostics.is_empty()) && dep_node.kind != DepKind::NULL { - tcx.dep_context().store_diagnostics(dep_node_index, diagnostics); + tcx.store_diagnostics(dep_node_index, diagnostics); } let result = job.complete(result, dep_node_index); @@ -676,7 +673,7 @@ where /// /// Note: The optimization is only available during incr. comp. #[inline(never)] -fn ensure_must_run(tcx: CTX::DepContext, key: &K, query: &QueryVtable) -> bool +fn ensure_must_run(tcx: CTX, key: &K, query: &QueryVtable) -> bool where K: crate::dep_graph::DepNodeParams, CTX: QueryContext, @@ -688,9 +685,9 @@ where // Ensuring an anonymous query makes no sense assert!(!query.anon); - let dep_node = query.to_dep_node(tcx, key); + let dep_node = query.to_dep_node(*tcx.dep_context(), key); - match tcx.dep_graph().try_mark_green_and_read(tcx, &dep_node) { + match tcx.dep_context().dep_graph().try_mark_green_and_read(tcx, &dep_node) { None => { // A None return from `try_mark_green_and_read` means that this is either // a new dep node or that the dep node has already been marked red. @@ -701,7 +698,7 @@ where true } Some((_, dep_node_index)) => { - tcx.profiler().query_cache_hit(dep_node_index.into()); + tcx.dep_context().profiler().query_cache_hit(dep_node_index.into()); false } } @@ -768,7 +765,7 @@ where { let query = &Q::VTABLE; if let QueryMode::Ensure = mode { - if !ensure_must_run(*tcx.dep_context(), &key, query) { + if !ensure_must_run(tcx, &key, query) { return None; } } From 1ac21e4571320c24e62044fabbcdb8886f45e375 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 19 Jan 2021 18:24:08 +0100 Subject: [PATCH 16/23] Use QueryCtxt in DepKindStruct. --- compiler/rustc_middle/src/dep_graph/dep_node.rs | 13 ++++--------- compiler/rustc_middle/src/ty/query/plumbing.rs | 4 ++-- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 823bcebe23b..063a57e484f 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -135,7 +135,7 @@ pub struct DepKindStruct { /// then `force_from_dep_node()` should not fail for it. Otherwise, you can just /// add it to the "We don't have enough information to reconstruct..." group in /// the match below. - pub(crate) force_from_dep_node: fn(tcx: TyCtxt<'_>, dep_node: &DepNode) -> bool, + pub(crate) force_from_dep_node: fn(tcx: QueryCtxt<'_>, dep_node: &DepNode) -> bool, /// Invoke a query to put the on-disk cached value in memory. pub(crate) try_load_from_on_disk_cache: fn(QueryCtxt<'_>, &DepNode), @@ -251,7 +251,7 @@ pub mod dep_kind { as DepNodeParams>>::recover(tcx, dep_node) } - fn force_from_dep_node(tcx: TyCtxt<'_>, dep_node: &DepNode) -> bool { + fn force_from_dep_node(tcx: QueryCtxt<'_>, dep_node: &DepNode) -> bool { if is_anon { return false; } @@ -260,13 +260,8 @@ pub mod dep_kind { return false; } - if let Some(key) = recover(tcx, dep_node) { - force_query::, _>( - QueryCtxt { tcx, queries: tcx.queries }, - key, - DUMMY_SP, - *dep_node - ); + if let Some(key) = recover(*tcx, dep_node) { + force_query::, _>(tcx, key, DUMMY_SP, *dep_node); return true; } diff --git a/compiler/rustc_middle/src/ty/query/plumbing.rs b/compiler/rustc_middle/src/ty/query/plumbing.rs index 23eb7ce3248..66ed3adb65a 100644 --- a/compiler/rustc_middle/src/ty/query/plumbing.rs +++ b/compiler/rustc_middle/src/ty/query/plumbing.rs @@ -68,7 +68,7 @@ impl QueryContext for QueryCtxt<'tcx> { self.queries.try_collect_active_jobs() } - fn try_load_from_on_disk_cache(&self, dep_node: &dep_graph::DepNode) { + fn try_load_from_on_disk_cache(&self, dep_node: &DepNode) { (dep_node.kind.try_load_from_on_disk_cache)(*self, dep_node) } @@ -126,7 +126,7 @@ impl QueryContext for QueryCtxt<'tcx> { "calling force_from_dep_node() on DepKind::codegen_unit" ); - (dep_node.kind.force_from_dep_node)(**self, dep_node) + (dep_node.kind.force_from_dep_node)(*self, dep_node) } fn has_errors_or_delayed_span_bugs(&self) -> bool { From cdc0b199a904fe0318c7a5cf55a610c2ded6ca68 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 19 Jan 2021 19:07:06 +0100 Subject: [PATCH 17/23] Split DepKindStruct in two. --- .../rustc_middle/src/dep_graph/dep_node.rs | 108 +------------ compiler/rustc_middle/src/dep_graph/mod.rs | 1 + compiler/rustc_middle/src/lib.rs | 1 + compiler/rustc_middle/src/ty/query/mod.rs | 1 + .../rustc_middle/src/ty/query/plumbing.rs | 143 +++++++++++++++++- 5 files changed, 151 insertions(+), 103 deletions(-) diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 063a57e484f..ba9d0a40732 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -55,7 +55,6 @@ //! //! [dependency graph]: https://rustc-dev-guide.rust-lang.org/query.html -use crate::ty::query::QueryCtxt; use crate::ty::TyCtxt; use rustc_data_structures::fingerprint::Fingerprint; @@ -63,7 +62,6 @@ use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX}; use rustc_hir::definitions::DefPathHash; use rustc_hir::HirId; use rustc_span::symbol::Symbol; -use rustc_span::DUMMY_SP; use std::hash::Hash; pub use rustc_query_system::dep_graph::{DepContext, DepNodeParams}; @@ -92,53 +90,6 @@ pub struct DepKindStruct { // FIXME: Make this a simple boolean once DepNodeParams::can_reconstruct_query_key // can be made a specialized associated const. can_reconstruct_query_key: fn() -> bool, - - /// The red/green evaluation system will try to mark a specific DepNode in the - /// dependency graph as green by recursively trying to mark the dependencies of - /// that `DepNode` as green. While doing so, it will sometimes encounter a `DepNode` - /// where we don't know if it is red or green and we therefore actually have - /// to recompute its value in order to find out. Since the only piece of - /// information that we have at that point is the `DepNode` we are trying to - /// re-evaluate, we need some way to re-run a query from just that. This is what - /// `force_from_dep_node()` implements. - /// - /// In the general case, a `DepNode` consists of a `DepKind` and an opaque - /// GUID/fingerprint that will uniquely identify the node. This GUID/fingerprint - /// is usually constructed by computing a stable hash of the query-key that the - /// `DepNode` corresponds to. Consequently, it is not in general possible to go - /// back from hash to query-key (since hash functions are not reversible). For - /// this reason `force_from_dep_node()` is expected to fail from time to time - /// because we just cannot find out, from the `DepNode` alone, what the - /// corresponding query-key is and therefore cannot re-run the query. - /// - /// The system deals with this case letting `try_mark_green` fail which forces - /// the root query to be re-evaluated. - /// - /// Now, if `force_from_dep_node()` would always fail, it would be pretty useless. - /// Fortunately, we can use some contextual information that will allow us to - /// reconstruct query-keys for certain kinds of `DepNode`s. In particular, we - /// enforce by construction that the GUID/fingerprint of certain `DepNode`s is a - /// valid `DefPathHash`. Since we also always build a huge table that maps every - /// `DefPathHash` in the current codebase to the corresponding `DefId`, we have - /// everything we need to re-run the query. - /// - /// Take the `mir_promoted` query as an example. Like many other queries, it - /// just has a single parameter: the `DefId` of the item it will compute the - /// validated MIR for. Now, when we call `force_from_dep_node()` on a `DepNode` - /// with kind `MirValidated`, we know that the GUID/fingerprint of the `DepNode` - /// is actually a `DefPathHash`, and can therefore just look up the corresponding - /// `DefId` in `tcx.def_path_hash_to_def_id`. - /// - /// When you implement a new query, it will likely have a corresponding new - /// `DepKind`, and you'll have to support it here in `force_from_dep_node()`. As - /// a rule of thumb, if your query takes a `DefId` or `LocalDefId` as sole parameter, - /// then `force_from_dep_node()` should not fail for it. Otherwise, you can just - /// add it to the "We don't have enough information to reconstruct..." group in - /// the match below. - pub(crate) force_from_dep_node: fn(tcx: QueryCtxt<'_>, dep_node: &DepNode) -> bool, - - /// Invoke a query to put the on-disk cached value in memory. - pub(crate) try_load_from_on_disk_cache: fn(QueryCtxt<'_>, &DepNode), } impl std::ops::Deref for DepKind { @@ -197,8 +148,7 @@ macro_rules! contains_eval_always_attr { #[allow(non_upper_case_globals)] pub mod dep_kind { use super::*; - use crate::ty::query::{queries, query_keys}; - use rustc_query_system::query::{force_query, QueryDescription}; + use crate::ty::query::query_keys; // We use this for most things when incr. comp. is turned off. pub const Null: DepKindStruct = DepKindStruct { @@ -207,8 +157,6 @@ pub mod dep_kind { is_eval_always: false, can_reconstruct_query_key: || true, - force_from_dep_node: |_, dep_node| bug!("force_from_dep_node: encountered {:?}", dep_node), - try_load_from_on_disk_cache: |_, _| {}, }; pub const TraitSelect: DepKindStruct = DepKindStruct { @@ -217,8 +165,6 @@ pub mod dep_kind { is_eval_always: false, can_reconstruct_query_key: || true, - force_from_dep_node: |_, _| false, - try_load_from_on_disk_cache: |_, _| {}, }; pub const CompileCodegenUnit: DepKindStruct = DepKindStruct { @@ -227,8 +173,6 @@ pub mod dep_kind { is_eval_always: false, can_reconstruct_query_key: || false, - force_from_dep_node: |_, _| false, - try_load_from_on_disk_cache: |_, _| {}, }; macro_rules! define_query_dep_kinds { @@ -247,54 +191,11 @@ pub mod dep_kind { ::can_reconstruct_query_key() } - fn recover<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option> { - as DepNodeParams>>::recover(tcx, dep_node) - } - - fn force_from_dep_node(tcx: QueryCtxt<'_>, dep_node: &DepNode) -> bool { - if is_anon { - return false; - } - - if !can_reconstruct_query_key() { - return false; - } - - if let Some(key) = recover(*tcx, dep_node) { - force_query::, _>(tcx, key, DUMMY_SP, *dep_node); - return true; - } - - false - } - - fn try_load_from_on_disk_cache(tcx: QueryCtxt<'_>, dep_node: &DepNode) { - if is_anon { - return - } - - if !can_reconstruct_query_key() { - return - } - - debug_assert!(tcx.dep_graph - .node_color(dep_node) - .map(|c| c.is_green()) - .unwrap_or(false)); - - let key = recover(*tcx, dep_node).unwrap_or_else(|| panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash)); - if queries::$variant::cache_on_disk(tcx, &key, None) { - let _ = tcx.$variant(key); - } - } - DepKindStruct { has_params, is_anon, is_eval_always, can_reconstruct_query_key, - force_from_dep_node, - try_load_from_on_disk_cache, } };)* ); @@ -310,7 +211,12 @@ macro_rules! define_dep_nodes { $variant:ident $(( $tuple_arg_ty:ty $(,)? ))* ,)* ) => ( - static DEP_KINDS: &[DepKindStruct] = &[ $(dep_kind::$variant),* ]; + #[macro_export] + macro_rules! make_dep_kind_array { + ($mod:ident) => {[ $(($mod::$variant),)* ]}; + } + + static DEP_KINDS: &[DepKindStruct] = &make_dep_kind_array!(dep_kind); /// This enum serves as an index into the `DEP_KINDS` array. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Encodable, Decodable)] diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index da9b0b7e48a..d862db2674e 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -3,6 +3,7 @@ use crate::ty::{self, TyCtxt}; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sync::Lock; +#[macro_use] mod dep_node; pub use rustc_query_system::dep_graph::{ diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 6ae83a7f667..d9e88265050 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -76,6 +76,7 @@ pub mod query; #[macro_use] pub mod arena; +#[macro_use] pub mod dep_graph; pub mod hir; pub mod ich; diff --git a/compiler/rustc_middle/src/ty/query/mod.rs b/compiler/rustc_middle/src/ty/query/mod.rs index 970deb659fa..a2f3c6eedcb 100644 --- a/compiler/rustc_middle/src/ty/query/mod.rs +++ b/compiler/rustc_middle/src/ty/query/mod.rs @@ -62,6 +62,7 @@ use std::sync::Arc; #[macro_use] mod plumbing; pub use plumbing::QueryCtxt; +use plumbing::QueryStruct; pub(crate) use rustc_query_system::query::CycleError; use rustc_query_system::query::*; diff --git a/compiler/rustc_middle/src/ty/query/plumbing.rs b/compiler/rustc_middle/src/ty/query/plumbing.rs index 66ed3adb65a..18ae6318a00 100644 --- a/compiler/rustc_middle/src/ty/query/plumbing.rs +++ b/compiler/rustc_middle/src/ty/query/plumbing.rs @@ -69,7 +69,8 @@ impl QueryContext for QueryCtxt<'tcx> { } fn try_load_from_on_disk_cache(&self, dep_node: &DepNode) { - (dep_node.kind.try_load_from_on_disk_cache)(*self, dep_node) + let cb = &super::QUERY_CALLBACKS[dep_node.kind as usize]; + (cb.try_load_from_on_disk_cache)(*self, dep_node) } fn try_force_from_dep_node(&self, dep_node: &DepNode) -> bool { @@ -126,7 +127,8 @@ impl QueryContext for QueryCtxt<'tcx> { "calling force_from_dep_node() on DepKind::codegen_unit" ); - (dep_node.kind.force_from_dep_node)(*self, dep_node) + let cb = &super::QUERY_CALLBACKS[dep_node.kind as usize]; + (cb.force_from_dep_node)(*self, dep_node) } fn has_errors_or_delayed_span_bugs(&self) -> bool { @@ -307,6 +309,60 @@ impl<'tcx> Queries<'tcx> { } } +/// This struct stores metadata about each Query. +/// +/// Information is retrieved by indexing the `QUERIES` array using the integer value +/// of the `DepKind`. Overall, this allows to implement `QueryContext` using this manual +/// jump table instead of large matches. +pub struct QueryStruct { + /// The red/green evaluation system will try to mark a specific DepNode in the + /// dependency graph as green by recursively trying to mark the dependencies of + /// that `DepNode` as green. While doing so, it will sometimes encounter a `DepNode` + /// where we don't know if it is red or green and we therefore actually have + /// to recompute its value in order to find out. Since the only piece of + /// information that we have at that point is the `DepNode` we are trying to + /// re-evaluate, we need some way to re-run a query from just that. This is what + /// `force_from_dep_node()` implements. + /// + /// In the general case, a `DepNode` consists of a `DepKind` and an opaque + /// GUID/fingerprint that will uniquely identify the node. This GUID/fingerprint + /// is usually constructed by computing a stable hash of the query-key that the + /// `DepNode` corresponds to. Consequently, it is not in general possible to go + /// back from hash to query-key (since hash functions are not reversible). For + /// this reason `force_from_dep_node()` is expected to fail from time to time + /// because we just cannot find out, from the `DepNode` alone, what the + /// corresponding query-key is and therefore cannot re-run the query. + /// + /// The system deals with this case letting `try_mark_green` fail which forces + /// the root query to be re-evaluated. + /// + /// Now, if `force_from_dep_node()` would always fail, it would be pretty useless. + /// Fortunately, we can use some contextual information that will allow us to + /// reconstruct query-keys for certain kinds of `DepNode`s. In particular, we + /// enforce by construction that the GUID/fingerprint of certain `DepNode`s is a + /// valid `DefPathHash`. Since we also always build a huge table that maps every + /// `DefPathHash` in the current codebase to the corresponding `DefId`, we have + /// everything we need to re-run the query. + /// + /// Take the `mir_promoted` query as an example. Like many other queries, it + /// just has a single parameter: the `DefId` of the item it will compute the + /// validated MIR for. Now, when we call `force_from_dep_node()` on a `DepNode` + /// with kind `MirValidated`, we know that the GUID/fingerprint of the `DepNode` + /// is actually a `DefPathHash`, and can therefore just look up the corresponding + /// `DefId` in `tcx.def_path_hash_to_def_id`. + /// + /// When you implement a new query, it will likely have a corresponding new + /// `DepKind`, and you'll have to support it here in `force_from_dep_node()`. As + /// a rule of thumb, if your query takes a `DefId` or `LocalDefId` as sole parameter, + /// then `force_from_dep_node()` should not fail for it. Otherwise, you can just + /// add it to the "We don't have enough information to reconstruct..." group in + /// the match below. + pub(crate) force_from_dep_node: fn(tcx: QueryCtxt<'_>, dep_node: &DepNode) -> bool, + + /// Invoke a query to put the on-disk cached value in memory. + pub(crate) try_load_from_on_disk_cache: fn(QueryCtxt<'_>, &DepNode), +} + macro_rules! handle_cycle_error { ([][$tcx: expr, $error:expr]) => {{ $tcx.report_cycle($error).emit(); @@ -545,6 +601,89 @@ macro_rules! define_queries { } })* + #[allow(non_upper_case_globals)] + pub mod query_callbacks { + use super::*; + use crate::dep_graph::DepNode; + use crate::ty::query::{queries, query_keys}; + use rustc_query_system::dep_graph::DepNodeParams; + use rustc_query_system::query::{force_query, QueryDescription}; + + // We use this for most things when incr. comp. is turned off. + pub const Null: QueryStruct = QueryStruct { + force_from_dep_node: |_, dep_node| bug!("force_from_dep_node: encountered {:?}", dep_node), + try_load_from_on_disk_cache: |_, _| {}, + }; + + pub const TraitSelect: QueryStruct = QueryStruct { + force_from_dep_node: |_, _| false, + try_load_from_on_disk_cache: |_, _| {}, + }; + + pub const CompileCodegenUnit: QueryStruct = QueryStruct { + force_from_dep_node: |_, _| false, + try_load_from_on_disk_cache: |_, _| {}, + }; + + $(pub const $name: QueryStruct = { + const is_anon: bool = is_anon!([$($modifiers)*]); + + #[inline(always)] + fn can_reconstruct_query_key() -> bool { + as DepNodeParams>> + ::can_reconstruct_query_key() + } + + fn recover<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option> { + as DepNodeParams>>::recover(tcx, dep_node) + } + + fn force_from_dep_node(tcx: QueryCtxt<'_>, dep_node: &DepNode) -> bool { + if is_anon { + return false; + } + + if !can_reconstruct_query_key() { + return false; + } + + if let Some(key) = recover(*tcx, dep_node) { + force_query::, _>(tcx, key, DUMMY_SP, *dep_node); + return true; + } + + false + } + + fn try_load_from_on_disk_cache(tcx: QueryCtxt<'_>, dep_node: &DepNode) { + if is_anon { + return + } + + if !can_reconstruct_query_key() { + return + } + + debug_assert!(tcx.dep_graph + .node_color(dep_node) + .map(|c| c.is_green()) + .unwrap_or(false)); + + let key = recover(*tcx, dep_node).unwrap_or_else(|| panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash)); + if queries::$name::cache_on_disk(tcx, &key, None) { + let _ = tcx.$name(key); + } + } + + QueryStruct { + force_from_dep_node, + try_load_from_on_disk_cache, + } + };)* + } + + static QUERY_CALLBACKS: &[QueryStruct] = &make_dep_kind_array!(query_callbacks); + define_provider_struct! { tcx: $tcx, input: ($(([$($modifiers)*] [$name] [$($K)*] [$V]))*) From 8e5d613a11df0e499cf1a006a4b0b2ea9740f991 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 19 Jan 2021 19:43:59 +0100 Subject: [PATCH 18/23] Wrap QueryDescription into a macro. --- compiler/rustc_macros/src/query.rs | 8 +++--- compiler/rustc_middle/src/query/mod.rs | 25 ------------------- .../rustc_middle/src/ty/query/plumbing.rs | 16 +++++++++--- 3 files changed, 17 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index e387020d828..5326f0ae269 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -344,7 +344,6 @@ fn add_query_description_impl( impls: &mut proc_macro2::TokenStream, ) { let name = &query.name; - let arg = &query.arg; let key = &query.key.0; // Find out if we should cache the query on disk @@ -414,7 +413,7 @@ fn add_query_description_impl( let desc = quote! { #[allow(unused_variables)] - fn describe(tcx: QueryCtxt<'tcx>, key: #arg) -> String { + fn describe(tcx: QueryCtxt<'tcx>, key: Self::Key) -> String { let (#tcx, #key) = (*tcx, key); ::rustc_middle::ty::print::with_no_trimmed_paths(|| format!(#desc).into()) } @@ -520,7 +519,8 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { $($macro)*(#cached_queries); } } - - #query_description_stream + macro_rules! rustc_query_description { + () => { #query_description_stream } + } }) } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 343ae66c07a..4207e2dea34 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1,28 +1,3 @@ -use crate::dep_graph::SerializedDepNodeIndex; -use crate::mir::interpret::{GlobalId, LitToConstInput}; -use crate::traits; -use crate::traits::query::{ - CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal, - CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal, - CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal, -}; -use crate::ty::query::queries; -use crate::ty::query::QueryCtxt; -use crate::ty::subst::{GenericArg, SubstsRef}; -use crate::ty::{self, ParamEnvAnd, Ty, TyCtxt}; -use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; -use rustc_query_system::query::QueryDescription; - -use rustc_span::symbol::Symbol; - -fn describe_as_module(def_id: LocalDefId, tcx: TyCtxt<'_>) -> String { - if def_id.is_top_level_module() { - "top-level module".to_string() - } else { - format!("module `{}`", tcx.def_path_str(def_id.to_def_id())) - } -} - // Each of these queries corresponds to a function pointer field in the // `Providers` struct for requesting a value of that type, and a method // on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way diff --git a/compiler/rustc_middle/src/ty/query/plumbing.rs b/compiler/rustc_middle/src/ty/query/plumbing.rs index 18ae6318a00..61bc4f3c1c4 100644 --- a/compiler/rustc_middle/src/ty/query/plumbing.rs +++ b/compiler/rustc_middle/src/ty/query/plumbing.rs @@ -3,19 +3,19 @@ //! manage the caches, and so forth. use crate::dep_graph::{self, DepKind, DepNode, DepNodeExt, DepNodeIndex, SerializedDepNodeIndex}; -use crate::ty::query::{on_disk_cache, Queries, Query}; +use crate::ty::query::{on_disk_cache, queries, Queries, Query}; use crate::ty::tls::{self, ImplicitCtxt}; use crate::ty::{self, TyCtxt}; use rustc_query_system::dep_graph::HasDepContext; -use rustc_query_system::query::QueryContext; use rustc_query_system::query::{CycleError, QueryJobId, QueryJobInfo}; +use rustc_query_system::query::{QueryContext, QueryDescription}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lock; use rustc_data_structures::thin_vec::ThinVec; use rustc_errors::{struct_span_err, Diagnostic, DiagnosticBuilder, Handler, Level}; use rustc_serialize::opaque; -use rustc_span::def_id::DefId; +use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::Span; #[derive(Copy, Clone)] @@ -797,3 +797,13 @@ macro_rules! define_provider_struct { } }; } + +fn describe_as_module(def_id: LocalDefId, tcx: TyCtxt<'_>) -> String { + if def_id.is_top_level_module() { + "top-level module".to_string() + } else { + format!("module `{}`", tcx.def_path_str(def_id.to_def_id())) + } +} + +rustc_query_description! {} From 24dbb61e5895e0f1433182f17d34eda1c94b130f Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 19 Jan 2021 19:44:27 +0100 Subject: [PATCH 19/23] Move query names and Providers to parent module. --- compiler/rustc_middle/src/ty/query/mod.rs | 66 ++++++++++++++++- .../rustc_middle/src/ty/query/plumbing.rs | 70 ------------------- 2 files changed, 65 insertions(+), 71 deletions(-) diff --git a/compiler/rustc_middle/src/ty/query/mod.rs b/compiler/rustc_middle/src/ty/query/mod.rs index a2f3c6eedcb..faef1f048cc 100644 --- a/compiler/rustc_middle/src/ty/query/mod.rs +++ b/compiler/rustc_middle/src/ty/query/mod.rs @@ -127,11 +127,52 @@ impl TyCtxt<'tcx> { } } +macro_rules! query_helper_param_ty { + (DefId) => { impl IntoQueryParam }; + ($K:ty) => { $K }; +} + macro_rules! define_callbacks { (<$tcx:tt> $($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => { + // HACK(eddyb) this is like the `impl QueryConfig for queries::$name` + // below, but using type aliases instead of associated types, to bypass + // the limitations around normalizing under HRTB - for example, this: + // `for<'tcx> fn(...) -> as QueryConfig>>::Value` + // doesn't currently normalize to `for<'tcx> fn(...) -> query_values::$name<'tcx>`. + // This is primarily used by the `provide!` macro in `rustc_metadata`. + #[allow(nonstandard_style, unused_lifetimes)] + pub mod query_keys { + use super::*; + + $(pub type $name<$tcx> = $($K)*;)* + } + #[allow(nonstandard_style, unused_lifetimes)] + pub mod query_values { + use super::*; + + $(pub type $name<$tcx> = $V;)* + } + #[allow(nonstandard_style, unused_lifetimes)] + pub mod query_storage { + use super::*; + + $(pub type $name<$tcx> = query_storage!([$($modifiers)*][$($K)*, $V]);)* + } + #[allow(nonstandard_style, unused_lifetimes)] + pub mod query_stored { + use super::*; + + $(pub type $name<$tcx> = as QueryStorage>::Stored;)* + } + + #[derive(Default)] + pub struct QueryCaches<$tcx> { + $($(#[$attr])* $name: QueryCacheStore>,)* + } + impl TyCtxtEnsure<$tcx> { $($(#[$attr])* #[inline(always)] @@ -176,7 +217,30 @@ macro_rules! define_callbacks { self.tcx.queries.$name(self.tcx, self.span, key, lookup, QueryMode::Get).unwrap() })* } - } + + pub struct Providers { + $(pub $name: for<'tcx> fn( + TyCtxt<'tcx>, + query_keys::$name<'tcx>, + ) -> query_values::$name<'tcx>,)* + } + + impl Default for Providers { + fn default() -> Self { + Providers { + $($name: |_, key| bug!( + "`tcx.{}({:?})` unsupported by its crate", + stringify!($name), key + ),)* + } + } + } + + impl Copy for Providers {} + impl Clone for Providers { + fn clone(&self) -> Self { *self } + } + }; } // Each of these queries corresponds to a function pointer field in the diff --git a/compiler/rustc_middle/src/ty/query/plumbing.rs b/compiler/rustc_middle/src/ty/query/plumbing.rs index 61bc4f3c1c4..32ed7e73635 100644 --- a/compiler/rustc_middle/src/ty/query/plumbing.rs +++ b/compiler/rustc_middle/src/ty/query/plumbing.rs @@ -430,11 +430,6 @@ macro_rules! hash_result { }; } -macro_rules! query_helper_param_ty { - (DefId) => { impl IntoQueryParam }; - ($K:ty) => { $K }; -} - macro_rules! define_queries { (<$tcx:tt> $($(#[$attr:meta])* @@ -512,42 +507,6 @@ macro_rules! define_queries { })* } - // HACK(eddyb) this is like the `impl QueryConfig for queries::$name` - // below, but using type aliases instead of associated types, to bypass - // the limitations around normalizing under HRTB - for example, this: - // `for<'tcx> fn(...) -> as QueryConfig>>::Value` - // doesn't currently normalize to `for<'tcx> fn(...) -> query_values::$name<'tcx>`. - // This is primarily used by the `provide!` macro in `rustc_metadata`. - #[allow(nonstandard_style, unused_lifetimes)] - pub mod query_keys { - use super::*; - - $(pub type $name<$tcx> = $($K)*;)* - } - #[allow(nonstandard_style, unused_lifetimes)] - pub mod query_values { - use super::*; - - $(pub type $name<$tcx> = $V;)* - } - #[allow(nonstandard_style, unused_lifetimes)] - pub mod query_storage { - use super::*; - - $(pub type $name<$tcx> = query_storage!([$($modifiers)*][$($K)*, $V]);)* - } - #[allow(nonstandard_style, unused_lifetimes)] - pub mod query_stored { - use super::*; - - $(pub type $name<$tcx> = as QueryStorage>::Stored;)* - } - - #[derive(Default)] - pub struct QueryCaches<$tcx> { - $($(#[$attr])* $name: QueryCacheStore>,)* - } - $(impl<$tcx> QueryConfig for queries::$name<$tcx> { type Key = $($K)*; type Value = $V; @@ -683,11 +642,6 @@ macro_rules! define_queries { } static QUERY_CALLBACKS: &[QueryStruct] = &make_dep_kind_array!(query_callbacks); - - define_provider_struct! { - tcx: $tcx, - input: ($(([$($modifiers)*] [$name] [$($K)*] [$V]))*) - } } } @@ -774,30 +728,6 @@ macro_rules! define_queries_struct { }; } -macro_rules! define_provider_struct { - (tcx: $tcx:tt, - input: ($(([$($modifiers:tt)*] [$name:ident] [$K:ty] [$R:ty]))*)) => { - pub struct Providers { - $(pub $name: for<$tcx> fn(TyCtxt<$tcx>, $K) -> $R,)* - } - - impl Default for Providers { - fn default() -> Self { - $(fn $name<$tcx>(_: TyCtxt<$tcx>, key: $K) -> $R { - bug!("`tcx.{}({:?})` unsupported by its crate", - stringify!($name), key); - })* - Providers { $($name),* } - } - } - - impl Copy for Providers {} - impl Clone for Providers { - fn clone(&self) -> Self { *self } - } - }; -} - fn describe_as_module(def_id: LocalDefId, tcx: TyCtxt<'_>) -> String { if def_id.is_top_level_module() { "top-level module".to_string() From 23f9d10ea7f63e075f607c41d83f1411405b5a9c Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 19 Jan 2021 20:04:40 +0100 Subject: [PATCH 20/23] Make encode_query_results more generic. --- .../rustc_middle/src/ty/query/on_disk_cache.rs | 14 ++++++++------ compiler/rustc_middle/src/ty/query/plumbing.rs | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs index 69352df1527..c71de7f4cd7 100644 --- a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs @@ -3,7 +3,6 @@ use crate::mir::interpret::{AllocDecodingSession, AllocDecodingState}; use crate::mir::{self, interpret}; use crate::ty::codec::{RefDecodable, TyDecoder, TyEncoder}; use crate::ty::context::TyCtxt; -use crate::ty::query::QueryCtxt; use crate::ty::{self, Ty}; use rustc_data_structures::fingerprint::{Fingerprint, FingerprintDecoder, FingerprintEncoder}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; @@ -15,6 +14,8 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, LOCAL_CRATE}; use rustc_hir::definitions::DefPathHash; use rustc_hir::definitions::Definitions; use rustc_index::vec::{Idx, IndexVec}; +use rustc_query_system::dep_graph::DepContext; +use rustc_query_system::query::QueryContext; use rustc_serialize::{ opaque::{self, FileEncodeResult, FileEncoder}, Decodable, Decoder, Encodable, Encoder, @@ -1215,18 +1216,19 @@ impl<'a> Decodable> for IntEncodedWithFixedSize { } } -pub fn encode_query_results<'a, 'tcx, Q>( - tcx: QueryCtxt<'tcx>, +pub fn encode_query_results<'a, 'tcx, CTX, Q>( + tcx: CTX, encoder: &mut CacheEncoder<'a, 'tcx, FileEncoder>, query_result_index: &mut EncodedQueryResultIndex, ) -> FileEncodeResult where - Q: super::QueryDescription> + super::QueryAccessors>, + CTX: QueryContext + 'tcx, + Q: super::QueryDescription + super::QueryAccessors, Q::Value: Encodable>, { let _timer = tcx - .sess - .prof + .dep_context() + .profiler() .extra_verbose_generic_activity("encode_query_results_for", std::any::type_name::()); assert!(Q::query_state(tcx).all_inactive()); diff --git a/compiler/rustc_middle/src/ty/query/plumbing.rs b/compiler/rustc_middle/src/ty/query/plumbing.rs index 32ed7e73635..53bac4181e6 100644 --- a/compiler/rustc_middle/src/ty/query/plumbing.rs +++ b/compiler/rustc_middle/src/ty/query/plumbing.rs @@ -251,7 +251,7 @@ impl<'tcx> QueryCtxt<'tcx> { macro_rules! encode_queries { ($($query:ident,)*) => { $( - on_disk_cache::encode_query_results::>( + on_disk_cache::encode_query_results::<_, ty::query::queries::$query<'_>>( self, encoder, query_result_index From 71f749a683731421c31591ea09f2623ef498c47a Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 18 Jan 2021 22:32:20 +0100 Subject: [PATCH 21/23] Introduce a QueryEngine trait object. --- compiler/rustc_middle/src/ty/context.rs | 6 +- compiler/rustc_middle/src/ty/query/mod.rs | 39 ++++++- .../rustc_middle/src/ty/query/plumbing.rs | 101 +++++++++--------- 3 files changed, 92 insertions(+), 54 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index ec680eeb30f..6c1e09b9bf9 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -14,7 +14,7 @@ use crate::middle::stability; use crate::mir::interpret::{self, Allocation, ConstValue, Scalar}; use crate::mir::{Body, Field, Local, Place, PlaceElem, ProjectionKind, Promoted}; use crate::traits; -use crate::ty::query::{self, OnDiskCache, Queries, TyCtxtAt}; +use crate::ty::query::{self, OnDiskCache, TyCtxtAt}; use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSubsts}; use crate::ty::TyKind::*; use crate::ty::{ @@ -968,7 +968,7 @@ pub struct GlobalCtxt<'tcx> { /// This is `None` if we are not incremental compilation mode pub(crate) on_disk_cache: Option>, - pub queries: &'tcx query::Queries<'tcx>, + pub queries: &'tcx dyn query::QueryEngine<'tcx>, pub query_caches: query::QueryCaches<'tcx>, maybe_unused_trait_imports: FxHashSet, @@ -1115,7 +1115,7 @@ impl<'tcx> TyCtxt<'tcx> { definitions: &'tcx Definitions, dep_graph: DepGraph, on_disk_cache: Option>, - queries: &'tcx Queries<'tcx>, + queries: &'tcx dyn query::QueryEngine<'tcx>, crate_name: &str, output_filenames: &OutputFilenames, ) -> GlobalCtxt<'tcx> { diff --git a/compiler/rustc_middle/src/ty/query/mod.rs b/compiler/rustc_middle/src/ty/query/mod.rs index faef1f048cc..0abd5676557 100644 --- a/compiler/rustc_middle/src/ty/query/mod.rs +++ b/compiler/rustc_middle/src/ty/query/mod.rs @@ -37,7 +37,7 @@ use rustc_data_structures::stable_hasher::StableVec; use rustc_data_structures::steal::Steal; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::Lrc; -use rustc_errors::ErrorReported; +use rustc_errors::{Diagnostic, ErrorReported, Handler, Level}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId}; @@ -122,8 +122,7 @@ impl TyCtxt<'tcx> { } pub fn try_mark_green(self, dep_node: &dep_graph::DepNode) -> bool { - let qcx = QueryCtxt { tcx: self, queries: self.queries }; - self.dep_graph.try_mark_green(qcx, dep_node).is_some() + self.queries.try_mark_green(self, dep_node) } } @@ -240,6 +239,40 @@ macro_rules! define_callbacks { impl Clone for Providers { fn clone(&self) -> Self { *self } } + + pub trait QueryEngine<'tcx>: rustc_data_structures::sync::Sync { + #[cfg(parallel_compiler)] + unsafe fn deadlock(&'tcx self, tcx: TyCtxt<'tcx>, registry: &rustc_rayon_core::Registry); + + fn encode_query_results( + &'tcx self, + tcx: TyCtxt<'tcx>, + encoder: &mut on_disk_cache::CacheEncoder<'a, 'tcx, opaque::FileEncoder>, + query_result_index: &mut on_disk_cache::EncodedQueryResultIndex, + ) -> opaque::FileEncodeResult; + + fn exec_cache_promotions(&'tcx self, tcx: TyCtxt<'tcx>); + + fn try_mark_green(&'tcx self, tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool; + + fn try_print_query_stack( + &'tcx self, + tcx: TyCtxt<'tcx>, + query: Option>, + handler: &Handler, + num_frames: Option, + ) -> usize; + + $($(#[$attr])* + fn $name( + &'tcx self, + tcx: TyCtxt<$tcx>, + span: Span, + key: query_keys::$name<$tcx>, + lookup: QueryLookup, + mode: QueryMode, + ) -> Option>;)* + } }; } diff --git a/compiler/rustc_middle/src/ty/query/plumbing.rs b/compiler/rustc_middle/src/ty/query/plumbing.rs index 53bac4181e6..79900fc7636 100644 --- a/compiler/rustc_middle/src/ty/query/plumbing.rs +++ b/compiler/rustc_middle/src/ty/query/plumbing.rs @@ -2,8 +2,8 @@ //! generate the actual methods on tcx which find and execute the provider, //! manage the caches, and so forth. -use crate::dep_graph::{self, DepKind, DepNode, DepNodeExt, DepNodeIndex, SerializedDepNodeIndex}; -use crate::ty::query::{on_disk_cache, queries, Queries, Query}; +use crate::dep_graph::{DepKind, DepNode, DepNodeExt, DepNodeIndex, SerializedDepNodeIndex}; +use crate::ty::query::{on_disk_cache, queries, Query}; use crate::ty::tls::{self, ImplicitCtxt}; use crate::ty::{self, TyCtxt}; use rustc_query_system::dep_graph::HasDepContext; @@ -13,7 +13,7 @@ use rustc_query_system::query::{QueryContext, QueryDescription}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lock; use rustc_data_structures::thin_vec::ThinVec; -use rustc_errors::{struct_span_err, Diagnostic, DiagnosticBuilder, Handler, Level}; +use rustc_errors::{struct_span_err, Diagnostic, DiagnosticBuilder}; use rustc_serialize::opaque; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::Span; @@ -266,49 +266,6 @@ impl<'tcx> QueryCtxt<'tcx> { } } -impl<'tcx> Queries<'tcx> { - pub fn try_print_query_stack( - &'tcx self, - tcx: TyCtxt<'tcx>, - query: Option>, - handler: &Handler, - num_frames: Option, - ) -> usize { - let query_map = self.try_collect_active_jobs(); - - let mut current_query = query; - let mut i = 0; - - while let Some(query) = current_query { - if Some(i) == num_frames { - break; - } - let query_info = if let Some(info) = query_map.as_ref().and_then(|map| map.get(&query)) - { - info - } else { - break; - }; - let mut diag = Diagnostic::new( - Level::FailureNote, - &format!( - "#{} [{}] {}", - i, - query_info.info.query.name(), - query_info.info.query.describe(QueryCtxt { tcx, queries: self }) - ), - ); - diag.span = tcx.sess.source_map().guess_head_span(query_info.info.span).into(); - handler.force_print_diagnostic(diag); - - current_query = query_info.job.parent; - i += 1; - } - - i - } -} - /// This struct stores metadata about each Query. /// /// Information is retrieved by indexing the `QUERIES` array using the integer value @@ -689,14 +646,16 @@ macro_rules! define_queries_struct { Some(jobs) } + } + impl QueryEngine<'tcx> for Queries<'tcx> { #[cfg(parallel_compiler)] - pub unsafe fn deadlock(&'tcx self, tcx: TyCtxt<'tcx>, registry: &rustc_rayon_core::Registry) { + unsafe fn deadlock(&'tcx self, tcx: TyCtxt<'tcx>, registry: &rustc_rayon_core::Registry) { let tcx = QueryCtxt { tcx, queries: self }; rustc_query_system::query::deadlock(tcx, registry) } - pub(crate) fn encode_query_results( + fn encode_query_results( &'tcx self, tcx: TyCtxt<'tcx>, encoder: &mut on_disk_cache::CacheEncoder<'a, 'tcx, opaque::FileEncoder>, @@ -711,6 +670,52 @@ macro_rules! define_queries_struct { tcx.dep_graph.exec_cache_promotions(tcx) } + fn try_mark_green(&'tcx self, tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool { + let qcx = QueryCtxt { tcx, queries: self }; + tcx.dep_graph.try_mark_green(qcx, dep_node).is_some() + } + + fn try_print_query_stack( + &'tcx self, + tcx: TyCtxt<'tcx>, + query: Option>, + handler: &Handler, + num_frames: Option, + ) -> usize { + let query_map = self.try_collect_active_jobs(); + + let mut current_query = query; + let mut i = 0; + + while let Some(query) = current_query { + if Some(i) == num_frames { + break; + } + let query_info = if let Some(info) = query_map.as_ref().and_then(|map| map.get(&query)) + { + info + } else { + break; + }; + let mut diag = Diagnostic::new( + Level::FailureNote, + &format!( + "#{} [{}] {}", + i, + query_info.info.query.name(), + query_info.info.query.describe(QueryCtxt { tcx, queries: self }) + ), + ); + diag.span = tcx.sess.source_map().guess_head_span(query_info.info.span).into(); + handler.force_print_diagnostic(diag); + + current_query = query_info.job.parent; + i += 1; + } + + i + } + $($(#[$attr])* #[inline(always)] fn $name( From 4581d16bcbea9273b6755dd24a884a234a0dc2f7 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 19 Jan 2021 20:40:16 +0100 Subject: [PATCH 22/23] Move the query system to rustc_query_impl. --- Cargo.lock | 24 +++++++ compiler/rustc_interface/Cargo.toml | 1 + compiler/rustc_interface/src/passes.rs | 8 +-- compiler/rustc_interface/src/queries.rs | 8 +-- compiler/rustc_macros/src/query.rs | 3 + compiler/rustc_middle/src/ty/context.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 2 - compiler/rustc_middle/src/ty/query/mod.rs | 44 +++++-------- .../src/ty/query/on_disk_cache.rs | 4 +- compiler/rustc_query_impl/Cargo.toml | 27 ++++++++ .../query => rustc_query_impl/src}/README.md | 0 .../ty/query => rustc_query_impl/src}/keys.rs | 10 +-- compiler/rustc_query_impl/src/lib.rs | 65 +++++++++++++++++++ .../src}/plumbing.rs | 44 ++++--------- .../src}/profiling_support.rs | 3 +- .../query => rustc_query_impl/src}/stats.rs | 4 +- .../query => rustc_query_impl/src}/values.rs | 4 +- 17 files changed, 170 insertions(+), 83 deletions(-) create mode 100644 compiler/rustc_query_impl/Cargo.toml rename compiler/{rustc_middle/src/ty/query => rustc_query_impl/src}/README.md (100%) rename compiler/{rustc_middle/src/ty/query => rustc_query_impl/src}/keys.rs (97%) create mode 100644 compiler/rustc_query_impl/src/lib.rs rename compiler/{rustc_middle/src/ty/query => rustc_query_impl/src}/plumbing.rs (95%) rename compiler/{rustc_middle/src/ty/query => rustc_query_impl/src}/profiling_support.rs (99%) rename compiler/{rustc_middle/src/ty/query => rustc_query_impl/src}/stats.rs (98%) rename compiler/{rustc_middle/src/ty/query => rustc_query_impl/src}/values.rs (94%) diff --git a/Cargo.lock b/Cargo.lock index b78bf583205..0576a55a447 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3901,6 +3901,7 @@ dependencies = [ "rustc_passes", "rustc_plugin_impl", "rustc_privacy", + "rustc_query_impl", "rustc_resolve", "rustc_serialize", "rustc_session", @@ -4167,6 +4168,29 @@ dependencies = [ "tracing", ] +[[package]] +name = "rustc_query_impl" +version = "0.0.0" +dependencies = [ + "measureme", + "rustc-rayon-core", + "rustc_ast", + "rustc_attr", + "rustc_data_structures", + "rustc_errors", + "rustc_feature", + "rustc_hir", + "rustc_index", + "rustc_macros", + "rustc_middle", + "rustc_query_system", + "rustc_serialize", + "rustc_session", + "rustc_span", + "rustc_target", + "tracing", +] + [[package]] name = "rustc_query_system" version = "0.0.0" diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml index a1ac155d57a..cfe98a630c1 100644 --- a/compiler/rustc_interface/Cargo.toml +++ b/compiler/rustc_interface/Cargo.toml @@ -41,6 +41,7 @@ rustc_lint = { path = "../rustc_lint" } rustc_errors = { path = "../rustc_errors" } rustc_plugin_impl = { path = "../rustc_plugin_impl" } rustc_privacy = { path = "../rustc_privacy" } +rustc_query_impl = { path = "../rustc_query_impl" } rustc_resolve = { path = "../rustc_resolve" } rustc_trait_selection = { path = "../rustc_trait_selection" } rustc_ty_utils = { path = "../rustc_ty_utils" } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 76d988815ff..6358855ac32 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -21,7 +21,6 @@ use rustc_middle::arena::Arena; use rustc_middle::dep_graph::DepGraph; use rustc_middle::middle; use rustc_middle::middle::cstore::{CrateStore, MetadataLoader, MetadataLoaderDyn}; -use rustc_middle::ty::query; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, GlobalCtxt, ResolverOutputs, TyCtxt}; use rustc_mir as mir; @@ -29,6 +28,7 @@ use rustc_mir_build as mir_build; use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str}; use rustc_passes::{self, hir_stats, layout_test}; use rustc_plugin_impl as plugin; +use rustc_query_impl::Queries as TcxQueries; use rustc_resolve::{Resolver, ResolverArenas}; use rustc_session::config::{CrateType, Input, OutputFilenames, OutputType, PpMode, PpSourceMode}; use rustc_session::lint; @@ -762,7 +762,7 @@ pub fn create_global_ctxt<'tcx>( mut resolver_outputs: ResolverOutputs, outputs: OutputFilenames, crate_name: &str, - queries: &'tcx OnceCell>, + queries: &'tcx OnceCell>, global_ctxt: &'tcx OnceCell>, arena: &'tcx WorkerLocal>, ) -> QueryContext<'tcx> { @@ -791,7 +791,7 @@ pub fn create_global_ctxt<'tcx>( let max_cnum = crates.iter().map(|c| c.as_usize()).max().unwrap_or(0); let mut providers = IndexVec::from_elem_n(extern_providers, max_cnum + 1); providers[LOCAL_CRATE] = local_providers; - queries.get_or_init(|| query::Queries::new(providers, extern_providers)) + queries.get_or_init(|| TcxQueries::new(providers, extern_providers)) }; let gcx = sess.time("setup_global_ctxt", || { @@ -805,7 +805,7 @@ pub fn create_global_ctxt<'tcx>( defs, dep_graph, query_result_on_disk_cache, - queries, + queries.as_dyn(), &crate_name, &outputs, ) diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index f70701257e2..9c38d2b91ab 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -13,8 +13,8 @@ use rustc_incremental::DepGraphFuture; use rustc_lint::LintStore; use rustc_middle::arena::Arena; use rustc_middle::dep_graph::DepGraph; -use rustc_middle::ty::query; use rustc_middle::ty::{GlobalCtxt, ResolverOutputs, TyCtxt}; +use rustc_query_impl::Queries as TcxQueries; use rustc_serialize::json; use rustc_session::config::{self, OutputFilenames, OutputType}; use rustc_session::{output::find_crate_name, Session}; @@ -72,7 +72,7 @@ impl Default for Query { pub struct Queries<'tcx> { compiler: &'tcx Compiler, gcx: OnceCell>, - queries: OnceCell>, + queries: OnceCell>, arena: WorkerLocal>, hir_arena: WorkerLocal>, @@ -429,11 +429,11 @@ impl Compiler { { let _prof_timer = queries.session().prof.generic_activity("self_profile_alloc_query_strings"); - gcx.enter(query::alloc_self_profile_query_strings); + gcx.enter(rustc_query_impl::alloc_self_profile_query_strings); } if self.session().opts.debugging_opts.query_stats { - gcx.enter(query::print_stats); + gcx.enter(rustc_query_impl::print_stats); } } diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index 5326f0ae269..3e67525567f 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -495,6 +495,7 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { } TokenStream::from(quote! { + #[macro_export] macro_rules! rustc_query_append { ([$($macro:tt)*][$($other:tt)*]) => { $($macro)* { @@ -514,11 +515,13 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { ); } } + #[macro_export] macro_rules! rustc_cached_queries { ($($macro:tt)*) => { $($macro)*(#cached_queries); } } + #[macro_export] macro_rules! rustc_query_description { () => { #query_description_stream } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 6c1e09b9bf9..d316d595b1a 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -966,7 +966,7 @@ pub struct GlobalCtxt<'tcx> { /// Do not access this directly. It is only meant to be used by /// `DepGraph::try_mark_green()` and the query infrastructure. /// This is `None` if we are not incremental compilation mode - pub(crate) on_disk_cache: Option>, + pub on_disk_cache: Option>, pub queries: &'tcx dyn query::QueryEngine<'tcx>, pub query_caches: query::QueryCaches<'tcx>, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index b7f62437fa5..018d269bfd1 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -100,8 +100,6 @@ pub use self::list::List; pub use self::trait_def::TraitDef; -pub use self::query::queries; - pub use self::consts::{Const, ConstInt, ConstKind, InferConst, ScalarInt}; pub mod _match; diff --git a/compiler/rustc_middle/src/ty/query/mod.rs b/compiler/rustc_middle/src/ty/query/mod.rs index 0abd5676557..0bc14f1e27c 100644 --- a/compiler/rustc_middle/src/ty/query/mod.rs +++ b/compiler/rustc_middle/src/ty/query/mod.rs @@ -31,13 +31,12 @@ use crate::traits::{self, ImplSource}; use crate::ty::subst::{GenericArg, SubstsRef}; use crate::ty::util::AlwaysRequiresDrop; use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt}; -use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_data_structures::stable_hasher::StableVec; use rustc_data_structures::steal::Steal; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::Lrc; -use rustc_errors::{Diagnostic, ErrorReported, Handler, Level}; +use rustc_errors::{ErrorReported, Handler}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId}; @@ -59,34 +58,12 @@ use std::ops::Deref; use std::path::PathBuf; use std::sync::Arc; -#[macro_use] -mod plumbing; -pub use plumbing::QueryCtxt; -use plumbing::QueryStruct; -pub(crate) use rustc_query_system::query::CycleError; +pub(crate) use rustc_query_system::query::QueryJobId; use rustc_query_system::query::*; -mod stats; -pub use self::stats::print_stats; - -pub use rustc_query_system::query::{QueryInfo, QueryJob, QueryJobId}; - -mod keys; -use self::keys::Key; - -mod values; -use self::values::Value; - -use rustc_query_system::query::QueryAccessors; -pub use rustc_query_system::query::QueryConfig; -pub(crate) use rustc_query_system::query::QueryDescription; - -mod on_disk_cache; +pub mod on_disk_cache; pub use self::on_disk_cache::OnDiskCache; -mod profiling_support; -pub use self::profiling_support::alloc_self_profile_query_strings; - #[derive(Copy, Clone)] pub struct TyCtxtAt<'tcx> { pub tcx: TyCtxt<'tcx>, @@ -131,6 +108,18 @@ macro_rules! query_helper_param_ty { ($K:ty) => { $K }; } +macro_rules! query_storage { + ([][$K:ty, $V:ty]) => { + >::Cache + }; + ([storage($ty:ty) $($rest:tt)*][$K:ty, $V:ty]) => { + <$ty as CacheSelector<$K, $V>>::Cache + }; + ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => { + query_storage!([$($($modifiers)*)*][$($args)*]) + }; +} + macro_rules! define_callbacks { (<$tcx:tt> $($(#[$attr:meta])* @@ -169,7 +158,7 @@ macro_rules! define_callbacks { #[derive(Default)] pub struct QueryCaches<$tcx> { - $($(#[$attr])* $name: QueryCacheStore>,)* + $($(#[$attr])* pub $name: QueryCacheStore>,)* } impl TyCtxtEnsure<$tcx> { @@ -288,7 +277,6 @@ macro_rules! define_callbacks { // Queries marked with `fatal_cycle` do not need the latter implementation, // as they will raise an fatal error on query cycles instead. -rustc_query_append! { [define_queries!][<'tcx>] } rustc_query_append! { [define_callbacks!][<'tcx>] } mod sealed { diff --git a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs index c71de7f4cd7..d0cd8a48f99 100644 --- a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs @@ -502,7 +502,7 @@ impl<'sess> OnDiskCache<'sess> { /// Returns the cached query result if there is something in the cache for /// the given `SerializedDepNodeIndex`; otherwise returns `None`. - crate fn try_load_query_result<'tcx, T>( + pub fn try_load_query_result<'tcx, T>( &self, tcx: TyCtxt<'tcx>, dep_node_index: SerializedDepNodeIndex, @@ -665,7 +665,7 @@ impl<'sess> OnDiskCache<'sess> { /// A decoder that can read from the incremental compilation cache. It is similar to the one /// we use for crate metadata decoding in that it can rebase spans and eventually /// will also handle things that contain `Ty` instances. -crate struct CacheDecoder<'a, 'tcx> { +pub struct CacheDecoder<'a, 'tcx> { tcx: TyCtxt<'tcx>, opaque: opaque::Decoder<'a>, source_map: &'a SourceMap, diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml new file mode 100644 index 00000000000..c88b766a55a --- /dev/null +++ b/compiler/rustc_query_impl/Cargo.toml @@ -0,0 +1,27 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_query_impl" +version = "0.0.0" +edition = "2018" + +[lib] +doctest = false + +[dependencies] +measureme = "9.0.0" +rustc-rayon-core = "0.3.0" +tracing = "0.1" +rustc_ast = { path = "../rustc_ast" } +rustc_attr = { path = "../rustc_attr" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_errors = { path = "../rustc_errors" } +rustc_feature = { path = "../rustc_feature" } +rustc_hir = { path = "../rustc_hir" } +rustc_index = { path = "../rustc_index" } +rustc_macros = { path = "../rustc_macros" } +rustc_middle = { path = "../rustc_middle" } +rustc_query_system = { path = "../rustc_query_system" } +rustc_span = { path = "../rustc_span" } +rustc_serialize = { path = "../rustc_serialize" } +rustc_session = { path = "../rustc_session" } +rustc_target = { path = "../rustc_target" } diff --git a/compiler/rustc_middle/src/ty/query/README.md b/compiler/rustc_query_impl/src/README.md similarity index 100% rename from compiler/rustc_middle/src/ty/query/README.md rename to compiler/rustc_query_impl/src/README.md diff --git a/compiler/rustc_middle/src/ty/query/keys.rs b/compiler/rustc_query_impl/src/keys.rs similarity index 97% rename from compiler/rustc_middle/src/ty/query/keys.rs rename to compiler/rustc_query_impl/src/keys.rs index 2f76237e8fb..1ae5bf12cab 100644 --- a/compiler/rustc_middle/src/ty/query/keys.rs +++ b/compiler/rustc_query_impl/src/keys.rs @@ -1,11 +1,11 @@ //! Defines the set of legal keys that can be used in queries. -use crate::infer::canonical::Canonical; -use crate::mir; -use crate::ty::fast_reject::SimplifiedType; -use crate::ty::subst::{GenericArg, SubstsRef}; -use crate::ty::{self, Ty, TyCtxt}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; +use rustc_middle::infer::canonical::Canonical; +use rustc_middle::mir; +use rustc_middle::ty::fast_reject::SimplifiedType; +use rustc_middle::ty::subst::{GenericArg, SubstsRef}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::symbol::{Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs new file mode 100644 index 00000000000..43dfe6892b1 --- /dev/null +++ b/compiler/rustc_query_impl/src/lib.rs @@ -0,0 +1,65 @@ +//! Support for serializing the dep-graph and reloading it. + +#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![feature(in_band_lifetimes)] +#![feature(exhaustive_patterns)] +#![feature(nll)] +#![feature(min_specialization)] +#![feature(crate_visibility_modifier)] +#![feature(once_cell)] +#![feature(rustc_attrs)] +#![feature(never_type)] +#![recursion_limit = "256"] + +#[macro_use] +extern crate rustc_middle; +#[macro_use] +extern crate tracing; + +use rustc_data_structures::fingerprint::Fingerprint; +use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_errors::{Diagnostic, Handler, Level}; +use rustc_hir::def_id::CrateNum; +use rustc_index::vec::IndexVec; +use rustc_middle::dep_graph; +use rustc_middle::ich::StableHashingContext; +use rustc_middle::ty::query::{query_keys, query_storage, query_stored, query_values}; +use rustc_middle::ty::query::{Providers, QueryEngine}; +use rustc_middle::ty::TyCtxt; +use rustc_serialize::opaque; +use rustc_span::{Span, DUMMY_SP}; +use std::mem; + +#[macro_use] +mod plumbing; +pub use plumbing::QueryCtxt; +use plumbing::QueryStruct; +use rustc_query_system::query::*; + +mod stats; +pub use self::stats::print_stats; + +mod keys; +use keys::Key; + +mod values; +use self::values::Value; + +use rustc_query_system::query::QueryAccessors; +pub use rustc_query_system::query::QueryConfig; +pub(crate) use rustc_query_system::query::QueryDescription; + +use rustc_middle::ty::query::on_disk_cache; + +mod profiling_support; +pub use self::profiling_support::alloc_self_profile_query_strings; + +rustc_query_append! { [define_queries!][<'tcx>] } + +impl<'tcx> Queries<'tcx> { + // Force codegen in the dyn-trait transformation in this crate. + pub fn as_dyn(&'tcx self) -> &'tcx dyn QueryEngine<'tcx> { + self + } +} diff --git a/compiler/rustc_middle/src/ty/query/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs similarity index 95% rename from compiler/rustc_middle/src/ty/query/plumbing.rs rename to compiler/rustc_query_impl/src/plumbing.rs index 79900fc7636..466c1f79f48 100644 --- a/compiler/rustc_middle/src/ty/query/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -2,10 +2,11 @@ //! generate the actual methods on tcx which find and execute the provider, //! manage the caches, and so forth. -use crate::dep_graph::{DepKind, DepNode, DepNodeExt, DepNodeIndex, SerializedDepNodeIndex}; -use crate::ty::query::{on_disk_cache, queries, Query}; -use crate::ty::tls::{self, ImplicitCtxt}; -use crate::ty::{self, TyCtxt}; +use super::{queries, Query}; +use rustc_middle::dep_graph::{DepKind, DepNode, DepNodeExt, DepNodeIndex, SerializedDepNodeIndex}; +use rustc_middle::ty::query::on_disk_cache; +use rustc_middle::ty::tls::{self, ImplicitCtxt}; +use rustc_middle::ty::{self, TyCtxt}; use rustc_query_system::dep_graph::HasDepContext; use rustc_query_system::query::{CycleError, QueryJobId, QueryJobInfo}; use rustc_query_system::query::{QueryContext, QueryDescription}; @@ -33,8 +34,8 @@ impl<'tcx> std::ops::Deref for QueryCtxt<'tcx> { } impl HasDepContext for QueryCtxt<'tcx> { - type DepKind = crate::dep_graph::DepKind; - type StableHashingContext = crate::ich::StableHashingContext<'tcx>; + type DepKind = rustc_middle::dep_graph::DepKind; + type StableHashingContext = rustc_middle::ich::StableHashingContext<'tcx>; type DepContext = TyCtxt<'tcx>; #[inline] @@ -251,7 +252,7 @@ impl<'tcx> QueryCtxt<'tcx> { macro_rules! encode_queries { ($($query:ident,)*) => { $( - on_disk_cache::encode_query_results::<_, ty::query::queries::$query<'_>>( + on_disk_cache::encode_query_results::<_, super::queries::$query<'_>>( self, encoder, query_result_index @@ -363,18 +364,6 @@ macro_rules! is_eval_always { }; } -macro_rules! query_storage { - ([][$K:ty, $V:ty]) => { - >::Cache - }; - ([storage($ty:ty) $($rest:tt)*][$K:ty, $V:ty]) => { - <$ty as CacheSelector<$K, $V>>::Cache - }; - ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => { - query_storage!([$($($modifiers)*)*][$($args)*]) - }; -} - macro_rules! hash_result { ([][$hcx:expr, $result:expr]) => {{ dep_graph::hash_result($hcx, &$result) @@ -392,13 +381,6 @@ macro_rules! define_queries { $($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => { - use std::mem; - use crate::{ - rustc_data_structures::stable_hasher::HashStable, - rustc_data_structures::stable_hasher::StableHasher, - ich::StableHashingContext - }; - define_queries_struct! { tcx: $tcx, input: ($(([$($modifiers)*] [$($attr)*] [$name]))*) @@ -407,7 +389,7 @@ macro_rules! define_queries { #[allow(nonstandard_style)] #[derive(Clone, Debug)] pub enum Query<$tcx> { - $($(#[$attr])* $name($($K)*)),* + $($(#[$attr])* $name(query_keys::$name<$tcx>)),* } impl<$tcx> Query<$tcx> { @@ -465,8 +447,8 @@ macro_rules! define_queries { } $(impl<$tcx> QueryConfig for queries::$name<$tcx> { - type Key = $($K)*; - type Value = $V; + type Key = query_keys::$name<$tcx>; + type Value = query_values::$name<$tcx>; type Stored = query_stored::$name<$tcx>; const NAME: &'static str = stringify!($name); } @@ -520,8 +502,8 @@ macro_rules! define_queries { #[allow(non_upper_case_globals)] pub mod query_callbacks { use super::*; - use crate::dep_graph::DepNode; - use crate::ty::query::{queries, query_keys}; + use rustc_middle::dep_graph::DepNode; + use rustc_middle::ty::query::query_keys; use rustc_query_system::dep_graph::DepNodeParams; use rustc_query_system::query::{force_query, QueryDescription}; diff --git a/compiler/rustc_middle/src/ty/query/profiling_support.rs b/compiler/rustc_query_impl/src/profiling_support.rs similarity index 99% rename from compiler/rustc_middle/src/ty/query/profiling_support.rs rename to compiler/rustc_query_impl/src/profiling_support.rs index aab5fd9e8a1..24485889731 100644 --- a/compiler/rustc_middle/src/ty/query/profiling_support.rs +++ b/compiler/rustc_query_impl/src/profiling_support.rs @@ -1,10 +1,9 @@ -use crate::ty::context::TyCtxt; -use crate::ty::WithOptConstParam; use measureme::{StringComponent, StringId}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::profiling::SelfProfiler; use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::definitions::DefPathData; +use rustc_middle::ty::{TyCtxt, WithOptConstParam}; use rustc_query_system::query::{QueryCache, QueryCacheStore}; use std::fmt::Debug; use std::io::Write; diff --git a/compiler/rustc_middle/src/ty/query/stats.rs b/compiler/rustc_query_impl/src/stats.rs similarity index 98% rename from compiler/rustc_middle/src/ty/query/stats.rs rename to compiler/rustc_query_impl/src/stats.rs index 47cbc7e43d2..4d52483c3b8 100644 --- a/compiler/rustc_middle/src/ty/query/stats.rs +++ b/compiler/rustc_query_impl/src/stats.rs @@ -1,6 +1,6 @@ -use crate::ty::query::query_storage; -use crate::ty::TyCtxt; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; +use rustc_middle::ty::query::query_storage; +use rustc_middle::ty::TyCtxt; use rustc_query_system::query::{QueryCache, QueryCacheStore}; use std::any::type_name; diff --git a/compiler/rustc_middle/src/ty/query/values.rs b/compiler/rustc_query_impl/src/values.rs similarity index 94% rename from compiler/rustc_middle/src/ty/query/values.rs rename to compiler/rustc_query_impl/src/values.rs index fa15395db4e..003867beeb7 100644 --- a/compiler/rustc_middle/src/ty/query/values.rs +++ b/compiler/rustc_query_impl/src/values.rs @@ -1,5 +1,5 @@ -use crate::ty::query::QueryCtxt; -use crate::ty::{self, AdtSizedConstraint, Ty, TyS}; +use super::QueryCtxt; +use rustc_middle::ty::{self, AdtSizedConstraint, Ty, TyS}; pub(super) trait Value<'tcx>: Sized { fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self; From 9823c2cc700fea541bf2670fcee93af662b63022 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 19 Feb 2021 21:48:47 +0100 Subject: [PATCH 23/23] Workaround rustdoc not honouring cfg(parallel_compiler). --- compiler/rustc_middle/src/ty/query/mod.rs | 1 - compiler/rustc_query_impl/src/plumbing.rs | 10 ++++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_middle/src/ty/query/mod.rs b/compiler/rustc_middle/src/ty/query/mod.rs index 0bc14f1e27c..51a214bc07b 100644 --- a/compiler/rustc_middle/src/ty/query/mod.rs +++ b/compiler/rustc_middle/src/ty/query/mod.rs @@ -230,7 +230,6 @@ macro_rules! define_callbacks { } pub trait QueryEngine<'tcx>: rustc_data_structures::sync::Sync { - #[cfg(parallel_compiler)] unsafe fn deadlock(&'tcx self, tcx: TyCtxt<'tcx>, registry: &rustc_rayon_core::Registry); fn encode_query_results( diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 466c1f79f48..d4093f281dd 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -631,10 +631,12 @@ macro_rules! define_queries_struct { } impl QueryEngine<'tcx> for Queries<'tcx> { - #[cfg(parallel_compiler)] - unsafe fn deadlock(&'tcx self, tcx: TyCtxt<'tcx>, registry: &rustc_rayon_core::Registry) { - let tcx = QueryCtxt { tcx, queries: self }; - rustc_query_system::query::deadlock(tcx, registry) + unsafe fn deadlock(&'tcx self, _tcx: TyCtxt<'tcx>, _registry: &rustc_rayon_core::Registry) { + #[cfg(parallel_compiler)] + { + let tcx = QueryCtxt { tcx: _tcx, queries: self }; + rustc_query_system::query::deadlock(tcx, _registry) + } } fn encode_query_results(