mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Remove explicit tcx bindings from query entries.
As currently written, these have big problems. - `desc` and `cache_on_disk_if` modifiers use different syntaxes to introduce `tcx`. - `desc` is mis-implemented such that the explicit binding isn't even necessary and the key name can be botched, as the previous two commits showed. (It's the `let (#tcx, #key) = (tcx, key);` line that messes things up.) It's simpler and less error-prone to simply not require explicit `tcx` bindings, and instead just make it implicitly available to these code snippets.
This commit is contained in:
@@ -103,13 +103,11 @@ fn parse(input: ParseStream<'_>) -> Result<Self> {
|
||||
|
||||
struct Desc {
|
||||
modifier: Ident,
|
||||
tcx_binding: Option<Ident>,
|
||||
expr_list: Punctuated<Expr, Token![,]>,
|
||||
}
|
||||
|
||||
struct CacheOnDiskIf {
|
||||
modifier: Ident,
|
||||
tcx_binding: Option<Pat>,
|
||||
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::<Token![|]>()?;
|
||||
let tcx = attr_content.parse()?;
|
||||
attr_content.parse::<Token![|]>()?;
|
||||
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)
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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<abi::FieldIdx> {
|
||||
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<LocalDefId> {
|
||||
|
||||
Reference in New Issue
Block a user