Skip to content

Commit 0b3046c

Browse files
committed
Streamline cache-related query functions.
There are three query vtable functions related to the `cache_on_disk_if` modifier: - `will_cache_on_disk_for_key_fn` - `try_load_from_disk_fn` - `is_loadable_from_disk_fn` These are all function ptrs within an `Option`. They each have a wrapper that returns `false`/`None` if the function ptr is missing. This commit removes the `Option` wrappers. In the `None` case we now set the function ptr to a trivial closure that returns `false`/`None`. The commit also removes some typedefs that each have a single use. All this is a bit simpler, with less indirection. Note that `QueryVTable::hash_value_fn` is still an `Option`. Unlike the above three functions, which have trivial behaviour in the `None` case, `hash_value_fn` is used in ways where the `Some`/`None` distinction is more meaningful.
1 parent d2218f5 commit 0b3046c

3 files changed

Lines changed: 25 additions & 64 deletions

File tree

compiler/rustc_middle/src/query/plumbing.rs

Lines changed: 8 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ pub struct QueryVTable<'tcx, C: QueryCache> {
114114
pub cycle_error_handling: CycleErrorHandling,
115115
pub state: QueryState<'tcx, C::Key>,
116116
pub cache: C,
117-
pub will_cache_on_disk_for_key_fn: Option<fn(tcx: TyCtxt<'tcx>, key: &C::Key) -> bool>,
117+
pub will_cache_on_disk_for_key_fn: fn(tcx: TyCtxt<'tcx>, key: &C::Key) -> bool,
118118

119119
/// Function pointer that calls `tcx.$query(key)` for this query and
120120
/// discards the returned value.
@@ -130,17 +130,15 @@ pub struct QueryVTable<'tcx, C: QueryCache> {
130130
/// This should be the only code that calls the provider function.
131131
pub invoke_provider_fn: fn(tcx: TyCtxt<'tcx>, key: C::Key) -> C::Value,
132132

133-
pub try_load_from_disk_fn: Option<
134-
fn(
135-
tcx: TyCtxt<'tcx>,
136-
key: &C::Key,
137-
prev_index: SerializedDepNodeIndex,
138-
index: DepNodeIndex,
139-
) -> Option<C::Value>,
140-
>,
133+
pub try_load_from_disk_fn: fn(
134+
tcx: TyCtxt<'tcx>,
135+
key: &C::Key,
136+
prev_index: SerializedDepNodeIndex,
137+
index: DepNodeIndex,
138+
) -> Option<C::Value>,
141139

142140
pub is_loadable_from_disk_fn:
143-
Option<fn(tcx: TyCtxt<'tcx>, key: &C::Key, index: SerializedDepNodeIndex) -> bool>,
141+
fn(tcx: TyCtxt<'tcx>, key: &C::Key, index: SerializedDepNodeIndex) -> bool,
144142

145143
/// Function pointer that hashes this query's result values.
146144
///
@@ -182,43 +180,6 @@ impl<'tcx, C: QueryCache> fmt::Debug for QueryVTable<'tcx, C> {
182180
}
183181

184182
impl<'tcx, C: QueryCache> QueryVTable<'tcx, C> {
185-
#[inline(always)]
186-
pub fn will_cache_on_disk_for_key(&self, tcx: TyCtxt<'tcx>, key: &C::Key) -> bool {
187-
self.will_cache_on_disk_for_key_fn.map_or(false, |f| f(tcx, key))
188-
}
189-
190-
#[inline(always)]
191-
pub fn try_load_from_disk(
192-
&self,
193-
tcx: TyCtxt<'tcx>,
194-
key: &C::Key,
195-
prev_index: SerializedDepNodeIndex,
196-
index: DepNodeIndex,
197-
) -> Option<C::Value> {
198-
// `?` will return None immediately for queries that never cache to disk.
199-
self.try_load_from_disk_fn?(tcx, key, prev_index, index)
200-
}
201-
202-
#[inline]
203-
pub fn is_loadable_from_disk(
204-
&self,
205-
tcx: TyCtxt<'tcx>,
206-
key: &C::Key,
207-
index: SerializedDepNodeIndex,
208-
) -> bool {
209-
self.is_loadable_from_disk_fn.map_or(false, |f| f(tcx, key, index))
210-
}
211-
212-
/// Synthesize an error value to let compilation continue after a cycle.
213-
pub fn value_from_cycle_error(
214-
&self,
215-
tcx: TyCtxt<'tcx>,
216-
cycle_error: CycleError,
217-
guar: ErrorGuaranteed,
218-
) -> C::Value {
219-
(self.value_from_cycle_error)(tcx, cycle_error, guar)
220-
}
221-
222183
pub fn construct_dep_node(&self, tcx: TyCtxt<'tcx>, key: &C::Key) -> DepNode {
223184
DepNode::construct(tcx, self.dep_kind, key)
224185
}

compiler/rustc_query_impl/src/execution.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,15 +129,15 @@ fn mk_cycle<'tcx, C: QueryCache>(
129129
match query.cycle_error_handling {
130130
CycleErrorHandling::Error => {
131131
let guar = error.emit();
132-
query.value_from_cycle_error(tcx, cycle_error, guar)
132+
(query.value_from_cycle_error)(tcx, cycle_error, guar)
133133
}
134134
CycleErrorHandling::Fatal => {
135135
let guar = error.emit();
136136
guar.raise_fatal();
137137
}
138138
CycleErrorHandling::DelayBug => {
139139
let guar = error.delay_as_bug();
140-
query.value_from_cycle_error(tcx, cycle_error, guar)
140+
(query.value_from_cycle_error)(tcx, cycle_error, guar)
141141
}
142142
CycleErrorHandling::Stash => {
143143
let guar = if let Some(root) = cycle_error.cycle.first()
@@ -147,7 +147,7 @@ fn mk_cycle<'tcx, C: QueryCache>(
147147
} else {
148148
error.emit()
149149
};
150-
query.value_from_cycle_error(tcx, cycle_error, guar)
150+
(query.value_from_cycle_error)(tcx, cycle_error, guar)
151151
}
152152
}
153153
}
@@ -522,7 +522,7 @@ fn load_from_disk_or_invoke_provider_green<'tcx, C: QueryCache>(
522522

523523
// First we try to load the result from the on-disk cache.
524524
// Some things are never cached on disk.
525-
if let Some(value) = query.try_load_from_disk(tcx, key, prev_index, dep_node_index) {
525+
if let Some(value) = (query.try_load_from_disk_fn)(tcx, key, prev_index, dep_node_index) {
526526
if std::intrinsics::unlikely(tcx.sess.opts.unstable_opts.query_dep_graph) {
527527
dep_graph_data.mark_debug_loaded_from_disk(*dep_node)
528528
}
@@ -555,15 +555,15 @@ fn load_from_disk_or_invoke_provider_green<'tcx, C: QueryCache>(
555555
// We always expect to find a cached result for things that
556556
// can be forced from `DepNode`.
557557
debug_assert!(
558-
!query.will_cache_on_disk_for_key(tcx, key)
558+
!(query.will_cache_on_disk_for_key_fn)(tcx, key)
559559
|| !tcx.key_fingerprint_style(dep_node.kind).is_maybe_recoverable(),
560560
"missing on-disk cache entry for {dep_node:?}"
561561
);
562562

563563
// Sanity check for the logic in `ensure`: if the node is green and the result loadable,
564564
// we should actually be able to load it.
565565
debug_assert!(
566-
!query.is_loadable_from_disk(tcx, key, prev_index),
566+
!(query.is_loadable_from_disk_fn)(tcx, key, prev_index),
567567
"missing on-disk cache entry for loadable {dep_node:?}"
568568
);
569569

@@ -660,7 +660,7 @@ fn check_if_ensure_can_skip_execution<'tcx, C: QueryCache>(
660660
// In ensure-done mode, we can only skip execution for this key if
661661
// there's a disk-cached value available to load later if needed,
662662
// which guarantees the query provider will never run for this key.
663-
let is_loadable = query.is_loadable_from_disk(tcx, key, serialized_dep_node_index);
663+
let is_loadable = (query.is_loadable_from_disk_fn)(tcx, key, serialized_dep_node_index);
664664
EnsureCanSkip { skip_execution: is_loadable, dep_node: Some(dep_node) }
665665
}
666666
}

compiler/rustc_query_impl/src/plumbing.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ pub(crate) fn encode_query_results<'a, 'tcx, C, V>(
168168

169169
assert!(all_inactive(&query.state));
170170
query.cache.iter(&mut |key, value, dep_node| {
171-
if query.will_cache_on_disk_for_key(tcx, key) {
171+
if (query.will_cache_on_disk_for_key_fn)(tcx, key) {
172172
let dep_node = SerializedDepNodeIndex::new(dep_node.index());
173173

174174
// Record position of the cache entry.
@@ -221,7 +221,7 @@ pub(crate) fn promote_from_disk_inner<'tcx, Q: GetQueryVTable<'tcx>>(
221221
dep_node.key_fingerprint
222222
)
223223
});
224-
if query.will_cache_on_disk_for_key(tcx, &key) {
224+
if (query.will_cache_on_disk_for_key_fn)(tcx, &key) {
225225
// Call `tcx.$query(key)` for its side-effect of loading the disk-cached
226226
// value into memory.
227227
(query.call_query_method_fn)(tcx, key);
@@ -429,9 +429,9 @@ macro_rules! define_queries {
429429

430430
#[cfg($cache_on_disk)]
431431
will_cache_on_disk_for_key_fn:
432-
Some(rustc_middle::queries::_cache_on_disk_if_fns::$name),
432+
rustc_middle::queries::_cache_on_disk_if_fns::$name,
433433
#[cfg(not($cache_on_disk))]
434-
will_cache_on_disk_for_key_fn: None,
434+
will_cache_on_disk_for_key_fn: |_, _| false,
435435

436436
call_query_method_fn: |tcx, key| {
437437
// Call the query method for its side-effect of loading a value
@@ -441,7 +441,7 @@ macro_rules! define_queries {
441441
invoke_provider_fn: self::invoke_provider_fn::__rust_begin_short_backtrace,
442442

443443
#[cfg($cache_on_disk)]
444-
try_load_from_disk_fn: Some(|tcx, key, prev_index, index| {
444+
try_load_from_disk_fn: |tcx, key, prev_index, index| {
445445
// Check the `cache_on_disk_if` condition for this key.
446446
if !rustc_middle::queries::_cache_on_disk_if_fns::$name(tcx, key) {
447447
return None;
@@ -452,17 +452,17 @@ macro_rules! define_queries {
452452

453453
// Arena-alloc the value if appropriate, and erase it.
454454
Some(queries::$name::provided_to_erased(tcx, value))
455-
}),
455+
},
456456
#[cfg(not($cache_on_disk))]
457-
try_load_from_disk_fn: None,
457+
try_load_from_disk_fn: |_tcx, _key, _prev_index, _index| None,
458458

459459
#[cfg($cache_on_disk)]
460-
is_loadable_from_disk_fn: Some(|tcx, key, index| -> bool {
460+
is_loadable_from_disk_fn: |tcx, key, index| -> bool {
461461
rustc_middle::queries::_cache_on_disk_if_fns::$name(tcx, key) &&
462462
$crate::plumbing::loadable_from_disk(tcx, index)
463-
}),
463+
},
464464
#[cfg(not($cache_on_disk))]
465-
is_loadable_from_disk_fn: None,
465+
is_loadable_from_disk_fn: |_tcx, _key, _index| false,
466466

467467
value_from_cycle_error: |tcx, cycle, guar| {
468468
let result: queries::$name::Value<'tcx> =

0 commit comments

Comments
 (0)