Skip to content

Commit 3abd475

Browse files
committed
Make QueryCache parameters associated types.
1 parent 7309b3c commit 3abd475

File tree

5 files changed

+101
-94
lines changed

5 files changed

+101
-94
lines changed

src/librustc/ty/query/caches.rs

+29-16
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@ use rustc_data_structures::fx::FxHashMap;
66
use rustc_data_structures::sharded::Sharded;
77
use std::default::Default;
88
use std::hash::Hash;
9+
use std::marker::PhantomData;
910

1011
pub(crate) trait CacheSelector<K, V> {
11-
type Cache: QueryCache<K, V>;
12+
type Cache: QueryCache<Key = K, Value = V>;
1213
}
1314

14-
pub(crate) trait QueryCache<K, V>: Default {
15+
pub(crate) trait QueryCache: Default {
16+
type Key;
17+
type Value;
1518
type Sharded: Default;
1619

1720
/// Checks if the query is already computed and in the cache.
@@ -20,52 +23,62 @@ pub(crate) trait QueryCache<K, V>: Default {
2023
/// to compute it.
2124
fn lookup<'tcx, R, GetCache, OnHit, OnMiss>(
2225
&self,
23-
state: &'tcx QueryStateImpl<'tcx, K, V, Self>,
26+
state: &'tcx QueryStateImpl<'tcx, Self>,
2427
get_cache: GetCache,
25-
key: K,
28+
key: Self::Key,
2629
// `on_hit` can be called while holding a lock to the query state shard.
2730
on_hit: OnHit,
2831
on_miss: OnMiss,
2932
) -> R
3033
where
31-
GetCache:
32-
for<'a> Fn(&'a mut QueryStateShard<'tcx, K, Self::Sharded>) -> &'a mut Self::Sharded,
33-
OnHit: FnOnce(&V, DepNodeIndex) -> R,
34-
OnMiss: FnOnce(K, QueryLookup<'tcx, K, Self::Sharded>) -> R;
34+
GetCache: for<'a> Fn(
35+
&'a mut QueryStateShard<'tcx, Self::Key, Self::Sharded>,
36+
) -> &'a mut Self::Sharded,
37+
OnHit: FnOnce(&Self::Value, DepNodeIndex) -> R,
38+
OnMiss: FnOnce(Self::Key, QueryLookup<'tcx, Self::Key, Self::Sharded>) -> R;
3539

3640
fn complete(
3741
&self,
3842
tcx: TyCtxt<'tcx>,
3943
lock_sharded_storage: &mut Self::Sharded,
40-
key: K,
41-
value: V,
44+
key: Self::Key,
45+
value: Self::Value,
4246
index: DepNodeIndex,
4347
);
4448

4549
fn iter<R, L>(
4650
&self,
4751
shards: &Sharded<L>,
4852
get_shard: impl Fn(&mut L) -> &mut Self::Sharded,
49-
f: impl for<'a> FnOnce(Box<dyn Iterator<Item = (&'a K, &'a V, DepNodeIndex)> + 'a>) -> R,
53+
f: impl for<'a> FnOnce(
54+
Box<dyn Iterator<Item = (&'a Self::Key, &'a Self::Value, DepNodeIndex)> + 'a>,
55+
) -> R,
5056
) -> R;
5157
}
5258

5359
pub struct DefaultCacheSelector;
5460

5561
impl<K: Eq + Hash, V: Clone> CacheSelector<K, V> for DefaultCacheSelector {
56-
type Cache = DefaultCache;
62+
type Cache = DefaultCache<K, V>;
5763
}
5864

59-
#[derive(Default)]
60-
pub struct DefaultCache;
65+
pub struct DefaultCache<K, V>(PhantomData<(K, V)>);
66+
67+
impl<K, V> Default for DefaultCache<K, V> {
68+
fn default() -> Self {
69+
DefaultCache(PhantomData)
70+
}
71+
}
6172

