From 1cf7bcc388b5aee7ef940d730d1ede212f8e5a31 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 23 Aug 2022 21:47:59 -0500 Subject: [PATCH 1/7] Get rid of `make_query` module --- compiler/rustc_query_impl/src/plumbing.rs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index eabb316614747..b115381eb1c1d 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -308,18 +308,6 @@ macro_rules! define_queries { input: ($(([$($modifiers)*] [$($attr)*] [$name]))*) } - mod make_query { - use super::*; - - // Create an eponymous constructor for each query. - $(#[allow(nonstandard_style)] $(#[$attr])* - pub fn $name<'tcx>(tcx: QueryCtxt<'tcx>, key: as QueryConfig>::Key) -> QueryStackFrame { - let kind = dep_graph::DepKind::$name; - let name = stringify!($name); - $crate::plumbing::create_query_frame(tcx, queries::$name::describe, key, kind, name) - })* - } - #[allow(nonstandard_style)] mod queries { use std::marker::PhantomData; @@ -531,9 +519,14 @@ macro_rules! define_queries_struct { let mut jobs = QueryMap::default(); $( + let make_query = |tcx, key| { + let kind = dep_graph::DepKind::$name; + let name = stringify!($name); + $crate::plumbing::create_query_frame(tcx, queries::$name::describe, key, kind, name) + }; self.$name.try_collect_active_jobs( tcx, - make_query::$name, + make_query, &mut jobs, )?; )* From 375d78012f2e7bdeba942eeb2a85115d1b1a98cb Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 23 Aug 2022 22:10:47 -0500 Subject: [PATCH 2/7] Move `try_on_disk_cache` out of the giant macro --- compiler/rustc_query_impl/src/plumbing.rs | 30 ++++++++++++++--------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index b115381eb1c1d..e0707eee8ba66 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -7,7 +7,7 @@ use crate::{on_disk_cache, Queries}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::Lock; use rustc_errors::{Diagnostic, Handler}; -use rustc_middle::dep_graph::{self, DepKind, DepNodeIndex, SerializedDepNodeIndex}; +use rustc_middle::dep_graph::{self, DepKind, DepNode, DepNodeIndex, SerializedDepNodeIndex}; use rustc_middle::ty::tls::{self, ImplicitCtxt}; use rustc_middle::ty::{self, TyCtxt}; use rustc_query_system::dep_graph::HasDepContext; @@ -298,6 +298,23 @@ pub(crate) fn create_query_frame< QueryStackFrame::new(name, description, span, def_kind, hash) } +pub(crate) fn try_load_from_on_disk_cache<'tcx, K, V>( + tcx: TyCtxt<'tcx>, + dep_node: DepNode, + recover: fn(TyCtxt<'tcx>, DepNode) -> Option, + cache_on_disk: fn(TyCtxt<'tcx>, &K) -> bool, + do_query: fn(TyCtxt<'tcx>, K) -> V, +) { + debug_assert!(tcx.dep_graph.is_green(&dep_node)); + + let key = recover(tcx, dep_node).unwrap_or_else(|| { + panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash) + }); + if cache_on_disk(tcx, &key) { + let _ = do_query(tcx, key); + } +} + // NOTE: `$V` isn't used here, but we still need to match on it so it can be passed to other macros // invoked by `rustc_query_append`. macro_rules! define_queries { @@ -457,21 +474,12 @@ macro_rules! define_queries { } } - fn try_load_from_on_disk_cache(tcx: TyCtxt<'_>, dep_node: DepNode) { - debug_assert!(tcx.dep_graph.is_green(&dep_node)); - - 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) { - let _ = tcx.$name(key); - } - } - DepKindStruct { is_anon, is_eval_always, fingerprint_style, force_from_dep_node: Some(force_from_dep_node), - try_load_from_on_disk_cache: Some(try_load_from_on_disk_cache), + try_load_from_on_disk_cache: Some(|tcx, key| $crate::plumbing::try_load_from_on_disk_cache(tcx, key, recover, queries::$name::cache_on_disk, TyCtxt::$name)), } })* } From 70f20ac40ea95f4bba330858750e81f4ab2b8b3a Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 23 Aug 2022 22:24:39 -0500 Subject: [PATCH 3/7] Move `force_with_dep_node` outside the giant macro --- compiler/rustc_query_impl/src/plumbing.rs | 42 ++++++++++++++--------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index e0707eee8ba66..7c6b898751a94 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -10,10 +10,11 @@ use rustc_errors::{Diagnostic, Handler}; use rustc_middle::dep_graph::{self, DepKind, DepNode, DepNodeIndex, SerializedDepNodeIndex}; use rustc_middle::ty::tls::{self, ImplicitCtxt}; use rustc_middle::ty::{self, TyCtxt}; -use rustc_query_system::dep_graph::HasDepContext; +use rustc_query_system::dep_graph::{DepNodeParams, HasDepContext}; use rustc_query_system::ich::StableHashingContext; use rustc_query_system::query::{ - QueryContext, QueryJobId, QueryMap, QuerySideEffects, QueryStackFrame, + force_query, QueryContext, QueryDescription, QueryJobId, QueryMap, QuerySideEffects, + QueryStackFrame, }; use std::any::Any; use std::num::NonZeroU64; @@ -315,6 +316,27 @@ pub(crate) fn try_load_from_on_disk_cache<'tcx, K, V>( } } +pub(crate) fn force_from_dep_node<'tcx, Q>( + tcx: TyCtxt<'tcx>, + // dep_node: rustc_query_system::dep_graph::DepNode, + dep_node: DepNode, + recover: fn(TyCtxt<'tcx>, DepNode) -> Option, +) -> bool +where + Q: QueryDescription>, + Q::Key: DepNodeParams>, +{ + if let Some(key) = recover(tcx, dep_node) { + #[cfg(debug_assertions)] + let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered(); + let tcx = QueryCtxt::from_tcx(tcx); + force_query::(tcx, key, dep_node); + true + } else { + false + } +} + // NOTE: `$V` isn't used here, but we still need to match on it so it can be passed to other macros // invoked by `rustc_query_append`. macro_rules! define_queries { @@ -385,7 +407,7 @@ macro_rules! define_queries { use super::*; use rustc_middle::dep_graph::DepNode; use rustc_query_system::dep_graph::DepNodeParams; - use rustc_query_system::query::{force_query, QueryDescription}; + use rustc_query_system::query::QueryDescription; use rustc_query_system::dep_graph::FingerprintStyle; // We use this for most things when incr. comp. is turned off. @@ -462,23 +484,11 @@ macro_rules! define_queries { < as QueryConfig>::Key as DepNodeParams>>::recover(tcx, &dep_node) } - fn force_from_dep_node(tcx: TyCtxt<'_>, dep_node: DepNode) -> bool { - if let Some(key) = recover(tcx, dep_node) { - #[cfg(debug_assertions)] - let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered(); - let tcx = QueryCtxt::from_tcx(tcx); - force_query::, _>(tcx, key, dep_node); - true - } else { - false - } - } - DepKindStruct { is_anon, is_eval_always, fingerprint_style, - force_from_dep_node: Some(force_from_dep_node), + force_from_dep_node: Some(|tcx, dep_node| $crate::plumbing::force_from_dep_node::>(tcx, dep_node, recover)), try_load_from_on_disk_cache: Some(|tcx, key| $crate::plumbing::try_load_from_on_disk_cache(tcx, key, recover, queries::$name::cache_on_disk, TyCtxt::$name)), } })* From 8f442e8ded9cd246e19ec9886eb50c2131a6e7ba Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 23 Aug 2022 22:49:20 -0500 Subject: [PATCH 4/7] Get rid of `fn recover` --- compiler/rustc_query_impl/src/plumbing.rs | 26 +++++++---------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 7c6b898751a94..3483c40396b59 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -299,16 +299,15 @@ pub(crate) fn create_query_frame< QueryStackFrame::new(name, description, span, def_kind, hash) } -pub(crate) fn try_load_from_on_disk_cache<'tcx, K, V>( +pub(crate) fn try_load_from_on_disk_cache<'tcx, K: DepNodeParams>, V>( tcx: TyCtxt<'tcx>, dep_node: DepNode, - recover: fn(TyCtxt<'tcx>, DepNode) -> Option, cache_on_disk: fn(TyCtxt<'tcx>, &K) -> bool, do_query: fn(TyCtxt<'tcx>, K) -> V, ) { debug_assert!(tcx.dep_graph.is_green(&dep_node)); - let key = recover(tcx, dep_node).unwrap_or_else(|| { + let key = K::recover(tcx, &dep_node).unwrap_or_else(|| { panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash) }); if cache_on_disk(tcx, &key) { @@ -316,17 +315,12 @@ pub(crate) fn try_load_from_on_disk_cache<'tcx, K, V>( } } -pub(crate) fn force_from_dep_node<'tcx, Q>( - tcx: TyCtxt<'tcx>, - // dep_node: rustc_query_system::dep_graph::DepNode, - dep_node: DepNode, - recover: fn(TyCtxt<'tcx>, DepNode) -> Option, -) -> bool +fn force_from_dep_node<'tcx, Q>(tcx: TyCtxt<'tcx>, dep_node: DepNode) -> bool where Q: QueryDescription>, Q::Key: DepNodeParams>, { - if let Some(key) = recover(tcx, dep_node) { + if let Some(key) = Q::Key::recover(tcx, &dep_node) { #[cfg(debug_assertions)] let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered(); let tcx = QueryCtxt::from_tcx(tcx); @@ -405,7 +399,6 @@ macro_rules! define_queries { #[allow(nonstandard_style)] mod query_callbacks { use super::*; - use rustc_middle::dep_graph::DepNode; use rustc_query_system::dep_graph::DepNodeParams; use rustc_query_system::query::QueryDescription; use rustc_query_system::dep_graph::FingerprintStyle; @@ -479,17 +472,14 @@ macro_rules! define_queries { } } - #[inline(always)] - fn recover<'tcx>(tcx: TyCtxt<'tcx>, dep_node: DepNode) -> Option< as QueryConfig>::Key> { - < as QueryConfig>::Key as DepNodeParams>>::recover(tcx, &dep_node) - } - DepKindStruct { is_anon, is_eval_always, fingerprint_style, - force_from_dep_node: Some(|tcx, dep_node| $crate::plumbing::force_from_dep_node::>(tcx, dep_node, recover)), - try_load_from_on_disk_cache: Some(|tcx, key| $crate::plumbing::try_load_from_on_disk_cache(tcx, key, recover, queries::$name::cache_on_disk, TyCtxt::$name)), + force_from_dep_node: Some(|tcx, dep_node| $crate::plumbing::force_from_dep_node::>(tcx, dep_node)), + try_load_from_on_disk_cache: Some(|tcx, key| $crate::plumbing::try_load_from_on_disk_cache::< + as QueryConfig>::Key, _ + >(tcx, key, queries::$name::cache_on_disk, TyCtxt::$name)), } })* } From 83b6dc9588b6f970fd2a1c2da6373bebe406946f Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 23 Aug 2022 23:31:12 -0500 Subject: [PATCH 5/7] Move almost all of the function in `query_callbacks` to a generic function --- compiler/rustc_query_impl/src/plumbing.rs | 75 ++++++++++++++--------- 1 file changed, 47 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 3483c40396b59..49afa3b363431 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -7,14 +7,16 @@ use crate::{on_disk_cache, Queries}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::Lock; use rustc_errors::{Diagnostic, Handler}; -use rustc_middle::dep_graph::{self, DepKind, DepNode, DepNodeIndex, SerializedDepNodeIndex}; +use rustc_middle::dep_graph::{ + self, DepKind, DepKindStruct, DepNode, DepNodeIndex, SerializedDepNodeIndex, +}; use rustc_middle::ty::tls::{self, ImplicitCtxt}; use rustc_middle::ty::{self, TyCtxt}; use rustc_query_system::dep_graph::{DepNodeParams, HasDepContext}; use rustc_query_system::ich::StableHashingContext; use rustc_query_system::query::{ - force_query, QueryContext, QueryDescription, QueryJobId, QueryMap, QuerySideEffects, - QueryStackFrame, + force_query, QueryConfig, QueryContext, QueryDescription, QueryJobId, QueryMap, + QuerySideEffects, QueryStackFrame, }; use std::any::Any; use std::num::NonZeroU64; @@ -303,7 +305,7 @@ pub(crate) fn try_load_from_on_disk_cache<'tcx, K: DepNodeParams>, tcx: TyCtxt<'tcx>, dep_node: DepNode, cache_on_disk: fn(TyCtxt<'tcx>, &K) -> bool, - do_query: fn(TyCtxt<'tcx>, K) -> V, + cache_query_deps: fn(TyCtxt<'tcx>, K) -> V, ) { debug_assert!(tcx.dep_graph.is_green(&dep_node)); @@ -311,11 +313,11 @@ pub(crate) fn try_load_from_on_disk_cache<'tcx, K: DepNodeParams>, panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash) }); if cache_on_disk(tcx, &key) { - let _ = do_query(tcx, key); + let _ = cache_query_deps(tcx, key); } } -fn force_from_dep_node<'tcx, Q>(tcx: TyCtxt<'tcx>, dep_node: DepNode) -> bool +pub(crate) fn force_from_dep_node<'tcx, Q>(tcx: TyCtxt<'tcx>, dep_node: DepNode) -> bool where Q: QueryDescription>, Q::Key: DepNodeParams>, @@ -331,6 +333,39 @@ where } } +pub(crate) fn query_callback<'tcx, Q: QueryConfig>( + // NOTE: we can't remove these function pointers, because `recover` is invariant -> `try_load_from_on_disk_cache` takes a concrete lifetime, not a universal lifetime. + // Instead, we infer the correct lifetime at the callsite, so we can pass in a HRTB function pointer to the DepKindStruct. + try_load_from_on_disk_cache: fn(TyCtxt<'_>, DepNode), + force_from_dep_node: fn(TyCtxt<'_>, DepNode) -> bool, + is_anon: bool, + is_eval_always: bool, +) -> DepKindStruct +where + Q: QueryDescription>, + Q::Key: DepNodeParams>, +{ + let fingerprint_style = Q::Key::fingerprint_style(); + + if is_anon || !fingerprint_style.reconstructible() { + return DepKindStruct { + is_anon, + is_eval_always, + fingerprint_style, + force_from_dep_node: None, + try_load_from_on_disk_cache: None, + }; + } + + DepKindStruct { + is_anon, + is_eval_always, + fingerprint_style, + force_from_dep_node: Some(force_from_dep_node), + try_load_from_on_disk_cache: Some(try_load_from_on_disk_cache), + } +} + // NOTE: `$V` isn't used here, but we still need to match on it so it can be passed to other macros // invoked by `rustc_query_append`. macro_rules! define_queries { @@ -399,7 +434,6 @@ macro_rules! define_queries { #[allow(nonstandard_style)] mod query_callbacks { use super::*; - use rustc_query_system::dep_graph::DepNodeParams; use rustc_query_system::query::QueryDescription; use rustc_query_system::dep_graph::FingerprintStyle; @@ -458,29 +492,14 @@ macro_rules! define_queries { $(pub(crate) fn $name()-> DepKindStruct { let is_anon = is_anon!([$($modifiers)*]); let is_eval_always = is_eval_always!([$($modifiers)*]); + type Q<'tcx> = queries::$name<'tcx>; - let fingerprint_style = - < as QueryConfig>::Key as DepNodeParams>>::fingerprint_style(); - - if is_anon || !fingerprint_style.reconstructible() { - return DepKindStruct { - is_anon, - is_eval_always, - fingerprint_style, - force_from_dep_node: None, - try_load_from_on_disk_cache: None, - } - } - - DepKindStruct { + $crate::plumbing::query_callback::>( + |tcx, key| $crate::plumbing::try_load_from_on_disk_cache::< as QueryConfig>::Key, _>(tcx, key, >::cache_on_disk, TyCtxt::$name), + |tcx, key| $crate::plumbing::force_from_dep_node::>(tcx, key), is_anon, - is_eval_always, - fingerprint_style, - force_from_dep_node: Some(|tcx, dep_node| $crate::plumbing::force_from_dep_node::>(tcx, dep_node)), - try_load_from_on_disk_cache: Some(|tcx, key| $crate::plumbing::try_load_from_on_disk_cache::< - as QueryConfig>::Key, _ - >(tcx, key, queries::$name::cache_on_disk, TyCtxt::$name)), - } + is_eval_always + ) })* } From 4fcc7452666a82c677ae6563bad31c852c258215 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 23 Aug 2022 23:34:23 -0500 Subject: [PATCH 6/7] Simplify `try_load_from_on_disk_cache` --- compiler/rustc_query_impl/src/plumbing.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 49afa3b363431..cc7e07651710c 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -301,18 +301,20 @@ pub(crate) fn create_query_frame< QueryStackFrame::new(name, description, span, def_kind, hash) } -pub(crate) fn try_load_from_on_disk_cache<'tcx, K: DepNodeParams>, V>( +pub(crate) fn try_load_from_on_disk_cache<'tcx, Q, V>( tcx: TyCtxt<'tcx>, dep_node: DepNode, - cache_on_disk: fn(TyCtxt<'tcx>, &K) -> bool, - cache_query_deps: fn(TyCtxt<'tcx>, K) -> V, -) { + cache_query_deps: fn(TyCtxt<'tcx>, Q::Key) -> V, +) where + Q: QueryDescription>, + Q::Key: DepNodeParams>, +{ debug_assert!(tcx.dep_graph.is_green(&dep_node)); - let key = K::recover(tcx, &dep_node).unwrap_or_else(|| { + let key = Q::Key::recover(tcx, &dep_node).unwrap_or_else(|| { panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash) }); - if cache_on_disk(tcx, &key) { + if Q::cache_on_disk(tcx, &key) { let _ = cache_query_deps(tcx, key); } } @@ -434,7 +436,6 @@ macro_rules! define_queries { #[allow(nonstandard_style)] mod query_callbacks { use super::*; - use rustc_query_system::query::QueryDescription; use rustc_query_system::dep_graph::FingerprintStyle; // We use this for most things when incr. comp. is turned off. @@ -495,7 +496,7 @@ macro_rules! define_queries { type Q<'tcx> = queries::$name<'tcx>; $crate::plumbing::query_callback::>( - |tcx, key| $crate::plumbing::try_load_from_on_disk_cache::< as QueryConfig>::Key, _>(tcx, key, >::cache_on_disk, TyCtxt::$name), + |tcx, key| $crate::plumbing::try_load_from_on_disk_cache::, _>(tcx, key, TyCtxt::$name), |tcx, key| $crate::plumbing::force_from_dep_node::>(tcx, key), is_anon, is_eval_always From 4e09a13bb848a64acf6bb20359f582e813e74764 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 29 Aug 2022 10:20:14 -0500 Subject: [PATCH 7/7] Don't create two new closures for each query - Parameterize DepKindStruct over `'tcx` This allows passing in an invariant function pointer in `query_callback`, rather than having to try and make it work for any lifetime. - Add a new `execute_query` function to `QueryDescription` so we can call `tcx.$name` without needing to be in a macro context --- compiler/rustc_middle/src/arena.rs | 2 +- .../rustc_middle/src/dep_graph/dep_node.rs | 6 +-- compiler/rustc_middle/src/ty/context.rs | 6 +-- compiler/rustc_query_impl/src/plumbing.rs | 51 ++++++++----------- .../rustc_query_system/src/query/config.rs | 3 ++ 5 files changed, 31 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index b94de537dc81e..65d5f755f7248 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -100,7 +100,7 @@ macro_rules! arena_types { [decode] is_late_bound_map: rustc_data_structures::fx::FxIndexSet, [decode] impl_source: rustc_middle::traits::ImplSource<'tcx, ()>, - [] dep_kind: rustc_middle::dep_graph::DepKindStruct, + [] dep_kind: rustc_middle::dep_graph::DepKindStruct<'tcx>, ]); ) } diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 65fc8a2e9cf5a..7718906ac4ee7 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -74,7 +74,7 @@ pub use rustc_query_system::dep_graph::{DepContext, DepNodeParams}; /// Information is retrieved by indexing the `DEP_KINDS` array using the integer value /// of the `DepKind`. Overall, this allows to implement `DepContext` using this manual /// jump table instead of large matches. -pub struct DepKindStruct { +pub struct DepKindStruct<'tcx> { /// Anonymous queries cannot be replayed from one compiler invocation to the next. /// When their result is needed, it is recomputed. They are useful for fine-grained /// dependency tracking, and caching within one compiler invocation. @@ -124,10 +124,10 @@ pub struct DepKindStruct { /// 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`. - pub force_from_dep_node: Option, dep_node: DepNode) -> bool>, + pub force_from_dep_node: Option, dep_node: DepNode) -> bool>, /// Invoke a query to put the on-disk cached value in memory. - pub try_load_from_on_disk_cache: Option, DepNode)>, + pub try_load_from_on_disk_cache: Option, DepNode)>, } impl DepKind { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 052bb1263c98f..7a990773ab875 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1089,7 +1089,7 @@ pub struct GlobalCtxt<'tcx> { pub queries: &'tcx dyn query::QueryEngine<'tcx>, pub query_caches: query::QueryCaches<'tcx>, - query_kinds: &'tcx [DepKindStruct], + query_kinds: &'tcx [DepKindStruct<'tcx>], // Internal caches for metadata decoding. No need to track deps on this. pub ty_rcache: Lock>>, @@ -1246,7 +1246,7 @@ impl<'tcx> TyCtxt<'tcx> { dep_graph: DepGraph, on_disk_cache: Option<&'tcx dyn OnDiskCache<'tcx>>, queries: &'tcx dyn query::QueryEngine<'tcx>, - query_kinds: &'tcx [DepKindStruct], + query_kinds: &'tcx [DepKindStruct<'tcx>], crate_name: &str, output_filenames: OutputFilenames, ) -> GlobalCtxt<'tcx> { @@ -1296,7 +1296,7 @@ impl<'tcx> TyCtxt<'tcx> { } } - pub(crate) fn query_kind(self, k: DepKind) -> &'tcx DepKindStruct { + pub(crate) fn query_kind(self, k: DepKind) -> &'tcx DepKindStruct<'tcx> { &self.query_kinds[k as usize] } diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index cc7e07651710c..274df5b5e5e94 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -301,11 +301,8 @@ pub(crate) fn create_query_frame< QueryStackFrame::new(name, description, span, def_kind, hash) } -pub(crate) fn try_load_from_on_disk_cache<'tcx, Q, V>( - tcx: TyCtxt<'tcx>, - dep_node: DepNode, - cache_query_deps: fn(TyCtxt<'tcx>, Q::Key) -> V, -) where +fn try_load_from_on_disk_cache<'tcx, Q>(tcx: TyCtxt<'tcx>, dep_node: DepNode) +where Q: QueryDescription>, Q::Key: DepNodeParams>, { @@ -315,11 +312,11 @@ pub(crate) fn try_load_from_on_disk_cache<'tcx, Q, V>( panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash) }); if Q::cache_on_disk(tcx, &key) { - let _ = cache_query_deps(tcx, key); + let _ = Q::execute_query(tcx, key); } } -pub(crate) fn force_from_dep_node<'tcx, Q>(tcx: TyCtxt<'tcx>, dep_node: DepNode) -> bool +fn force_from_dep_node<'tcx, Q>(tcx: TyCtxt<'tcx>, dep_node: DepNode) -> bool where Q: QueryDescription>, Q::Key: DepNodeParams>, @@ -336,13 +333,9 @@ where } pub(crate) fn query_callback<'tcx, Q: QueryConfig>( - // NOTE: we can't remove these function pointers, because `recover` is invariant -> `try_load_from_on_disk_cache` takes a concrete lifetime, not a universal lifetime. - // Instead, we infer the correct lifetime at the callsite, so we can pass in a HRTB function pointer to the DepKindStruct. - try_load_from_on_disk_cache: fn(TyCtxt<'_>, DepNode), - force_from_dep_node: fn(TyCtxt<'_>, DepNode) -> bool, is_anon: bool, is_eval_always: bool, -) -> DepKindStruct +) -> DepKindStruct<'tcx> where Q: QueryDescription>, Q::Key: DepNodeParams>, @@ -363,8 +356,8 @@ where is_anon, is_eval_always, fingerprint_style, - force_from_dep_node: Some(force_from_dep_node), - try_load_from_on_disk_cache: Some(try_load_from_on_disk_cache), + force_from_dep_node: Some(force_from_dep_node::), + try_load_from_on_disk_cache: Some(try_load_from_on_disk_cache::), } } @@ -431,6 +424,10 @@ macro_rules! define_queries { try_load_from_disk: Self::TRY_LOAD_FROM_DISK, } } + + fn execute_query(tcx: TyCtxt<'tcx>, k: Self::Key) -> Self::Stored { + tcx.$name(k) + } })* #[allow(nonstandard_style)] @@ -439,7 +436,7 @@ macro_rules! define_queries { use rustc_query_system::dep_graph::FingerprintStyle; // We use this for most things when incr. comp. is turned off. - pub fn Null() -> DepKindStruct { + pub fn Null<'tcx>() -> DepKindStruct<'tcx> { DepKindStruct { is_anon: false, is_eval_always: false, @@ -450,7 +447,7 @@ macro_rules! define_queries { } // We use this for the forever-red node. - pub fn Red() -> DepKindStruct { + pub fn Red<'tcx>() -> DepKindStruct<'tcx> { DepKindStruct { is_anon: false, is_eval_always: false, @@ -460,7 +457,7 @@ macro_rules! define_queries { } } - pub fn TraitSelect() -> DepKindStruct { + pub fn TraitSelect<'tcx>() -> DepKindStruct<'tcx> { DepKindStruct { is_anon: true, is_eval_always: false, @@ -470,7 +467,7 @@ macro_rules! define_queries { } } - pub fn CompileCodegenUnit() -> DepKindStruct { + pub fn CompileCodegenUnit<'tcx>() -> DepKindStruct<'tcx> { DepKindStruct { is_anon: false, is_eval_always: false, @@ -480,7 +477,7 @@ macro_rules! define_queries { } } - pub fn CompileMonoItem() -> DepKindStruct { + pub fn CompileMonoItem<'tcx>() -> DepKindStruct<'tcx> { DepKindStruct { is_anon: false, is_eval_always: false, @@ -490,21 +487,15 @@ macro_rules! define_queries { } } - $(pub(crate) fn $name()-> DepKindStruct { - let is_anon = is_anon!([$($modifiers)*]); - let is_eval_always = is_eval_always!([$($modifiers)*]); - type Q<'tcx> = queries::$name<'tcx>; - - $crate::plumbing::query_callback::>( - |tcx, key| $crate::plumbing::try_load_from_on_disk_cache::, _>(tcx, key, TyCtxt::$name), - |tcx, key| $crate::plumbing::force_from_dep_node::>(tcx, key), - is_anon, - is_eval_always + $(pub(crate) fn $name<'tcx>()-> DepKindStruct<'tcx> { + $crate::plumbing::query_callback::>( + is_anon!([$($modifiers)*]), + is_eval_always!([$($modifiers)*]), ) })* } - pub fn query_callbacks<'tcx>(arena: &'tcx Arena<'tcx>) -> &'tcx [DepKindStruct] { + pub fn query_callbacks<'tcx>(arena: &'tcx Arena<'tcx>) -> &'tcx [DepKindStruct<'tcx>] { arena.alloc_from_iter(make_dep_kind_array!(query_callbacks)) } } diff --git a/compiler/rustc_query_system/src/query/config.rs b/compiler/rustc_query_system/src/query/config.rs index bd0fd7ac3503a..ea38df836cbf1 100644 --- a/compiler/rustc_query_system/src/query/config.rs +++ b/compiler/rustc_query_system/src/query/config.rs @@ -73,4 +73,7 @@ pub trait QueryDescription: QueryConfig { fn make_vtable(tcx: CTX, key: &Self::Key) -> QueryVTable; fn cache_on_disk(tcx: CTX::DepContext, key: &Self::Key) -> bool; + + // Don't use this method to compute query results, instead use the methods on TyCtxt + fn execute_query(tcx: CTX::DepContext, k: Self::Key) -> Self::Stored; }