Skip to content

Commit 7b25457

Browse files
committed
Auto merge of #151943 - Zalathar:cache-on-disk, r=TaKO8Ki
Clean up query macros for `cache_on_disk_if` This PR aims to make the macros for dealing with `cache_on_disk_if` a bit easier to read and work with. There should be no change to compiler behaviour.
2 parents 9e79395 + 892665b commit 7b25457

File tree

2 files changed

+81
-62
lines changed

2 files changed

+81
-62
lines changed

compiler/rustc_macros/src/query.rs

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ struct QueryModifiers {
9090
arena_cache: Option<Ident>,
9191

9292
/// Cache the query to disk if the `Block` returns true.
93-
cache: Option<(Option<Pat>, Block)>,
93+
cache_on_disk_if: Option<(Option<Pat>, Block)>,
9494

9595
/// A cycle error for this query aborting the compilation with a fatal error.
9696
cycle_fatal: Option<Ident>,
@@ -134,7 +134,7 @@ struct QueryModifiers {
134134

135135
fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
136136
let mut arena_cache = None;
137-
let mut cache = None;
137+
let mut cache_on_disk_if = None;
138138
let mut desc = None;
139139
let mut cycle_fatal = None;
140140
let mut cycle_delay_bug = None;
@@ -175,8 +175,11 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
175175
let list = attr_content.parse_terminated(Expr::parse, Token![,])?;
176176
try_insert!(desc = (tcx, list));
177177
} else if modifier == "cache_on_disk_if" {
178-
// Parse a cache modifier like:
179-
// `cache(tcx) { |tcx| key.is_local() }`
178+
// Parse a cache-on-disk modifier like:
179+
//
180+
// `cache_on_disk_if { true }`
181+
// `cache_on_disk_if { key.is_local() }`
182+
// `cache_on_disk_if(tcx) { tcx.is_typeck_child(key.to_def_id()) }`
180183
let args = if input.peek(token::Paren) {
181184
let args;
182185
parenthesized!(args in input);
@@ -186,7 +189,7 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
186189
None
187190
};
188191
let block = input.parse()?;
189-
try_insert!(cache = (args, block));
192+
try_insert!(cache_on_disk_if = (args, block));
190193
} else if modifier == "arena_cache" {
191194
try_insert!(arena_cache = modifier);
192195
} else if modifier == "cycle_fatal" {
@@ -218,7 +221,7 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
218221
};
219222
Ok(QueryModifiers {
220223
arena_cache,
221-
cache,
224+
cache_on_disk_if,
222225
desc,
223226
cycle_fatal,
224227
cycle_delay_bug,
@@ -260,12 +263,18 @@ fn doc_comment_from_desc(list: &Punctuated<Expr, token::Comma>) -> Result<Attrib
260263
Ok(parse_quote! { #[doc = #doc_string] })
261264
}
262265

263-
/// Add the impl of QueryDescription for the query to `impls` if one is requested
264-
fn add_query_desc_cached_impl(
265-
query: &Query,
266-
descs: &mut proc_macro2::TokenStream,
267-
cached: &mut proc_macro2::TokenStream,
268-
) {
266+
/// Contains token streams that are used to accumulate per-query helper
267+
/// functions, to be used by the final output of `rustc_queries!`.
268+
///
269+
/// Helper items typically have the same name as the query they relate to,
270+
/// and expect to be interpolated into a dedicated module.
271+
#[derive(Default)]
272+
struct HelperTokenStreams {
273+
description_fns_stream: proc_macro2::TokenStream,
274+
cache_on_disk_if_fns_stream: proc_macro2::TokenStream,
275+
}
276+
277+
fn make_helpers_for_query(query: &Query, streams: &mut HelperTokenStreams) {
269278
let Query { name, key, modifiers, .. } = &query;
270279

271280
// This dead code exists to instruct rust-analyzer about the link between the `rustc_queries`
@@ -281,12 +290,12 @@ fn add_query_desc_cached_impl(
281290
};
282291

283292
// 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() {
293+
if let Some((args, expr)) = modifiers.cache_on_disk_if.as_ref() {
285294
let tcx = args.as_ref().map(|t| quote! { #t }).unwrap_or_else(|| quote! { _ });
286295
// expr is a `Block`, meaning that `{ #expr }` gets expanded
287296
// to `{ { stmts... } }`, which triggers the `unused_braces` lint.
288297
// we're taking `key` by reference, but some rustc types usually prefer being passed by value
289-
cached.extend(quote! {
298+
streams.cache_on_disk_if_fns_stream.extend(quote! {
290299
#[allow(unused_variables, unused_braces, rustc::pass_by_value)]
291300
#[inline]
292301
pub fn #name<'tcx>(#tcx: TyCtxt<'tcx>, #key: &crate::queries::#name::Key<'tcx>) -> bool {
@@ -307,7 +316,7 @@ fn add_query_desc_cached_impl(
307316
}
308317
};
309318

310-
descs.extend(quote! {
319+
streams.description_fns_stream.extend(quote! {
311320
#desc
312321
});
313322
}
@@ -316,8 +325,7 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {
316325
let queries = parse_macro_input!(input as List<Query>);
317326

318327
let mut query_stream = quote! {};
319-
let mut query_description_stream = quote! {};
320-
let mut query_cached_stream = quote! {};
328+
let mut helpers = HelperTokenStreams::default();
321329
let mut feedable_queries = quote! {};
322330
let mut errors = quote! {};
323331

@@ -363,9 +371,11 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {
363371
return_result_from_ensure_ok,
364372
);
365373

366-
// Pass on the cache modifier
367-
if modifiers.cache.is_some() {
368-
attributes.push(quote! { (cache) });
374+
// If there was a `cache_on_disk_if` modifier in the real input, pass
375+
// on a synthetic `(cache_on_disk)` modifier that can be inspected by
376+
// macro-rules macros.
377+
if modifiers.cache_on_disk_if.is_some() {
378+
attributes.push(quote! { (cache_on_disk) });
369379
}
370380

371381
// This uses the span of the query definition for the commas,
@@ -399,9 +409,11 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {
399409
});
400410
}
401411

402-
add_query_desc_cached_impl(&query, &mut query_description_stream, &mut query_cached_stream);
412+
make_helpers_for_query(&query, &mut helpers);
403413
}
404414

415+
let HelperTokenStreams { description_fns_stream, cache_on_disk_if_fns_stream } = helpers;
416+
405417
TokenStream::from(quote! {
406418
/// Higher-order macro that invokes the specified macro with a prepared
407419
/// list of all query signatures (including modifiers).
@@ -438,12 +450,17 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {
438450
/// module easier to search for.)
439451
pub mod _description_fns {
440452
use super::*;
441-
#query_description_stream
453+
#description_fns_stream
442454
}
443-
pub mod cached {
455+
456+
// FIXME(Zalathar): Instead of declaring these functions directly, can
457+
// we put them in a macro and then expand that macro downstream in
458+
// `rustc_query_impl`, where the functions are actually used?
459+
pub mod _cache_on_disk_if_fns {
444460
use super::*;
445-
#query_cached_stream
461+
#cache_on_disk_if_fns_stream
446462
}
463+
447464
#errors
448465
})
449466
}

compiler/rustc_query_impl/src/plumbing.rs

Lines changed: 40 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -302,15 +302,31 @@ macro_rules! call_provider {
302302
};
303303
}
304304

305-
macro_rules! should_ever_cache_on_disk {
306-
([]$yes:tt $no:tt) => {{
305+
/// Expands to one of two token trees, depending on whether the current query
306+
/// has the `cache_on_disk_if` modifier.
307+
macro_rules! if_cache_on_disk {
308+
([] $yes:tt $no:tt) => {
307309
$no
308-
}};
309-
([(cache) $($rest:tt)*]$yes:tt $no:tt) => {{
310+
};
311+
// The `cache_on_disk_if` modifier generates a synthetic `(cache_on_disk)`,
312+
// modifier, for use by this macro and similar macros.
313+
([(cache_on_disk) $($rest:tt)*] $yes:tt $no:tt) => {
310314
$yes
311-
}};
312-
([$other:tt $($modifiers:tt)*]$yes:tt $no:tt) => {
313-
should_ever_cache_on_disk!([$($modifiers)*]$yes $no)
315+
};
316+
([$other:tt $($modifiers:tt)*] $yes:tt $no:tt) => {
317+
if_cache_on_disk!([$($modifiers)*] $yes $no)
318+
};
319+
}
320+
321+
/// Conditionally expands to some token trees, if the current query has the
322+
/// `cache_on_disk_if` modifier.
323+
macro_rules! item_if_cache_on_disk {
324+
([] $($item:tt)*) => {};
325+
([(cache_on_disk) $($rest:tt)*] $($item:tt)*) => {
326+
$($item)*
327+
};
328+
([$other:tt $($modifiers:tt)*] $($item:tt)*) => {
329+
item_if_cache_on_disk! { [$($modifiers)*] $($item)* }
314330
};
315331
}
316332

@@ -551,28 +567,6 @@ where
551567
}
552568
}
553569

554-
macro_rules! item_if_cached {
555-
([] $tokens:tt) => {};
556-
([(cache) $($rest:tt)*] { $($tokens:tt)* }) => {
557-
$($tokens)*
558-
};
559-
([$other:tt $($modifiers:tt)*] $tokens:tt) => {
560-
item_if_cached! { [$($modifiers)*] $tokens }
561-
};
562-
}
563-
564-
macro_rules! expand_if_cached {
565-
([], $tokens:expr) => {{
566-
None
567-
}};
568-
([(cache) $($rest:tt)*], $tokens:expr) => {{
569-
Some($tokens)
570-
}};
571-
([$other:tt $($modifiers:tt)*], $tokens:expr) => {
572-
expand_if_cached!([$($modifiers)*], $tokens)
573-
};
574-
}
575-
576570
// NOTE: `$V` isn't used here, but we still need to match on it so it can be passed to other macros
577571
// invoked by `rustc_with_all_queries`.
578572
macro_rules! define_queries {
@@ -667,17 +661,17 @@ macro_rules! define_queries {
667661
cycle_error_handling: cycle_error_handling!([$($modifiers)*]),
668662
query_state: std::mem::offset_of!(QueryStates<'tcx>, $name),
669663
query_cache: std::mem::offset_of!(QueryCaches<'tcx>, $name),
670-
will_cache_on_disk_for_key_fn: should_ever_cache_on_disk!([$($modifiers)*] {
671-
Some(queries::cached::$name)
664+
will_cache_on_disk_for_key_fn: if_cache_on_disk!([$($modifiers)*] {
665+
Some(::rustc_middle::queries::_cache_on_disk_if_fns::$name)
672666
} {
673667
None
674668
}),
675669
execute_query: |tcx, key| erase::erase_val(tcx.$name(key)),
676670
compute_fn: self::compute_fn::__rust_begin_short_backtrace,
677-
try_load_from_disk_fn: should_ever_cache_on_disk!([$($modifiers)*] {
671+
try_load_from_disk_fn: if_cache_on_disk!([$($modifiers)*] {
678672
Some(|tcx, key, prev_index, index| {
679673
// Check the `cache_on_disk_if` condition for this key.
680-
if !queries::cached::$name(tcx, key) {
674+
if !::rustc_middle::queries::_cache_on_disk_if_fns::$name(tcx, key) {
681675
return None;
682676
}
683677

@@ -690,9 +684,9 @@ macro_rules! define_queries {
690684
} {
691685
None
692686
}),
693-
is_loadable_from_disk_fn: should_ever_cache_on_disk!([$($modifiers)*] {
687+
is_loadable_from_disk_fn: if_cache_on_disk!([$($modifiers)*] {
694688
Some(|tcx, key, index| -> bool {
695-
::rustc_middle::queries::cached::$name(tcx, key) &&
689+
::rustc_middle::queries::_cache_on_disk_if_fns::$name(tcx, key) &&
696690
$crate::plumbing::loadable_from_disk(tcx, index)
697691
})
698692
} {
@@ -788,7 +782,7 @@ macro_rules! define_queries {
788782
)
789783
}
790784

791-
item_if_cached! { [$($modifiers)*] {
785+
item_if_cache_on_disk! { [$($modifiers)*]
792786
pub(crate) fn encode_query_results<'tcx>(
793787
tcx: TyCtxt<'tcx>,
794788
encoder: &mut CacheEncoder<'_, 'tcx>,
@@ -805,7 +799,7 @@ macro_rules! define_queries {
805799
query_result_index,
806800
)
807801
}
808-
}}
802+
}
809803

810804
pub(crate) fn query_key_hash_verify<'tcx>(tcx: TyCtxt<'tcx>) {
811805
$crate::plumbing::query_key_hash_verify(
@@ -859,7 +853,15 @@ macro_rules! define_queries {
859853
&mut CacheEncoder<'_, 'tcx>,
860854
&mut EncodedDepNodeIndex)
861855
>
862-
] = &[$(expand_if_cached!([$($modifiers)*], query_impl::$name::encode_query_results)),*];
856+
] = &[
857+
$(
858+
if_cache_on_disk!([$($modifiers)*] {
859+
Some(query_impl::$name::encode_query_results)
860+
} {
861+
None
862+
})
863+
),*
864+
];
863865

864866
const QUERY_KEY_HASH_VERIFY: &[
865867
for<'tcx> fn(TyCtxt<'tcx>)

0 commit comments

Comments
 (0)