Skip to content

Commit c59d7f4

Browse files
committed
Clean up query macros for cache_on_disk_if
1 parent 930ecbc commit c59d7f4

2 files changed

Lines changed: 81 additions & 62 deletions

File tree

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).
@@ -431,12 +443,17 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {
431443
}
432444
pub mod descs {
433445
use super::*;
434-
#query_description_stream
446+
#description_fns_stream
435447
}
436-
pub mod cached {
448+
449+
// FIXME(Zalathar): Instead of declaring these functions directly, can
450+
// we put them in a macro and then expand that macro downstream in
451+
// `rustc_query_impl`, where the functions are actually used?
452+
pub mod _cache_on_disk_if_fns {
437453
use super::*;
438-
#query_cached_stream
454+
#cache_on_disk_if_fns_stream
439455
}
456+
440457
#errors
441458
})
442459
}

compiler/rustc_query_impl/src/plumbing.rs

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

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

@@ -544,28 +560,6 @@ where
544560
}
545561
}
546562

547-
macro_rules! item_if_cached {
548-
([] $tokens:tt) => {};
549-
([(cache) $($rest:tt)*] { $($tokens:tt)* }) => {
550-
$($tokens)*
551-
};
552-
([$other:tt $($modifiers:tt)*] $tokens:tt) => {
553-
item_if_cached! { [$($modifiers)*] $tokens }
554-
};
555-
}
556-
557-
macro_rules! expand_if_cached {
558-
([], $tokens:expr) => {{
559-
None
560-
}};
561-
([(cache) $($rest:tt)*], $tokens:expr) => {{
562-
Some($tokens)
563-
}};
564-
([$other:tt $($modifiers:tt)*], $tokens:expr) => {
565-
expand_if_cached!([$($modifiers)*], $tokens)
566-
};
567-
}
568-
569563
/// Don't show the backtrace for query system by default
570564
/// use `RUST_BACKTRACE=full` to show all the backtraces
571565
#[inline(never)]
@@ -646,8 +640,8 @@ macro_rules! define_queries {
646640
cycle_error_handling: cycle_error_handling!([$($modifiers)*]),
647641
query_state: std::mem::offset_of!(QueryStates<'tcx>, $name),
648642
query_cache: std::mem::offset_of!(QueryCaches<'tcx>, $name),
649-
will_cache_on_disk_for_key_fn: should_ever_cache_on_disk!([$($modifiers)*] {
650-
Some(queries::cached::$name)
643+
will_cache_on_disk_for_key_fn: if_cache_on_disk!([$($modifiers)*] {
644+
Some(::rustc_middle::queries::_cache_on_disk_if_fns::$name)
651645
} {
652646
None
653647
}),
@@ -668,10 +662,10 @@ macro_rules! define_queries {
668662
)
669663
)
670664
},
671-
try_load_from_disk_fn: should_ever_cache_on_disk!([$($modifiers)*] {
665+
try_load_from_disk_fn: if_cache_on_disk!([$($modifiers)*] {
672666
Some(|tcx, key, prev_index, index| {
673667
// Check the `cache_on_disk_if` condition for this key.
674-
if !queries::cached::$name(tcx, key) {
668+
if !::rustc_middle::queries::_cache_on_disk_if_fns::$name(tcx, key) {
675669
return None;
676670
}
677671

@@ -684,9 +678,9 @@ macro_rules! define_queries {
684678
} {
685679
None
686680
}),
687-
is_loadable_from_disk_fn: should_ever_cache_on_disk!([$($modifiers)*] {
681+
is_loadable_from_disk_fn: if_cache_on_disk!([$($modifiers)*] {
688682
Some(|tcx, key, index| -> bool {
689-
::rustc_middle::queries::cached::$name(tcx, key) &&
683+
::rustc_middle::queries::_cache_on_disk_if_fns::$name(tcx, key) &&
690684
$crate::plumbing::loadable_from_disk(tcx, index)
691685
})
692686
} {
@@ -781,7 +775,7 @@ macro_rules! define_queries {
781775
)
782776
}
783777

784-
item_if_cached! { [$($modifiers)*] {
778+
item_if_cache_on_disk! { [$($modifiers)*]
785779
pub(crate) fn encode_query_results<'tcx>(
786780
tcx: TyCtxt<'tcx>,
787781
encoder: &mut CacheEncoder<'_, 'tcx>,
@@ -794,7 +788,7 @@ macro_rules! define_queries {
794788
query_result_index,
795789
)
796790
}
797-
}}
791+
}
798792

799793
pub(crate) fn query_key_hash_verify<'tcx>(tcx: TyCtxt<'tcx>) {
800794
$crate::plumbing::query_key_hash_verify(
@@ -848,7 +842,15 @@ macro_rules! define_queries {
848842
&mut CacheEncoder<'_, 'tcx>,
849843
&mut EncodedDepNodeIndex)
850844
>
851-
] = &[$(expand_if_cached!([$($modifiers)*], query_impl::$name::encode_query_results)),*];
845+
] = &[
846+
$(
847+
if_cache_on_disk!([$($modifiers)*] {
848+
Some(query_impl::$name::encode_query_results)
849+
} {
850+
None
851+
})
852+
),*
853+
];
852854

853855
const QUERY_KEY_HASH_VERIFY: &[
854856
for<'tcx> fn(TyCtxt<'tcx>)

0 commit comments

Comments
 (0)