2 pub use self::plumbing::*;
5 #[cfg(parallel_compiler)]
6 pub use self::job::deadlock;
7 pub use self::job::{print_query_stack, QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryMap};
10 pub use self::caches::{
11 ArenaCacheSelector, CacheSelector, DefaultCacheSelector, QueryCache, QueryStorage,
15 pub use self::config::{QueryConfig, QueryDescription, QueryVtable};
17 use crate::dep_graph::{DepNodeIndex, HasDepContext, SerializedDepNodeIndex};
19 use rustc_data_structures::sync::Lock;
20 use rustc_data_structures::thin_vec::ThinVec;
21 use rustc_errors::Diagnostic;
24 /// Description of a frame in the query stack.
26 /// This is mostly used in case of cycles for error reporting.
27 #[derive(Clone, Debug)]
28 pub struct QueryStackFrame {
29 pub name: &'static str,
30 pub description: String,
32 /// The `DefKind` this query frame is associated with, if applicable.
34 /// We can't use `rustc_hir::def::DefKind` because `rustc_hir` is not
35 /// available in `rustc_query_system`. Instead, we have a simplified
36 /// custom version of it, called [`SimpleDefKind`].
37 def_kind: Option<SimpleDefKind>,
38 /// This hash is used to deterministically pick
39 /// a query to remove cycles in the parallel compiler.
40 #[cfg(parallel_compiler)]
44 /// A simplified version of `rustc_hir::def::DefKind`.
46 /// It was added to help improve cycle errors caused by recursive type aliases.
47 /// As of August 2021, `rustc_query_system` cannot depend on `rustc_hir`
48 /// because it would create a dependency cycle. So, instead, a simplified
49 /// version of `DefKind` was added to `rustc_query_system`.
51 /// `DefKind`s are converted to `SimpleDefKind`s in `rustc_query_impl`.
52 #[derive(Debug, Copy, Clone)]
53 pub enum SimpleDefKind {
61 // FIXME: add more from `rustc_hir::def::DefKind` and then remove `Other`
65 impl QueryStackFrame {
71 def_kind: Option<SimpleDefKind>,
72 _hash: impl FnOnce() -> u64,
79 #[cfg(parallel_compiler)]
84 // FIXME(eddyb) Get more valid `Span`s on queries.
86 pub fn default_span(&self, span: Span) -> Span {
90 self.span.unwrap_or(span)
94 /// Tracks 'side effects' for a particular query.
95 /// This struct is saved to disk along with the query result,
96 /// and loaded from disk if we mark the query as green.
97 /// This allows us to 'replay' changes to global state
98 /// that would otherwise only occur if we actually
99 /// executed the query method.
100 #[derive(Debug, Clone, Default, Encodable, Decodable)]
101 pub struct QuerySideEffects {
102 /// Stores any diagnostics emitted during query execution.
103 /// These diagnostics will be re-emitted if we mark
104 /// the query as green.
105 pub(super) diagnostics: ThinVec<Diagnostic>,
108 impl QuerySideEffects {
109 pub fn is_empty(&self) -> bool {
110 let QuerySideEffects { diagnostics } = self;
111 diagnostics.is_empty()
113 pub fn append(&mut self, other: QuerySideEffects) {
114 let QuerySideEffects { diagnostics } = self;
115 diagnostics.extend(other.diagnostics);
119 pub trait QueryContext: HasDepContext {
120 /// Get the query information from the TLS context.
121 fn current_query_job(&self) -> Option<QueryJobId<Self::DepKind>>;
123 fn try_collect_active_jobs(&self) -> Option<QueryMap<Self::DepKind>>;
125 /// Load side effects associated to the node in the previous session.
126 fn load_side_effects(&self, prev_dep_node_index: SerializedDepNodeIndex) -> QuerySideEffects;
128 /// Register diagnostics for the given node, for use in next session.
129 fn store_side_effects(&self, dep_node_index: DepNodeIndex, side_effects: QuerySideEffects);
131 /// Register diagnostics for the given node, for use in next session.
132 fn store_side_effects_for_anon_node(
134 dep_node_index: DepNodeIndex,
135 side_effects: QuerySideEffects,
138 /// Executes a job by changing the `ImplicitCtxt` to point to the
139 /// new query job while it executes. It returns the diagnostics
140 /// captured during execution and the actual result.
143 token: QueryJobId<Self::DepKind>,
144 diagnostics: Option<&Lock<ThinVec<Diagnostic>>>,
145 compute: impl FnOnce() -> R,