@@ -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
135135fn 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}
0 commit comments