Skip to content

Commit ce4f469

Browse files
committed
Auto merge of #151736 - Zalathar:can-load-from-disk, r=<try>
Make some load-from-disk function pointers optional in query vtables
2 parents 78df2f9 + 414535b commit ce4f469

6 files changed

Lines changed: 58 additions & 70 deletions

File tree

compiler/rustc_macros/src/query.rs

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -280,31 +280,21 @@ fn add_query_desc_cached_impl(
280280
let crate::query::Providers { #name: _, .. };
281281
};
282282

283-
// Find out if we should cache the query on disk
284-
let cache = if let Some((args, expr)) = modifiers.cache.as_ref() {
283+
// Generate a function to check whether we should cache the query to disk, for some key.
284+
if let Some((args, expr)) = modifiers.cache.as_ref() {
285285
let tcx = args.as_ref().map(|t| quote! { #t }).unwrap_or_else(|| quote! { _ });
286286
// expr is a `Block`, meaning that `{ #expr }` gets expanded
287287
// to `{ { stmts... } }`, which triggers the `unused_braces` lint.
288288
// we're taking `key` by reference, but some rustc types usually prefer being passed by value
289-
quote! {
289+
cached.extend(quote! {
290290
#[allow(unused_variables, unused_braces, rustc::pass_by_value)]
291291
#[inline]
292292
pub fn #name<'tcx>(#tcx: TyCtxt<'tcx>, #key: &crate::query::queries::#name::Key<'tcx>) -> bool {
293293
#ra_hint
294294
#expr
295295
}
296-
}
297-
} else {
298-
quote! {
299-
// we're taking `key` by reference, but some rustc types usually prefer being passed by value
300-
#[allow(rustc::pass_by_value)]
301-
#[inline]
302-
pub fn #name<'tcx>(_: TyCtxt<'tcx>, _: &crate::query::queries::#name::Key<'tcx>) -> bool {
303-
#ra_hint
304-
false
305-
}
306-
}
307-
};
296+
});
297+
}
308298

309299
let (tcx, desc) = &modifiers.desc;
310300
let tcx = tcx.as_ref().map_or_else(|| quote! { _ }, |t| quote! { #t });
@@ -322,10 +312,6 @@ fn add_query_desc_cached_impl(
322312
descs.extend(quote! {
323313
#desc
324314
});
325-
326-
cached.extend(quote! {
327-
#cache
328-
});
329315
}
330316

331317
pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {

compiler/rustc_middle/src/query/plumbing.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,18 @@ use crate::query::{
1818
};
1919
use crate::ty::TyCtxt;
2020

21+
pub type WillCacheOnDiskForKeyFn<'tcx, Key> = fn(tcx: TyCtxt<'tcx>, key: &Key) -> bool;
22+
23+
pub type TryLoadFromDiskFn<'tcx, Key, Value> = fn(
24+
tcx: TyCtxt<'tcx>,
25+
key: &Key,
26+
prev_index: SerializedDepNodeIndex,
27+
index: DepNodeIndex,
28+
) -> Option<Value>;
29+
30+
pub type IsLoadableFromDiskFn<'tcx, Key> =
31+
fn(tcx: TyCtxt<'tcx>, key: &Key, index: SerializedDepNodeIndex) -> bool;
32+
2133
pub struct DynamicQuery<'tcx, C: QueryCache> {
2234
pub name: &'static str,
2335
pub eval_always: bool,
@@ -28,18 +40,11 @@ pub struct DynamicQuery<'tcx, C: QueryCache> {
2840
pub query_state: usize,
2941
// Offset of this query's cache field in the QueryCaches struct
3042
pub query_cache: usize,
31-
pub cache_on_disk: fn(tcx: TyCtxt<'tcx>, key: &C::Key) -> bool,
43+
pub will_cache_on_disk_for_key_fn: Option<WillCacheOnDiskForKeyFn<'tcx, C::Key>>,
3244
pub execute_query: fn(tcx: TyCtxt<'tcx>, k: C::Key) -> C::Value,
3345
pub compute: fn(tcx: TyCtxt<'tcx>, key: C::Key) -> C::Value,
34-
pub can_load_from_disk: bool,
35-
pub try_load_from_disk: fn(
36-
tcx: TyCtxt<'tcx>,
37-
key: &C::Key,
38-
prev_index: SerializedDepNodeIndex,
39-
index: DepNodeIndex,
40-
) -> Option<C::Value>,
41-
pub loadable_from_disk:
42-
fn(tcx: TyCtxt<'tcx>, key: &C::Key, index: SerializedDepNodeIndex) -> bool,
46+
pub try_load_from_disk_fn: Option<TryLoadFromDiskFn<'tcx, C::Key, C::Value>>,
47+
pub is_loadable_from_disk_fn: Option<IsLoadableFromDiskFn<'tcx, C::Key>>,
4348
pub hash_result: HashResult<C::Value>,
4449
pub value_from_cycle_error:
4550
fn(tcx: TyCtxt<'tcx>, cycle_error: &CycleError, guar: ErrorGuaranteed) -> C::Value,

compiler/rustc_query_impl/src/lib.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ where
7474
}
7575

7676
#[inline(always)]
77-
fn cache_on_disk(self, tcx: TyCtxt<'tcx>, key: &Self::Key) -> bool {
78-
(self.dynamic.cache_on_disk)(tcx, key)
77+
fn will_cache_on_disk_for_key(self, tcx: TyCtxt<'tcx>, key: &Self::Key) -> bool {
78+
self.dynamic.will_cache_on_disk_for_key_fn.map_or(false, |f| f(tcx, key))
7979
}
8080

8181
#[inline(always)]
@@ -127,21 +127,17 @@ where
127127
prev_index: SerializedDepNodeIndex,
128128
index: DepNodeIndex,
129129
) -> Option<Self::Value> {
130-
if self.dynamic.can_load_from_disk {
131-
(self.dynamic.try_load_from_disk)(qcx.tcx, key, prev_index, index)
132-
} else {
133-
None
134-
}
130+
self.dynamic.try_load_from_disk_fn?(qcx.tcx, key, prev_index, index)
135131
}
136132

137133
#[inline]
138-
fn loadable_from_disk(
134+
fn is_loadable_from_disk(
139135
self,
140136
qcx: QueryCtxt<'tcx>,
141137
key: &Self::Key,
142138
index: SerializedDepNodeIndex,
143139
) -> bool {
144-
(self.dynamic.loadable_from_disk)(qcx.tcx, key, index)
140+
self.dynamic.is_loadable_from_disk_fn.map_or(false, |f| f(qcx.tcx, key, index))
145141
}
146142

147143
fn value_from_cycle_error(

compiler/rustc_query_impl/src/plumbing.rs

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ pub(crate) fn encode_query_results<'a, 'tcx, Q>(
400400
assert!(query.query_state(qcx).all_inactive());
401401
let cache = query.query_cache(qcx);
402402
cache.iter(&mut |key, value, dep_node| {
403-
if query.cache_on_disk(qcx.tcx, key) {
403+
if query.will_cache_on_disk_for_key(qcx.tcx, key) {
404404
let dep_node = SerializedDepNodeIndex::new(dep_node.index());
405405

406406
// Record position of the cache entry.
@@ -449,7 +449,7 @@ where
449449
let key = Q::Key::recover(tcx, &dep_node).unwrap_or_else(|| {
450450
panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash)
451451
});
452-
if query.cache_on_disk(tcx, &key) {
452+
if query.will_cache_on_disk_for_key(tcx, &key) {
453453
let _ = query.execute_query(tcx, key);
454454
}
455455
}
@@ -651,7 +651,11 @@ macro_rules! define_queries {
651651
cycle_error_handling: cycle_error_handling!([$($modifiers)*]),
652652
query_state: std::mem::offset_of!(QueryStates<'tcx>, $name),
653653
query_cache: std::mem::offset_of!(QueryCaches<'tcx>, $name),
654-
cache_on_disk: |tcx, key| ::rustc_middle::query::cached::$name(tcx, key),
654+
will_cache_on_disk_for_key_fn: should_ever_cache_on_disk!([$($modifiers)*] {
655+
Some(::rustc_middle::query::cached::$name)
656+
} {
657+
None
658+
}),
655659
execute_query: |tcx, key| erase(tcx.$name(key)),
656660
compute: |tcx, key| {
657661
#[cfg(debug_assertions)]
@@ -669,37 +673,34 @@ macro_rules! define_queries {
669673
)
670674
)
671675
},
672-
can_load_from_disk: should_ever_cache_on_disk!([$($modifiers)*] true false),
673-
try_load_from_disk: should_ever_cache_on_disk!([$($modifiers)*] {
674-
|tcx, key, prev_index, index| {
675-
if ::rustc_middle::query::cached::$name(tcx, key) {
676-
let value = $crate::plumbing::try_load_from_disk::<
677-
queries::$name::ProvidedValue<'tcx>
678-
>(
679-
tcx,
680-
prev_index,
681-
index,
682-
);
683-
value.map(|value| queries::$name::provided_to_erased(tcx, value))
684-
} else {
685-
None
676+
try_load_from_disk_fn: should_ever_cache_on_disk!([$($modifiers)*] {
677+
Some(|tcx, key, prev_index, index| {
678+
// Check the `cache_on_disk_if` condition for this key.
679+
if !::rustc_middle::query::cached::$name(tcx, key) {
680+
return None;
686681
}
687-
}
682+
683+
let value: queries::$name::ProvidedValue<'tcx> =
684+
$crate::plumbing::try_load_from_disk(tcx, prev_index, index)?;
685+
686+
// Arena-alloc the value if appropriate, and erase it.
687+
Some(queries::$name::provided_to_erased(tcx, value))
688+
})
688689
} {
689-
|_tcx, _key, _prev_index, _index| None
690+
None
691+
}),
692+
is_loadable_from_disk_fn: should_ever_cache_on_disk!([$($modifiers)*] {
693+
Some(|tcx, key, index| -> bool {
694+
::rustc_middle::query::cached::$name(tcx, key) &&
695+
$crate::plumbing::loadable_from_disk(tcx, index)
696+
})
697+
} {
698+
None
690699
}),
691700
value_from_cycle_error: |tcx, cycle, guar| {
692701
let result: queries::$name::Value<'tcx> = Value::from_cycle_error(tcx, cycle, guar);
693702
erase(result)
694703
},
695-
loadable_from_disk: |_tcx, _key, _index| {
696-
should_ever_cache_on_disk!([$($modifiers)*] {
697-
::rustc_middle::query::cached::$name(_tcx, _key) &&
698-
$crate::plumbing::loadable_from_disk(_tcx, _index)
699-
} {
700-
false
701-
})
702-
},
703704
hash_result: hash_result!([$($modifiers)*][queries::$name::Value<'tcx>]),
704705
format_value: |value| format!("{:?}", restore::<queries::$name::Value<'tcx>>(*value)),
705706
}

compiler/rustc_query_system/src/query/config.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ pub trait QueryConfig<Qcx: QueryContext>: Copy {
3636
where
3737
Qcx: 'a;
3838

39-
fn cache_on_disk(self, tcx: Qcx::DepContext, key: &Self::Key) -> bool;
39+
fn will_cache_on_disk_for_key(self, tcx: Qcx::DepContext, key: &Self::Key) -> bool;
4040

4141
// Don't use this method to compute query results, instead use the methods on TyCtxt
4242
fn execute_query(self, tcx: Qcx::DepContext, k: Self::Key) -> Self::Value;
@@ -51,7 +51,7 @@ pub trait QueryConfig<Qcx: QueryContext>: Copy {
5151
index: DepNodeIndex,
5252
) -> Option<Self::Value>;
5353

54-
fn loadable_from_disk(self, qcx: Qcx, key: &Self::Key, idx: SerializedDepNodeIndex) -> bool;
54+
fn is_loadable_from_disk(self, qcx: Qcx, key: &Self::Key, idx: SerializedDepNodeIndex) -> bool;
5555

5656
/// Synthesize an error value to let compilation continue after a cycle.
5757
fn value_from_cycle_error(

compiler/rustc_query_system/src/query/plumbing.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -630,15 +630,15 @@ where
630630
// We always expect to find a cached result for things that
631631
// can be forced from `DepNode`.
632632
debug_assert!(
633-
!query.cache_on_disk(*qcx.dep_context(), key)
633+
!query.will_cache_on_disk_for_key(*qcx.dep_context(), key)
634634
|| !qcx.dep_context().fingerprint_style(dep_node.kind).reconstructible(),
635635
"missing on-disk cache entry for {dep_node:?}"
636636
);
637637

638638
// Sanity check for the logic in `ensure`: if the node is green and the result loadable,
639639
// we should actually be able to load it.
640640
debug_assert!(
641-
!query.loadable_from_disk(qcx, key, prev_dep_node_index),
641+
!query.is_loadable_from_disk(qcx, key, prev_dep_node_index),
642642
"missing on-disk cache entry for loadable {dep_node:?}"
643643
);
644644

@@ -806,7 +806,7 @@ where
806806
return (false, None);
807807
}
808808

809-
let loadable = query.loadable_from_disk(qcx, key, serialized_dep_node_index);
809+
let loadable = query.is_loadable_from_disk(qcx, key, serialized_dep_node_index);
810810
(!loadable, Some(dep_node))
811811
}
812812

0 commit comments

Comments
 (0)