62-
impl<K: Eq + Hash, V: Clone> QueryCache<K, V> for DefaultCache {
73+
impl<K: Eq + Hash, V: Clone> QueryCache for DefaultCache<K, V> {
74+
type Key = K;
75+
type Value = V;
6376
type Sharded = FxHashMap<K, (V, DepNodeIndex)>;
6477

6578
#[inline(always)]
6679
fn lookup<'tcx, R, GetCache, OnHit, OnMiss>(
6780
&self,
68-
state: &'tcx QueryStateImpl<'tcx, K, V, Self>,
81+
state: &'tcx QueryStateImpl<'tcx, Self>,
6982
get_cache: GetCache,
7083
key: K,
7184
on_hit: OnHit,

src/librustc/ty/query/config.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub(crate) trait QueryAccessors<'tcx>: QueryConfig<'tcx> {
3030
const EVAL_ALWAYS: bool;
3131
const DEP_KIND: DepKind;
3232

33-
type Cache: QueryCache<Self::Key, Self::Value>;
33+
type Cache: QueryCache<Key = Self::Key, Value = Self::Value>;
3434

3535
// Don't use this method to access query results, instead use the methods on TyCtxt
3636
fn query_state<'a>(tcx: TyCtxt<'tcx>) -> &'a QueryState<'tcx, Self>;
@@ -59,10 +59,7 @@ pub(crate) trait QueryDescription<'tcx>: QueryAccessors<'tcx> {
5959
}
6060
}
6161

62-
impl<'tcx, M: QueryAccessors<'tcx, Key = DefId>> QueryDescription<'tcx> for M
63-
where
64-
<M as QueryAccessors<'tcx>>::Cache: QueryCache<DefId, <M as QueryConfig<'tcx>>::Value>,
65-
{
62+
impl<'tcx, M: QueryAccessors<'tcx, Key = DefId>> QueryDescription<'tcx> for M {
6663
default fn describe(tcx: TyCtxt<'_>, def_id: DefId) -> Cow<'static, str> {
6764
if !tcx.sess.verbose() {
6865
format!("processing `{}`", tcx.def_path_str(def_id)).into()

src/librustc/ty/query/plumbing.rs

+60-58
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
55
use crate::dep_graph::{DepKind, DepNode, DepNodeIndex, SerializedDepNodeIndex};
66
use crate::ty::query::caches::QueryCache;
7-
use crate::ty::query::config::{QueryAccessors, QueryConfig, QueryDescription};
7+
use crate::ty::query::config::{QueryAccessors, QueryDescription};
88
use crate::ty::query::job::{QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryShardJobId};
99
use crate::ty::query::Query;
1010
use crate::ty::tls;
@@ -49,22 +49,20 @@ impl<'tcx, K, C: Default> Default for QueryStateShard<'tcx, K, C> {
4949
}
5050
}
5151

52-
pub(crate) type QueryState<'tcx, Q> = QueryStateImpl<
53-
'tcx,
54-
<Q as QueryConfig<'tcx>>::Key,
55-
<Q as QueryConfig<'tcx>>::Value,
56-
<Q as QueryAccessors<'tcx>>::Cache,
57-
>;
52+
pub(crate) type QueryState<'tcx, Q> = QueryStateImpl<'tcx, <Q as QueryAccessors<'tcx>>::Cache>;
5853

59-
pub(crate) struct QueryStateImpl<'tcx, K, V, C: QueryCache<K, V>> {
54+
pub(crate) struct QueryStateImpl<'tcx, C: QueryCache> {
6055
pub(super) cache: C,
61-
pub(super) shards: Sharded<QueryStateShard<'tcx, K, C::Sharded>>,
56+
pub(super) shards: Sharded<QueryStateShard<'tcx, C::Key, C::Sharded>>,
6257
#[cfg(debug_assertions)]
6358
pub(super) cache_hits: AtomicUsize,
6459
}
6560

66-
impl<'tcx, K, V, C: QueryCache<K, V>> QueryStateImpl<'tcx, K, V, C> {
67-
pub(super) fn get_lookup<K2: Hash>(&'tcx self, key: &K2) -> QueryLookup<'tcx, K, C::Sharded> {
61+
impl<'tcx, C: QueryCache> QueryStateImpl<'tcx, C> {
62+
pub(super) fn get_lookup<K2: Hash>(
63+
&'tcx self,
64+
key: &K2,
65+
) -> QueryLookup<'tcx, C::Key, C::Sharded> {
6866
// We compute the key's hash once and then use it for both the
6967
// shard lookup and the hashmap lookup. This relies on the fact
7068
// that both of them use `FxHasher`.
@@ -88,10 +86,12 @@ pub(super) enum QueryResult<'tcx> {
8886
Poisoned,
8987
}
9088

91-
impl<'tcx, K, V, C: QueryCache<K, V>> QueryStateImpl<'tcx, K, V, C> {
89+
impl<'tcx, C: QueryCache> QueryStateImpl<'tcx, C> {
9290
pub fn iter_results<R>(
9391
&self,
94-
f: impl for<'a> FnOnce(Box<dyn Iterator<Item = (&'a K, &'a V, DepNodeIndex)> + 'a>) -> R,
92+
f: impl for<'a> FnOnce(
93+
Box<dyn Iterator<Item = (&'a C::Key, &'a C::Value, DepNodeIndex)> + 'a>,
94+
) -> R,
9595
) -> R {
9696
self.cache.iter(&self.shards, |shard| &mut shard.cache, f)
9797
}
@@ -103,11 +103,11 @@ impl<'tcx, K, V, C: QueryCache<K, V>> QueryStateImpl<'tcx, K, V, C> {
103103
pub(super) fn try_collect_active_jobs(
104104
&self,
105105
kind: DepKind,
106-
make_query: fn(K) -> Query<'tcx>,
106+
make_query: fn(C::Key) -> Query<'tcx>,
107107
jobs: &mut FxHashMap<QueryJobId, QueryJobInfo<'tcx>>,
108108
) -> Option<()>
109109
where
110-
K: Clone,
110+
C::Key: Clone,
111111
{
112112
// We use try_lock_shards here since we are called from the
113113
// deadlock handler, and this shouldn't be locked.
@@ -130,8 +130,8 @@ impl<'tcx, K, V, C: QueryCache<K, V>> QueryStateImpl<'tcx, K, V, C> {
130130
}
131131
}
132132

133-
impl<'tcx, K, V, C: QueryCache<K, V>> Default for QueryStateImpl<'tcx, K, V, C> {
134-
fn default() -> QueryStateImpl<'tcx, K, V, C> {
133+
impl<'tcx, C: QueryCache> Default for QueryStateImpl<'tcx, C> {
134+
fn default() -> QueryStateImpl<'tcx, C> {
135135
QueryStateImpl {
136136
cache: C::default(),
137137
shards: Default::default(),
@@ -150,27 +150,22 @@ pub(crate) struct QueryLookup<'tcx, K, C> {
150150

151151
/// A type representing the responsibility to execute the job in the `job` field.
152152
/// This will poison the relevant query if dropped.
153-
pub(super) type JobOwner<'tcx, Q> = JobOwnerImpl<
154-
'tcx,
155-
<Q as QueryConfig<'tcx>>::Key,
156-
<Q as QueryConfig<'tcx>>::Value,
157-
<Q as QueryAccessors<'tcx>>::Cache,
158-
>;
159-
160-
pub(super) struct JobOwnerImpl<'tcx, K, V, C: QueryCache<K, V>>
153+
pub(super) struct JobOwner<'tcx, C>
161154
where
162-
K: Eq + Hash + Clone + Debug,
163-
V: Clone,
155+
C: QueryCache,
156+
C::Key: Eq + Hash + Clone + Debug,
157+
C::Value: Clone,
164158
{
165-
state: &'tcx QueryStateImpl<'tcx, K, V, C>,
166-
key: K,
159+
state: &'tcx QueryStateImpl<'tcx, C>,
160+
key: C::Key,
167161
id: QueryJobId,
168162
}
169163

170-
impl<'tcx, K, V, C: QueryCache<K, V>> JobOwnerImpl<'tcx, K, V, C>
164+
impl<'tcx, C: QueryCache> JobOwner<'tcx, C>
171165
where
172-
K: Eq + Hash + Clone + Debug,
173-
V: Clone,
166+
C: QueryCache,
167+
C::Key: Eq + Hash + Clone + Debug,
168+
C::Value: Clone,
174169
{
175170
/// Either gets a `JobOwner` corresponding the query, allowing us to
176171
/// start executing the query, or returns with the result of the query.
@@ -184,13 +179,11 @@ where
184179
pub(super) fn try_start<Q>(
185180
tcx: TyCtxt<'tcx>,
186181
span: Span,
187-
key: &K,
188-
mut lookup: QueryLookup<'tcx, K, C::Sharded>,
189-
) -> TryGetJob<'tcx, Q>
182+
key: &C::Key,
183+
mut lookup: QueryLookup<'tcx, C::Key, C::Sharded>,
184+
) -> TryGetJob<'tcx, C>
190185
where
191-
K: Eq + Hash + Clone + Debug,
192-
V: Clone,
193-
Q: QueryDescription<'tcx, Key = K, Value = V, Cache = C> + 'tcx,
186+
Q: QueryDescription<'tcx, Key = C::Key, Value = C::Value, Cache = C>,
194187
{
195188
let lock = &mut *lookup.lock;
196189

@@ -230,7 +223,7 @@ where
230223
entry.insert(QueryResult::Started(job));
231224

232225
let owner =
233-
JobOwnerImpl { state: Q::query_state(tcx), id: global_id, key: (*key).clone() };
226+
JobOwner { state: Q::query_state(tcx), id: global_id, key: (*key).clone() };
234227
return TryGetJob::NotYetStarted(owner);
235228
}
236229
};
@@ -271,7 +264,12 @@ where
271264
/// Completes the query by updating the query cache with the `result`,
272265
/// signals the waiter and forgets the JobOwner, so it won't poison the query
273266
#[inline(always)]
274-
pub(super) fn complete(self, tcx: TyCtxt<'tcx>, result: &V, dep_node_index: DepNodeIndex) {
267+
pub(super) fn complete(
268+
self,
269+
tcx: TyCtxt<'tcx>,
270+
result: &C::Value,
271+
dep_node_index: DepNodeIndex,
272+
) {
275273
// We can move out of `self` here because we `mem::forget` it below
276274
let key = unsafe { ptr::read(&self.key) };
277275
let state = self.state;
@@ -304,10 +302,10 @@ where
304302
(result, diagnostics.into_inner())
305303
}
306304

307-
impl<'tcx, K, V, C: QueryCache<K, V>> Drop for JobOwnerImpl<'tcx, K, V, C>
305+
impl<'tcx, C: QueryCache> Drop for JobOwner<'tcx, C>
308306
where
309-
K: Eq + Hash + Clone + Debug,
310-
V: Clone,
307+
C::Key: Eq + Hash + Clone + Debug,
308+
C::Value: Clone,
311309
{
312310
#[inline(never)]
313311
#[cold]
@@ -338,18 +336,22 @@ pub struct CycleError<'tcx> {
338336
}
339337

340338
/// The result of `try_start`.
341-
pub(super) enum TryGetJob<'tcx, D: QueryDescription<'tcx>> {
339+
pub(super) enum TryGetJob<'tcx, C: QueryCache>
340+
where
341+
C::Key: Eq + Hash + Clone + Debug,
342+
C::Value: Clone,
343+
{
342344
/// The query is not yet started. Contains a guard to the cache eventually used to start it.
343-
NotYetStarted(JobOwner<'tcx, D>),
345+
NotYetStarted(JobOwner<'tcx, C>),
344346

345347
/// The query was already completed.
346348
/// Returns the result of the query and its dep-node index
347349
/// if it succeeded or a cycle error if it failed.
348350
#[cfg(parallel_compiler)]
349-
JobCompleted((D::Value, DepNodeIndex)),
351+
JobCompleted((C::Value, DepNodeIndex)),
350352

351353
/// Trying to execute the query resulted in a cycle.
352-
Cycle(D::Value),
354+
Cycle(C::Value),
353355
}
354356

355357
impl<'tcx> TyCtxt<'tcx> {
@@ -478,22 +480,22 @@ impl<'tcx> TyCtxt<'tcx> {
478480
/// which will be used if the query is not in the cache and we need
479481
/// to compute it.
480482
#[inline(always)]
481-
fn try_get_cached<K, V, C, R, OnHit, OnMiss>(
483+
fn try_get_cached<C, R, OnHit, OnMiss>(
482484
self,
483-
state: &'tcx QueryStateImpl<'tcx, K, V, C>,
484-
key: K,
485+
state: &'tcx QueryStateImpl<'tcx, C>,
486+
key: C::Key,
485487
// `on_hit` can be called while holding a lock to the query cache
486488
on_hit: OnHit,
487489
on_miss: OnMiss,
488490
) -> R
489491
where
490-
C: QueryCache<K, V>,
491-
OnHit: FnOnce(&V, DepNodeIndex) -> R,
492-
OnMiss: FnOnce(K, QueryLookup<'tcx, K, C::Sharded>) -> R,
492+
C: QueryCache,
493+
OnHit: FnOnce(&C::Value, DepNodeIndex) -> R,
494+
OnMiss: FnOnce(C::Key, QueryLookup<'tcx, C::Key, C::Sharded>) -> R,
493495
{
494496
state.cache.lookup(
495497
state,
496-
QueryStateShard::<K, C::Sharded>::get_cache,
498+
QueryStateShard::<C::Key, C::Sharded>::get_cache,
497499
key,
498500
|value, index| {
499501
if unlikely!(self.prof.enabled()) {
@@ -533,9 +535,9 @@ impl<'tcx> TyCtxt<'tcx> {
533535
self,
534536
span: Span,
535537
key: Q::Key,
536-
lookup: QueryLookup<'tcx, Q::Key, <Q::Cache as QueryCache<Q::Key, Q::Value>>::Sharded>,
538+
lookup: QueryLookup<'tcx, Q::Key, <Q::Cache as QueryCache>::Sharded>,
537539
) -> Q::Value {
538-
let job = match JobOwnerImpl::try_start::<Q>(self, span, &key, lookup) {
540+
let job = match JobOwner::try_start::<Q>(self, span, &key, lookup) {
539541
TryGetJob::NotYetStarted(job) => job,
540542
TryGetJob::Cycle(result) => return result,
541543
#[cfg(parallel_compiler)]
@@ -696,7 +698,7 @@ impl<'tcx> TyCtxt<'tcx> {
696698
fn force_query_with_job<Q: QueryDescription<'tcx> + 'tcx>(
697699
self,
698700
key: Q::Key,
699-
job: JobOwner<'tcx, Q>,
701+
job: JobOwner<'tcx, Q::Cache>,
700702
dep_node: DepNode,
701703
) -> (Q::Value, DepNodeIndex) {
702704
// If the following assertion triggers, it can have two reasons:
@@ -795,7 +797,7 @@ impl<'tcx> TyCtxt<'tcx> {
795797
// Cache hit, do nothing
796798
},
797799
|key, lookup| {
798-
let job = match JobOwnerImpl::try_start::<Q>(self, span, &key, lookup) {
800+
let job = match JobOwner::try_start::<Q>(self, span, &key, lookup) {
799801
TryGetJob::NotYetStarted(job) => job,
800802
TryGetJob::Cycle(_) => return,
801803
#[cfg(parallel_compiler)]

src/librustc/ty/query/profiling_support.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -157,14 +157,14 @@ where
157157
/// Allocate the self-profiling query strings for a single query cache. This
158158
/// method is called from `alloc_self_profile_query_strings` which knows all
159159
/// the queries via macro magic.
160-
pub(super) fn alloc_self_profile_query_strings_for_query_cache<'tcx, K, V, C>(
160+
pub(super) fn alloc_self_profile_query_strings_for_query_cache<'tcx, C>(
161161
tcx: TyCtxt<'tcx>,
162162
query_name: &'static str,
163-
query_state: &QueryStateImpl<'tcx, K, V, C>,
163+
query_state: &QueryStateImpl<'tcx, C>,
164164
string_cache: &mut QueryKeyStringCache,
165165
) where
166-
K: Debug + Clone,
167-
C: QueryCache<K, V>,
166+
C: QueryCache,
167+
C::Key: Debug + Clone,
168168
{
169169
tcx.prof.with_profiler(|profiler| {
170170
let event_id_builder = profiler.event_id_builder();

0 commit comments

Comments
 (0)