1 //! Query configuration and description traits.
3 use crate::dep_graph
::DepNode
;
4 use crate::dep_graph
::SerializedDepNodeIndex
;
5 use crate::query
::caches
::QueryCache
;
6 use crate::query
::plumbing
::CycleError
;
7 use crate::query
::{QueryContext, QueryState}
;
8 use rustc_data_structures
::profiling
::ProfileCategory
;
10 use rustc_data_structures
::fingerprint
::Fingerprint
;
15 // The parameter `CTX` is required in librustc_middle:
16 // implementations may need to access the `'tcx` lifetime in `CTX = TyCtxt<'tcx>`.
17 pub trait QueryConfig
<CTX
> {
18 const NAME
: &'
static str;
19 const CATEGORY
: ProfileCategory
;
21 type Key
: Eq
+ Hash
+ Clone
+ Debug
;
26 pub(crate) struct QueryVtable
<CTX
: QueryContext
, K
, V
> {
28 pub dep_kind
: CTX
::DepKind
,
29 pub eval_always
: bool
,
31 // Don't use this method to compute query results, instead use the methods on TyCtxt
32 pub compute
: fn(CTX
, K
) -> V
,
34 pub hash_result
: fn(&mut CTX
::StableHashingContext
, &V
) -> Option
<Fingerprint
>,
35 pub handle_cycle_error
: fn(CTX
, CycleError
<CTX
::Query
>) -> V
,
36 pub cache_on_disk
: fn(CTX
, &K
, Option
<&V
>) -> bool
,
37 pub try_load_from_disk
: fn(CTX
, SerializedDepNodeIndex
) -> Option
<V
>,
40 impl<CTX
: QueryContext
, K
, V
> QueryVtable
<CTX
, K
, V
> {
41 pub(crate) fn to_dep_node(&self, tcx
: CTX
, key
: &K
) -> DepNode
<CTX
::DepKind
>
43 K
: crate::dep_graph
::DepNodeParams
<CTX
>,
45 DepNode
::construct(tcx
, self.dep_kind
, key
)
48 pub(crate) fn compute(&self, tcx
: CTX
, key
: K
) -> V
{
49 (self.compute
)(tcx
, key
)
52 pub(crate) fn hash_result(
54 hcx
: &mut CTX
::StableHashingContext
,
56 ) -> Option
<Fingerprint
> {
57 (self.hash_result
)(hcx
, value
)
60 pub(crate) fn handle_cycle_error(&self, tcx
: CTX
, error
: CycleError
<CTX
::Query
>) -> V
{
61 (self.handle_cycle_error
)(tcx
, error
)
64 pub(crate) fn cache_on_disk(&self, tcx
: CTX
, key
: &K
, value
: Option
<&V
>) -> bool
{
65 (self.cache_on_disk
)(tcx
, key
, value
)
68 pub(crate) fn try_load_from_disk(&self, tcx
: CTX
, index
: SerializedDepNodeIndex
) -> Option
<V
> {
69 (self.try_load_from_disk
)(tcx
, index
)
73 pub trait QueryAccessors
<CTX
: QueryContext
>: QueryConfig
<CTX
> {
75 const EVAL_ALWAYS
: bool
;
76 const DEP_KIND
: CTX
::DepKind
;
78 type Cache
: QueryCache
<Key
= Self::Key
, Stored
= Self::Stored
, Value
= Self::Value
>;
80 // Don't use this method to access query results, instead use the methods on TyCtxt
81 fn query_state
<'a
>(tcx
: CTX
) -> &'a QueryState
<CTX
, Self::Cache
>;
83 fn to_dep_node(tcx
: CTX
, key
: &Self::Key
) -> DepNode
<CTX
::DepKind
>
85 Self::Key
: crate::dep_graph
::DepNodeParams
<CTX
>,
87 DepNode
::construct(tcx
, Self::DEP_KIND
, key
)
90 // Don't use this method to compute query results, instead use the methods on TyCtxt
91 fn compute(tcx
: CTX
, key
: Self::Key
) -> Self::Value
;
94 hcx
: &mut CTX
::StableHashingContext
,
96 ) -> Option
<Fingerprint
>;
98 fn handle_cycle_error(tcx
: CTX
, error
: CycleError
<CTX
::Query
>) -> Self::Value
;
101 pub trait QueryDescription
<CTX
: QueryContext
>: QueryAccessors
<CTX
> {
102 fn describe(tcx
: CTX
, key
: Self::Key
) -> Cow
<'
static, str>;
105 fn cache_on_disk(_
: CTX
, _
: &Self::Key
, _
: Option
<&Self::Value
>) -> bool
{
109 fn try_load_from_disk(_
: CTX
, _
: SerializedDepNodeIndex
) -> Option
<Self::Value
> {
110 panic
!("QueryDescription::load_from_disk() called for an unsupported query.")
114 pub(crate) trait QueryVtableExt
<CTX
: QueryContext
, K
, V
> {
115 const VTABLE
: QueryVtable
<CTX
, K
, V
>;
118 impl<CTX
, Q
> QueryVtableExt
<CTX
, Q
::Key
, Q
::Value
> for Q
121 Q
: QueryDescription
<CTX
>,
123 const VTABLE
: QueryVtable
<CTX
, Q
::Key
, Q
::Value
> = QueryVtable
{
125 dep_kind
: Q
::DEP_KIND
,
126 eval_always
: Q
::EVAL_ALWAYS
,
128 hash_result
: Q
::hash_result
,
129 handle_cycle_error
: Q
::handle_cycle_error
,
130 cache_on_disk
: Q
::cache_on_disk
,
131 try_load_from_disk
: Q
::try_load_from_disk
,