Skip to content

Commit b2d5760

Browse files
committed
Clean up query macros for cache_on_disk_if
1 parent a1db344 commit b2d5760

2 files changed

Lines changed: 81 additions & 61 deletions

File tree

compiler/rustc_macros/src/query.rs

Lines changed: 41 additions & 23 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+
descs_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::query::queries::#name::Key<'tcx>) -> bool {
@@ -309,7 +318,7 @@ fn add_query_desc_cached_impl(
309318
}
310319
};
311320

312-
descs.extend(quote! {
321+
streams.descs_stream.extend(quote! {
313322
#desc
314323
});
315324
}
@@ -318,8 +327,7 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {
318327
let queries = parse_macro_input!(input as List<Query>);
319328

320329
let mut query_stream = quote! {};
321-
let mut query_description_stream = quote! {};
322-
let mut query_cached_stream = quote! {};
330+
let mut helpers = HelperTokenStreams::default();
323331
let mut feedable_queries = quote! {};
324332
let mut errors = quote! {};
325333

@@ -364,9 +372,11 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {
364372
return_result_from_ensure_ok,
365373
);
366374

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

372382
// This uses the span of the query definition for the commas,
@@ -400,9 +410,12 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {
400410
});
401411
}
402412

403-
add_query_desc_cached_impl(&query, &mut query_description_stream, &mut query_cached_stream);
413+
make_helpers_for_query(&query, &mut helpers);
404414
}
405415

416+
let HelperTokenStreams { descs_stream: query_description_stream, cache_on_disk_if_fns_stream } =
417+
helpers;
418+
406419
TokenStream::from(quote! {
407420
/// Higher-order macro that invokes the specified macro with a prepared
408421
/// list of all query signatures (including modifiers).
@@ -434,10 +447,15 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {
434447
use super::*;
435448
#query_description_stream
436449
}
437-
pub mod cached {
450+
451+
// FIXME(Zalathar): Instead of declaring these functions directly, can
452+
// we put them in a macro and then expand that macro downstream in
453+
// `rustc_query_impl`, where the functions are actually used?
454+
pub mod _cache_on_disk_if_fns {
438455
use super::*;
439-
#query_cached_stream
456+
#cache_on_disk_if_fns_stream
440457
}
458+
441459
#errors
442460
})
443461
}

compiler/rustc_query_impl/src/plumbing.rs

Lines changed: 40 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -305,15 +305,31 @@ macro_rules! call_provider {
305305
};
306306
}
307307

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

@@ -546,28 +562,6 @@ where
546562
}
547563
}
548564

549-
macro_rules! item_if_cached {
550-
([] $tokens:tt) => {};
551-
([(cache) $($rest:tt)*] { $($tokens:tt)* }) => {
552-
$($tokens)*
553-
};
554-
([$other:tt $($modifiers:tt)*] $tokens:tt) => {
555-
item_if_cached! { [$($modifiers)*] $tokens }
556-
};
557-
}
558-
559-
macro_rules! expand_if_cached {
560-
([], $tokens:expr) => {{
561-
None
562-
}};
563-
([(cache) $($rest:tt)*], $tokens:expr) => {{
564-
Some($tokens)
565-
}};
566-
([$other:tt $($modifiers:tt)*], $tokens:expr) => {
567-
expand_if_cached!([$($modifiers)*], $tokens)
568-
};
569-
}
570-
571565
/// Don't show the backtrace for query system by default
572566
/// use `RUST_BACKTRACE=full` to show all the backtraces
573567
#[inline(never)]
@@ -648,8 +642,8 @@ macro_rules! define_queries {
648642
cycle_error_handling: cycle_error_handling!([$($modifiers)*]),
649643
query_state: std::mem::offset_of!(QueryStates<'tcx>, $name),
650644
query_cache: std::mem::offset_of!(QueryCaches<'tcx>, $name),
651-
will_cache_on_disk_for_key_fn: should_ever_cache_on_disk!([$($modifiers)*] {
652-
Some(::rustc_middle::query::cached::$name)
645+
will_cache_on_disk_for_key_fn: if_cache_on_disk!([$($modifiers)*] {
646+
Some(::rustc_middle::query::_cache_on_disk_if_fns::$name)
653647
} {
654648
None
655649
}),
@@ -670,10 +664,10 @@ macro_rules! define_queries {
670664
)
671665
)
672666
},
673-
try_load_from_disk_fn: should_ever_cache_on_disk!([$($modifiers)*] {
667+
try_load_from_disk_fn: if_cache_on_disk!([$($modifiers)*] {
674668
Some(|tcx, key, prev_index, index| {
675669
// Check the `cache_on_disk_if` condition for this key.
676-
if !::rustc_middle::query::cached::$name(tcx, key) {
670+
if !::rustc_middle::query::_cache_on_disk_if_fns::$name(tcx, key) {
677671
return None;
678672
}
679673

@@ -686,9 +680,9 @@ macro_rules! define_queries {
686680
} {
687681
None
688682
}),
689-
is_loadable_from_disk_fn: should_ever_cache_on_disk!([$($modifiers)*] {
683+
is_loadable_from_disk_fn: if_cache_on_disk!([$($modifiers)*] {
690684
Some(|tcx, key, index| -> bool {
691-
::rustc_middle::query::cached::$name(tcx, key) &&
685+
::rustc_middle::query::_cache_on_disk_if_fns::$name(tcx, key) &&
692686
$crate::plumbing::loadable_from_disk(tcx, index)
693687
})
694688
} {
@@ -773,7 +767,7 @@ macro_rules! define_queries {
773767
)
774768
}
775769

776-
item_if_cached! { [$($modifiers)*] {
770+
item_if_cache_on_disk! { [$($modifiers)*]
777771
pub(crate) fn encode_query_results<'tcx>(
778772
tcx: TyCtxt<'tcx>,
779773
encoder: &mut CacheEncoder<'_, 'tcx>,
@@ -786,7 +780,7 @@ macro_rules! define_queries {
786780
query_result_index,
787781
)
788782
}
789-
}}
783+
}
790784

791785
pub(crate) fn query_key_hash_verify<'tcx>(tcx: TyCtxt<'tcx>) {
792786
$crate::plumbing::query_key_hash_verify(
@@ -833,7 +827,15 @@ macro_rules! define_queries {
833827
&mut CacheEncoder<'_, 'tcx>,
834828
&mut EncodedDepNodeIndex)
835829
>
836-
] = &[$(expand_if_cached!([$($modifiers)*], query_impl::$name::encode_query_results)),*];
830+
] = &[
831+
$(
832+
if_cache_on_disk!([$($modifiers)*] {
833+
Some(query_impl::$name::encode_query_results)
834+
} {
835+
None
836+
})
837+
),*
838+
];
837839

838840
const QUERY_KEY_HASH_VERIFY: &[
839841
for<'tcx> fn(TyCtxt<'tcx>)

0 commit comments

Comments
 (0)