1use rustc_data_structures::jobserver::Proxy;
2use rustc_errors::DiagInner;
3use rustc_hashes::Hash64;
4use rustc_hir::def::DefKind;
5use rustc_macros::{Decodable, Encodable};
6use rustc_span::Span;
7use rustc_span::def_id::DefId;
89pub use self::caches::{DefIdCache, DefaultCache, QueryCache, SingleCache, VecCache};
10pub use self::config::{HashResult, QueryConfig};
11pub use self::job::{
12QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryMap, break_query_cycles, print_query_stack,
13report_cycle,
14};
15pub use self::plumbing::*;
16use crate::dep_graph::{DepKind, DepNodeIndex, HasDepContext, SerializedDepNodeIndex};
1718mod caches;
19mod config;
20mod job;
21mod plumbing;
2223/// Description of a frame in the query stack.
24///
25/// This is mostly used in case of cycles for error reporting.
26#[derive(#[automatically_derived]
impl ::core::clone::Clone for QueryStackFrame {
#[inline]
fn clone(&self) -> QueryStackFrame {
QueryStackFrame {
description: ::core::clone::Clone::clone(&self.description),
span: ::core::clone::Clone::clone(&self.span),
def_id: ::core::clone::Clone::clone(&self.def_id),
def_kind: ::core::clone::Clone::clone(&self.def_kind),
def_id_for_ty_in_cycle: ::core::clone::Clone::clone(&self.def_id_for_ty_in_cycle),
dep_kind: ::core::clone::Clone::clone(&self.dep_kind),
hash: ::core::clone::Clone::clone(&self.hash),
}
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for QueryStackFrame {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
let names: &'static _ =
&["description", "span", "def_id", "def_kind",
"def_id_for_ty_in_cycle", "dep_kind", "hash"];
let values: &[&dyn ::core::fmt::Debug] =
&[&self.description, &self.span, &self.def_id, &self.def_kind,
&self.def_id_for_ty_in_cycle, &self.dep_kind, &&self.hash];
::core::fmt::Formatter::debug_struct_fields_finish(f,
"QueryStackFrame", names, values)
}
}Debug)]
27pub struct QueryStackFrame {
28pub description: String,
29 span: Option<Span>,
30pub def_id: Option<DefId>,
31pub def_kind: Option<DefKind>,
32/// A def-id that is extracted from a `Ty` in a query key
33pub def_id_for_ty_in_cycle: Option<DefId>,
34pub dep_kind: DepKind,
35/// This hash is used to deterministically pick
36 /// a query to remove cycles in the parallel compiler.
37hash: Hash64,
38}
3940impl QueryStackFrame {
41#[inline]
42pub fn new(
43 description: String,
44 span: Option<Span>,
45 def_id: Option<DefId>,
46 def_kind: Option<DefKind>,
47 dep_kind: DepKind,
48 def_id_for_ty_in_cycle: Option<DefId>,
49 hash: Hash64,
50 ) -> Self {
51Self { description, span, def_id, def_kind, def_id_for_ty_in_cycle, dep_kind, hash }
52 }
5354// FIXME(eddyb) Get more valid `Span`s on queries.
55#[inline]
56pub fn default_span(&self, span: Span) -> Span {
57if !span.is_dummy() {
58return span;
59 }
60self.span.unwrap_or(span)
61 }
62}
6364/// Tracks 'side effects' for a particular query.
65/// This struct is saved to disk along with the query result,
66/// and loaded from disk if we mark the query as green.
67/// This allows us to 'replay' changes to global state
68/// that would otherwise only occur if we actually
69/// executed the query method.
70///
71/// Each side effect gets an unique dep node index which is added
72/// as a dependency of the query which had the effect.
73#[derive(#[automatically_derived]
impl ::core::fmt::Debug for QuerySideEffect {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
QuerySideEffect::Diagnostic(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"Diagnostic", &__self_0),
}
}
}Debug, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for QuerySideEffect {
fn encode(&self, __encoder: &mut __E) {
match *self {
QuerySideEffect::Diagnostic(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for QuerySideEffect {
fn decode(__decoder: &mut __D) -> Self {
QuerySideEffect::Diagnostic(::rustc_serialize::Decodable::decode(__decoder))
}
}
};Decodable)]
74pub enum QuerySideEffect {
75/// Stores a diagnostic emitted during query execution.
76 /// This diagnostic will be re-emitted if we mark
77 /// the query as green, as that query will have the side
78 /// effect dep node as a dependency.
79Diagnostic(DiagInner),
80}
8182pub trait QueryContext: HasDepContext {
83/// Gets a jobserver reference which is used to release then acquire
84 /// a token while waiting on a query.
85fn jobserver_proxy(&self) -> &Proxy;
8687fn next_job_id(self) -> QueryJobId;
8889/// Get the query information from the TLS context.
90fn current_query_job(self) -> Option<QueryJobId>;
9192fn collect_active_jobs(self, require_complete: bool) -> Result<QueryMap, QueryMap>;
9394/// Load a side effect associated to the node in the previous session.
95fn load_side_effect(
96self,
97 prev_dep_node_index: SerializedDepNodeIndex,
98 ) -> Option<QuerySideEffect>;
99100/// Register a side effect for the given node, for use in next session.
101fn store_side_effect(self, dep_node_index: DepNodeIndex, side_effect: QuerySideEffect);
102103/// Executes a job by changing the `ImplicitCtxt` to point to the
104 /// new query job while it executes.
105fn start_query<R>(self, token: QueryJobId, depth_limit: bool, compute: impl FnOnce() -> R)
106 -> R;
107108fn depth_limit_error(self, job: QueryJobId);
109}