diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index d81bac4930a6..346604a46ef7 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -103,13 +103,11 @@ fn parse(input: ParseStream<'_>) -> Result { struct Desc { modifier: Ident, - tcx_binding: Option, expr_list: Punctuated, } struct CacheOnDiskIf { modifier: Ident, - tcx_binding: Option, block: Block, } @@ -192,35 +190,16 @@ macro_rules! try_insert { if modifier == "desc" { // Parse a description modifier like: - // `desc { |tcx| "foo {}", tcx.item_path(key) }` + // `desc { "foo {}", tcx.item_path(key) }` let attr_content; braced!(attr_content in input); - let tcx_binding = if attr_content.peek(Token![|]) { - attr_content.parse::()?; - let tcx = attr_content.parse()?; - attr_content.parse::()?; - Some(tcx) - } else { - None - }; let expr_list = attr_content.parse_terminated(Expr::parse, Token![,])?; - try_insert!(desc = Desc { modifier, tcx_binding, expr_list }); + try_insert!(desc = Desc { modifier, expr_list }); } else if modifier == "cache_on_disk_if" { // Parse a cache-on-disk modifier like: - // - // `cache_on_disk_if { true }` - // `cache_on_disk_if { key.is_local() }` - // `cache_on_disk_if(tcx) { tcx.is_typeck_child(key.to_def_id()) }` - let tcx_binding = if input.peek(token::Paren) { - let args; - parenthesized!(args in input); - let tcx = Pat::parse_single(&args)?; - Some(tcx) - } else { - None - }; + // `cache_on_disk_if { tcx.is_typeck_child(key.to_def_id()) }` let block = input.parse()?; - try_insert!(cache_on_disk_if = CacheOnDiskIf { modifier, tcx_binding, block }); + try_insert!(cache_on_disk_if = CacheOnDiskIf { modifier, block }); } else if modifier == "arena_cache" { try_insert!(arena_cache = modifier); } else if modifier == "cycle_fatal" { @@ -313,24 +292,24 @@ fn make_helpers_for_query(query: &Query, streams: &mut HelperTokenStreams) { erased_name.set_span(Span::call_site()); // Generate a function to check whether we should cache the query to disk, for some key. - if let Some(CacheOnDiskIf { tcx_binding, block, .. }) = modifiers.cache_on_disk_if.as_ref() { - let tcx = tcx_binding.as_ref().map(|t| quote! { #t }).unwrap_or_else(|| quote! { _ }); - // we're taking `key` by reference, but some rustc types usually prefer being passed by value + if let Some(CacheOnDiskIf { block, .. }) = modifiers.cache_on_disk_if.as_ref() { + // `pass_by_value`: some keys are marked with `rustc_pass_by_value`, but we take keys by + // reference here. + // FIXME: `pass_by_value` is badly named; `allow(rustc::pass_by_value)` actually means + // "allow pass by reference of `rustc_pass_by_value` types". streams.cache_on_disk_if_fns_stream.extend(quote! { #[allow(unused_variables, rustc::pass_by_value)] #[inline] - pub fn #erased_name<'tcx>(#tcx: TyCtxt<'tcx>, #key_pat: &crate::queries::#name::Key<'tcx>) -> bool + pub fn #erased_name<'tcx>(tcx: TyCtxt<'tcx>, #key_pat: &#key_ty) -> bool #block }); } - let Desc { tcx_binding, expr_list, .. } = &modifiers.desc; - let tcx = tcx_binding.as_ref().map_or_else(|| quote! { _ }, |t| quote! { #t }); + let Desc { expr_list, .. } = &modifiers.desc; let desc = quote! { #[allow(unused_variables)] - pub fn #erased_name<'tcx>(tcx: TyCtxt<'tcx>, key: #key_ty) -> String { - let (#tcx, #key_pat) = (tcx, key); + pub fn #erased_name<'tcx>(tcx: TyCtxt<'tcx>, #key_pat: #key_ty) -> String { format!(#expr_list) } }; diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index 0cf15bd793a9..3a3a2743ec4f 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -25,9 +25,13 @@ //! Query modifiers are special flags that alter the behavior of a query. They are parsed and processed by the `rustc_macros` //! The main modifiers are: //! -//! - `desc { ... }`: Sets the human-readable description for diagnostics and profiling. Required for every query. +//! - `desc { ... }`: Sets the human-readable description for diagnostics and profiling. Required +//! for every query. The block should contain a `format!`-style string literal followed by +//! optional arguments. The query key identifier is available for use within the block, as is +//! `tcx`. //! - `arena_cache`: Use an arena for in-memory caching of the query result. -//! - `cache_on_disk_if { ... }`: Cache the query result to disk if the provided block evaluates to true. +//! - `cache_on_disk_if { ... }`: Cache the query result to disk if the provided block evaluates to +//! true. The query key identifier is available for use within the block, as is `tcx`. //! - `cycle_fatal`: If a dependency cycle is detected, abort compilation with a fatal error. //! - `cycle_delay_bug`: If a dependency cycle is detected, emit a delayed bug instead of aborting immediately. //! - `cycle_stash`: If a dependency cycle is detected, stash the error for later handling. @@ -1211,7 +1215,7 @@ query check_liveness(key: LocalDefId) -> &'tcx rustc_index::bit_set::DenseBitSet { arena_cache desc { "checking liveness of variables in `{}`", tcx.def_path_str(key.to_def_id()) } - cache_on_disk_if(tcx) { tcx.is_typeck_child(key.to_def_id()) } + cache_on_disk_if { tcx.is_typeck_child(key.to_def_id()) } } /// Return the live symbols in the crate for dead code check. @@ -1244,7 +1248,7 @@ query typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> { desc { "type-checking `{}`", tcx.def_path_str(key) } - cache_on_disk_if(tcx) { !tcx.is_typeck_child(key.to_def_id()) } + cache_on_disk_if { !tcx.is_typeck_child(key.to_def_id()) } } query used_trait_imports(key: LocalDefId) -> &'tcx UnordSet {