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