diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index b75236b35230b..75be5a1686035 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -5,8 +5,8 @@ use syn::parse::{Parse, ParseStream, Result}; use syn::punctuated::Punctuated; use syn::spanned::Spanned; use syn::{ - AttrStyle, Attribute, Block, Error, Expr, Ident, Pat, ReturnType, Token, Type, braced, - parenthesized, parse_macro_input, token, + AttrStyle, Attribute, Error, Expr, Ident, Pat, ReturnType, Token, Type, braced, parenthesized, + parse_macro_input, token, }; mod kw { @@ -132,16 +132,11 @@ struct Desc { expr_list: Punctuated, } -struct CacheOnDiskIf { - modifier: Ident, - block: Block, -} - /// See `rustc_middle::query::modifiers` for documentation of each query modifier. struct QueryModifiers { // tidy-alphabetical-start arena_cache: Option, - cache_on_disk_if: Option, + cache_on_disk: Option, depth_limit: Option, desc: Desc, eval_always: Option, @@ -154,7 +149,7 @@ struct QueryModifiers { fn parse_query_modifiers(input: ParseStream<'_>) -> Result { let mut arena_cache = None; - let mut cache_on_disk_if = None; + let mut cache_on_disk = None; let mut desc = None; let mut no_force = None; let mut no_hash = None; @@ -182,11 +177,8 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result { braced!(attr_content in input); let expr_list = attr_content.parse_terminated(Expr::parse, Token![,])?; 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 { tcx.is_typeck_child(key.to_def_id()) }` - let block = input.parse()?; - try_insert!(cache_on_disk_if = CacheOnDiskIf { modifier, block }); + } else if modifier == "cache_on_disk" { + try_insert!(cache_on_disk = modifier); } else if modifier == "arena_cache" { try_insert!(arena_cache = modifier); } else if modifier == "no_force" { @@ -210,7 +202,7 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result { }; Ok(QueryModifiers { arena_cache, - cache_on_disk_if, + cache_on_disk, desc, no_force, no_hash, @@ -244,7 +236,7 @@ fn make_modifiers_stream(query: &Query) -> proc_macro2::TokenStream { let QueryModifiers { // tidy-alphabetical-start arena_cache, - cache_on_disk_if, + cache_on_disk, depth_limit, desc: _, eval_always, @@ -256,7 +248,7 @@ fn make_modifiers_stream(query: &Query) -> proc_macro2::TokenStream { } = &query.modifiers; let arena_cache = arena_cache.is_some(); - let cache_on_disk = cache_on_disk_if.is_some(); + let cache_on_disk = cache_on_disk.is_some(); let depth_limit = depth_limit.is_some(); let eval_always = eval_always.is_some(); let feedable = feedable.is_some(); @@ -321,7 +313,6 @@ fn doc_comment_from_desc(list: &Punctuated) -> Result(tcx: TyCtxt<'tcx>, #key_pat: #key_ty) -> bool - #block - }); - } - let Desc { expr_list, .. } = &modifiers.desc; let desc = quote! { @@ -368,12 +349,6 @@ fn add_to_analyzer_stream(query: &Query, analyzer_stream: &mut proc_macro2::Toke crate::query::modifiers::#name; }); - if let Some(CacheOnDiskIf { modifier, .. }) = &modifiers.cache_on_disk_if { - modifiers_stream.extend(quote! { - crate::query::modifiers::#modifier; - }); - } - macro_rules! doc_link { ( $( $modifier:ident ),+ $(,)? ) => { $( @@ -389,6 +364,7 @@ fn add_to_analyzer_stream(query: &Query, analyzer_stream: &mut proc_macro2::Toke doc_link!( // tidy-alphabetical-start arena_cache, + cache_on_disk, depth_limit, eval_always, feedable, @@ -489,7 +465,7 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream { make_helpers_for_query(&query, &mut helpers); } - let HelperTokenStreams { description_fns_stream, cache_on_disk_if_fns_stream } = helpers; + let HelperTokenStreams { description_fns_stream } = helpers; TokenStream::from(quote! { /// Higher-order macro that invokes the specified macro with (a) a list of all query @@ -525,14 +501,6 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream { #description_fns_stream } - // FIXME(Zalathar): Instead of declaring these functions directly, can - // we put them in a macro and then expand that macro downstream in - // `rustc_query_impl`, where the functions are actually used? - pub mod _cache_on_disk_if_fns { - use super::*; - #cache_on_disk_if_fns_stream - } - #errors }) } diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index 7537a4fc6b0e8..179998c2ee24c 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -144,7 +144,7 @@ rustc_queries! { /// The output is the token stream generated by the proc macro. query derive_macro_expansion(key: (LocalExpnId, &'tcx TokenStream)) -> Result<&'tcx TokenStream, ()> { desc { "expanding a derive (proc) macro" } - cache_on_disk_if { true } + cache_on_disk } /// This exists purely for testing the interactions between delayed bugs and incremental. @@ -235,7 +235,7 @@ rustc_queries! { query hir_module_items(key: LocalModDefId) -> &'tcx rustc_middle::hir::ModuleItems { arena_cache desc { "getting HIR module items in `{}`", tcx.def_path_str(key) } - cache_on_disk_if { true } + cache_on_disk } /// Returns HIR ID for the given `LocalDefId`. @@ -283,7 +283,7 @@ rustc_queries! { /// E.g., given `struct Ty;` this returns `3` for `N`. query const_param_default(param: DefId) -> ty::EarlyBinder<'tcx, ty::Const<'tcx>> { desc { "computing the default for const parameter `{}`", tcx.def_path_str(param) } - cache_on_disk_if { param.is_local() } + cache_on_disk separate_provide_extern } @@ -296,7 +296,7 @@ rustc_queries! { /// This query will ICE if given a const that is not marked with `type const`. query const_of_item(def_id: DefId) -> ty::EarlyBinder<'tcx, ty::Const<'tcx>> { desc { "computing the type-level value for `{}`", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } + cache_on_disk separate_provide_extern } @@ -328,7 +328,7 @@ rustc_queries! { }, path = tcx.def_path_str(key), } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern feedable } @@ -376,7 +376,7 @@ rustc_queries! { -> Result<&'tcx DefIdMap>>, ErrorGuaranteed> { desc { "comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process" } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } @@ -427,7 +427,7 @@ rustc_queries! { query generics_of(key: DefId) -> &'tcx ty::Generics { desc { "computing generics of `{}`", tcx.def_path_str(key) } arena_cache - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern feedable } @@ -483,7 +483,7 @@ rustc_queries! { /// ``` query explicit_item_bounds(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { desc { "finding item bounds for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern feedable } @@ -496,7 +496,7 @@ rustc_queries! { /// [explicit item bounds]: Self::explicit_item_bounds query explicit_item_self_bounds(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { desc { "finding item bounds for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern feedable } @@ -625,7 +625,7 @@ rustc_queries! { /// the final value of a `const`. query mir_const_qualif(key: DefId) -> mir::ConstQualifs { desc { "const checking `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } @@ -658,7 +658,7 @@ rustc_queries! { key: DefId ) -> &'tcx mir::Body<'tcx> { desc { "caching mir of `{}` for CTFE", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } @@ -693,7 +693,7 @@ rustc_queries! { query mir_coroutine_witnesses(key: DefId) -> Option<&'tcx mir::CoroutineLayout<'tcx>> { arena_cache desc { "coroutine witness types for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } @@ -721,7 +721,7 @@ rustc_queries! { /// for codegen. This is also the only query that can fetch non-local MIR, at present. query optimized_mir(key: DefId) -> &'tcx mir::Body<'tcx> { desc { "optimizing MIR for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } @@ -759,7 +759,7 @@ rustc_queries! { /// need to use the `DefId` of the original body. query promoted_mir(key: DefId) -> &'tcx IndexVec> { desc { "optimizing promoted MIR for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } @@ -810,7 +810,7 @@ rustc_queries! { /// predicates with explicit spans for diagnostics purposes. query explicit_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { desc { "computing explicit predicates of `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern feedable } @@ -823,7 +823,7 @@ rustc_queries! { /// print the result of this query for use in UI tests or for debugging purposes. query inferred_outlives_of(key: DefId) -> &'tcx [(ty::Clause<'tcx>, Span)] { desc { "computing inferred outlives-predicates of `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern feedable } @@ -837,7 +837,7 @@ rustc_queries! { /// predicates are available (note that super-predicates must not be cyclic). query explicit_super_predicates_of(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { desc { "computing the super predicates of `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } @@ -849,7 +849,7 @@ rustc_queries! { /// predicates of the trait alias. query explicit_implied_predicates_of(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { desc { "computing the implied predicates of `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } @@ -908,22 +908,22 @@ rustc_queries! { query trait_def(key: DefId) -> &'tcx ty::TraitDef { desc { "computing trait definition for `{}`", tcx.def_path_str(key) } arena_cache - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } query adt_def(key: DefId) -> ty::AdtDef<'tcx> { desc { "computing ADT definition for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } query adt_destructor(key: DefId) -> Option { desc { "computing `Drop` impl for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } query adt_async_destructor(key: DefId) -> Option { desc { "computing `AsyncDrop` impl for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } query adt_sizedness_constraint( @@ -1031,7 +1031,7 @@ rustc_queries! { /// the result of this query for use in UI tests or for debugging purposes. query variances_of(def_id: DefId) -> &'tcx [ty::Variance] { desc { "computing the variances of `{}`", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } + cache_on_disk separate_provide_extern } @@ -1051,14 +1051,14 @@ rustc_queries! { /// to a list of the `DefId`s of its associated items or fields. query associated_item_def_ids(key: DefId) -> &'tcx [DefId] { desc { "collecting associated items or fields of `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } /// Maps from a trait/impl item to the trait/impl item "descriptor". query associated_item(key: DefId) -> ty::AssocItem { desc { "computing associated item data for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern feedable } @@ -1106,7 +1106,7 @@ rustc_queries! { /// Given an `impl_id`, return the trait it implements along with some header information. query impl_trait_header(impl_id: DefId) -> ty::ImplTraitHeader<'tcx> { desc { "computing trait implemented by `{}`", tcx.def_path_str(impl_id) } - cache_on_disk_if { impl_id.is_local() } + cache_on_disk separate_provide_extern } @@ -1122,7 +1122,7 @@ rustc_queries! { /// Methods in these implementations don't need to be exported. query inherent_impls(key: DefId) -> &'tcx [DefId] { desc { "collecting inherent impls for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } @@ -1163,7 +1163,7 @@ rustc_queries! { /// Computes the signature of the function. query fn_sig(key: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> { desc { "computing function signature of `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } @@ -1193,7 +1193,6 @@ rustc_queries! { 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.is_typeck_child(key.to_def_id()) } } /// Return the live symbols in the crate for dead code check. @@ -1218,18 +1217,18 @@ rustc_queries! { /// Caches `CoerceUnsized` kinds for impls on custom types. query coerce_unsized_info(key: DefId) -> Result { desc { "computing CoerceUnsized info for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } query typeck_root(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> { desc { "type-checking `{}`", tcx.def_path_str(key) } - cache_on_disk_if { true } + cache_on_disk } query used_trait_imports(key: LocalDefId) -> &'tcx UnordSet { desc { "finding used_trait_imports `{}`", tcx.def_path_str(key) } - cache_on_disk_if { true } + cache_on_disk } query coherent_trait(def_id: DefId) -> Result<(), ErrorGuaranteed> { @@ -1295,7 +1294,7 @@ rustc_queries! { "computing (transitive) callees of `{}` that may recurse", tcx.def_path_str(key), } - cache_on_disk_if { true } + cache_on_disk } /// Obtain all the calls into other local functions @@ -1333,7 +1332,7 @@ rustc_queries! { "const-evaluating + checking `{}`", key.value.display(tcx) } - cache_on_disk_if { true } + cache_on_disk } /// Evaluate a static's initializer, returning the allocation of the initializer's memory. @@ -1342,7 +1341,7 @@ rustc_queries! { "evaluating initializer of static `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern feedable } @@ -1366,7 +1365,7 @@ rustc_queries! { key.value.display(tcx) } depth_limit - cache_on_disk_if { true } + cache_on_disk } /// Evaluate a constant and convert it to a type level constant or @@ -1408,7 +1407,7 @@ rustc_queries! { query reachable_set(_: ()) -> &'tcx LocalDefIdSet { arena_cache desc { "reachability" } - cache_on_disk_if { true } + cache_on_disk } /// Per-body `region::ScopeTree`. The `DefId` should be the owner `DefId` for the body; @@ -1432,12 +1431,12 @@ rustc_queries! { /// look up the correct symbol name of instances from upstream crates. query symbol_name(key: ty::Instance<'tcx>) -> ty::SymbolName<'tcx> { desc { "computing the symbol for `{}`", key } - cache_on_disk_if { true } + cache_on_disk } query def_kind(def_id: DefId) -> DefKind { desc { "looking up definition kind of `{}`", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } + cache_on_disk separate_provide_extern feedable } @@ -1445,7 +1444,7 @@ rustc_queries! { /// Gets the span for the definition. query def_span(def_id: DefId) -> Span { desc { "looking up span for `{}`", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } + cache_on_disk separate_provide_extern feedable } @@ -1453,7 +1452,7 @@ rustc_queries! { /// Gets the span for the identifier of the definition. query def_ident_span(def_id: DefId) -> Option { desc { "looking up span for `{}`'s identifier", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } + cache_on_disk separate_provide_extern feedable } @@ -1462,18 +1461,18 @@ rustc_queries! { /// Panics if it is not a definition that has a single type. query ty_span(def_id: LocalDefId) -> Span { desc { "looking up span for `{}`'s type", tcx.def_path_str(def_id) } - cache_on_disk_if { true } + cache_on_disk } query lookup_stability(def_id: DefId) -> Option { desc { "looking up stability of `{}`", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } + cache_on_disk separate_provide_extern } query lookup_const_stability(def_id: DefId) -> Option { desc { "looking up const stability of `{}`", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } + cache_on_disk separate_provide_extern } @@ -1492,7 +1491,7 @@ rustc_queries! { query lookup_deprecation_entry(def_id: DefId) -> Option { desc { "checking whether `{}` is deprecated", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } + cache_on_disk separate_provide_extern } @@ -1527,7 +1526,7 @@ rustc_queries! { query codegen_fn_attrs(def_id: DefId) -> &'tcx CodegenFnAttrs { desc { "computing codegen attributes of `{}`", tcx.def_path_str(def_id) } arena_cache - cache_on_disk_if { def_id.is_local() } + cache_on_disk separate_provide_extern feedable } @@ -1562,7 +1561,7 @@ rustc_queries! { query is_mir_available(key: DefId) -> bool { desc { "checking if item has MIR available: `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } @@ -1596,7 +1595,7 @@ rustc_queries! { query codegen_select_candidate( key: PseudoCanonicalInput<'tcx, ty::TraitRef<'tcx>> ) -> Result<&'tcx ImplSource<'tcx, ()>, CodegenObligationError> { - cache_on_disk_if { true } + cache_on_disk desc { "computing candidate for `{}`", key.value } } @@ -1618,7 +1617,7 @@ rustc_queries! { query specialization_graph_of(trait_id: DefId) -> Result<&'tcx specialization_graph::Graph, ErrorGuaranteed> { desc { "building specialization graph of trait `{}`", tcx.def_path_str(trait_id) } - cache_on_disk_if { true } + cache_on_disk } query dyn_compatibility_violations(trait_id: DefId) -> &'tcx [DynCompatibilityViolation] { desc { "determining dyn-compatibility of trait `{}`", tcx.def_path_str(trait_id) } @@ -1706,7 +1705,7 @@ rustc_queries! { /// then `Err(AlwaysRequiresDrop)` is returned. query adt_drop_tys(def_id: DefId) -> Result<&'tcx ty::List>, AlwaysRequiresDrop> { desc { "computing when `{}` needs drop", tcx.def_path_str(def_id) } - cache_on_disk_if { true } + cache_on_disk } /// A list of types where the ADT requires async drop if and only if any of @@ -1714,7 +1713,7 @@ rustc_queries! { /// then `Err(AlwaysRequiresDrop)` is returned. query adt_async_drop_tys(def_id: DefId) -> Result<&'tcx ty::List>, AlwaysRequiresDrop> { desc { "computing when `{}` needs async drop", tcx.def_path_str(def_id) } - cache_on_disk_if { true } + cache_on_disk } /// A list of types where the ADT requires drop if and only if any of those types @@ -1841,7 +1840,7 @@ rustc_queries! { } query has_ffi_unwind_calls(key: LocalDefId) -> bool { desc { "checking if `{}` contains FFI-unwind calls", tcx.def_path_str(key) } - cache_on_disk_if { true } + cache_on_disk } query required_panic_strategy(_: CrateNum) -> Option { desc { "getting a crate's required panic strategy" } @@ -1921,7 +1920,7 @@ rustc_queries! { } query is_reachable_non_generic(def_id: DefId) -> bool { desc { "checking whether `{}` is an exported symbol", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } + cache_on_disk separate_provide_extern } query is_unreachable_local_definition(def_id: LocalDefId) -> bool { @@ -2368,7 +2367,7 @@ rustc_queries! { /// sets of different crates do not intersect. query exported_non_generic_symbols(cnum: CrateNum) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] { desc { "collecting exported non-generic symbols for crate `{}`", cnum} - cache_on_disk_if { cnum == LOCAL_CRATE } + cache_on_disk separate_provide_extern } @@ -2381,7 +2380,7 @@ rustc_queries! { /// sets of different crates do not intersect. query exported_generic_symbols(cnum: CrateNum) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] { desc { "collecting exported generic symbols for crate `{}`", cnum} - cache_on_disk_if { cnum == LOCAL_CRATE } + cache_on_disk separate_provide_extern } @@ -2711,12 +2710,12 @@ rustc_queries! { query items_of_instance(key: (ty::Instance<'tcx>, CollectionMode)) -> Result<(&'tcx [Spanned>], &'tcx [Spanned>]), NormalizationErrorInMono> { desc { "collecting items used by `{}`", key.0 } - cache_on_disk_if { true } + cache_on_disk } query size_estimate(key: ty::Instance<'tcx>) -> usize { desc { "estimating codegen size of `{}`", key } - cache_on_disk_if { true } + cache_on_disk } query anon_const_kind(def_id: DefId) -> ty::AnonConstKind { @@ -2726,7 +2725,7 @@ rustc_queries! { query trivial_const(def_id: DefId) -> Option<(mir::ConstValue, Ty<'tcx>)> { desc { "checking if `{}` is a trivial const", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } + cache_on_disk separate_provide_extern } @@ -2748,7 +2747,7 @@ rustc_queries! { query externally_implementable_items(cnum: CrateNum) -> &'tcx FxIndexMap)> { arena_cache desc { "looking up the externally implementable items of a crate" } - cache_on_disk_if { cnum == LOCAL_CRATE } + cache_on_disk separate_provide_extern } diff --git a/compiler/rustc_middle/src/query/modifiers.rs b/compiler/rustc_middle/src/query/modifiers.rs index 50c9136ac6e9d..2d22a548b7351 100644 --- a/compiler/rustc_middle/src/query/modifiers.rs +++ b/compiler/rustc_middle/src/query/modifiers.rs @@ -18,11 +18,15 @@ /// The query plumbing takes care of the arenas and the type manipulations. pub(crate) struct arena_cache; -/// # `cache_on_disk_if { ... }` query modifier +/// # `cache_on_disk` query modifier /// -/// 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`. -pub(crate) struct cache_on_disk_if; +/// The query's return values are cached to disk, and can be loaded by subsequent +/// sessions if the corresponding dep node is green. +/// +/// If the [`separate_provide_extern`] modifier is also present, values will only +/// be cached to disk for "local" keys, because values for external crates should +/// be loadable from crate metadata instead. +pub(crate) struct cache_on_disk; /// # `depth_limit` query modifier /// @@ -73,6 +77,8 @@ pub(crate) struct no_hash; /// # `separate_provide_extern` query modifier /// /// Use separate query provider functions for local and extern crates. +/// +/// Also affects the [`cache_on_disk`] modifier. pub(crate) struct separate_provide_extern; // tidy-alphabetical-end diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index e5c7d994b6c89..2e1e614b8fb4c 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -97,7 +97,7 @@ pub struct QueryVTable<'tcx, C: QueryCache> { /// This should be the only code that calls the provider function. pub invoke_provider_fn: fn(tcx: TyCtxt<'tcx>, key: C::Key) -> C::Value, - pub will_cache_on_disk_for_key_fn: fn(tcx: TyCtxt<'tcx>, key: C::Key) -> bool, + pub will_cache_on_disk_for_key_fn: fn(key: C::Key) -> bool, pub try_load_from_disk_fn: fn( tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_query_impl/src/execution.rs b/compiler/rustc_query_impl/src/execution.rs index 8844d40f49cf3..44995f3f9826a 100644 --- a/compiler/rustc_query_impl/src/execution.rs +++ b/compiler/rustc_query_impl/src/execution.rs @@ -576,7 +576,7 @@ fn ensure_can_skip_execution<'tcx, C: QueryCache>( // needed, which guarantees the query provider will never run // for this key. EnsureMode::Done => { - (query.will_cache_on_disk_for_key_fn)(tcx, key) + (query.will_cache_on_disk_for_key_fn)(key) && loadable_from_disk(tcx, serialized_dep_node_index) } } diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index ef4fff293bf65..dfc66a2225f26 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -93,7 +93,7 @@ fn encode_query_values_inner<'a, 'tcx, C, V>( assert!(all_inactive(&query.state)); query.cache.for_each(&mut |key, value, dep_node| { - if (query.will_cache_on_disk_for_key_fn)(tcx, *key) { + if (query.will_cache_on_disk_for_key_fn)(*key) { encoder.encode_query_value::(dep_node, &erase::restore_val::(*value)); } }); @@ -152,7 +152,7 @@ pub(crate) fn promote_from_disk_inner<'tcx, C: QueryCache>( // If the recovered key isn't eligible for cache-on-disk, then there's no // value on disk to promote. - if !(query.will_cache_on_disk_for_key_fn)(tcx, key) { + if !(query.will_cache_on_disk_for_key_fn)(key) { return; } diff --git a/compiler/rustc_query_impl/src/query_impl.rs b/compiler/rustc_query_impl/src/query_impl.rs index 60ddf3e4ad381..2d3dae04181e5 100644 --- a/compiler/rustc_query_impl/src/query_impl.rs +++ b/compiler/rustc_query_impl/src/query_impl.rs @@ -125,6 +125,20 @@ macro_rules! define_queries { } } + fn will_cache_on_disk_for_key<'tcx>( + _key: rustc_middle::queries::$name::Key<'tcx>, + ) -> bool { + cfg_select! { + // If a query has both `cache_on_disk` and `separate_provide_extern`, only + // disk-cache values for "local" keys, i.e. things in the current crate. + all($cache_on_disk, $separate_provide_extern) => { + AsLocalQueryKey::as_local_key(&_key).is_some() + } + all($cache_on_disk, not($separate_provide_extern)) => true, + not($cache_on_disk) => false, + } + } + pub(crate) fn make_query_vtable<'tcx>(incremental: bool) -> QueryVTable<'tcx, rustc_middle::queries::$name::Cache<'tcx>> { @@ -141,18 +155,15 @@ macro_rules! define_queries { invoke_provider_fn: self::invoke_provider_fn::__rust_begin_short_backtrace, - #[cfg($cache_on_disk)] will_cache_on_disk_for_key_fn: - rustc_middle::queries::_cache_on_disk_if_fns::$name, - #[cfg(not($cache_on_disk))] - will_cache_on_disk_for_key_fn: |_, _| false, + $crate::query_impl::$name::will_cache_on_disk_for_key, #[cfg($cache_on_disk)] try_load_from_disk_fn: |tcx, key, prev_index, index| { use rustc_middle::queries::$name::{ProvidedValue, provided_to_erased}; - // Check the `cache_on_disk_if` condition for this key. - if !rustc_middle::queries::_cache_on_disk_if_fns::$name(tcx, key) { + // Check the cache-on-disk condition for this key. + if !$crate::query_impl::$name::will_cache_on_disk_for_key(key) { return None; } diff --git a/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md b/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md index 014d1a08af78b..d68c90f49b80f 100644 --- a/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md +++ b/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md @@ -479,11 +479,11 @@ respect to incremental compilation: and the projection queries act as a "firewall", shielding their dependents from the unconditionally red `no_hash` node. - - `cache_on_disk_if` - This attribute is what determines which query results - are persisted in the incremental compilation query result cache. - The attribute takes an expression that allows per query invocation decisions. - For example, it makes no sense to store values from upstream - crates in the cache because they are already available in the upstream crate's metadata. + - `cache_on_disk` - The query's return values are cached to disk, and can be + loaded by subsequent sessions if the corresponding dep node is green. + If the `separate_provide_extern` modifier is also present, values will only + be cached to disk for "local" keys, because values for external crates should + be loadable from crate metadata instead. [mod]: ../query.html#adding-a-new-kind-of-query diff --git a/src/doc/rustc-dev-guide/src/query.md b/src/doc/rustc-dev-guide/src/query.md index 680393a6d4f32..df0c21c9d719a 100644 --- a/src/doc/rustc-dev-guide/src/query.md +++ b/src/doc/rustc-dev-guide/src/query.md @@ -275,8 +275,9 @@ This looks something like: rustc_queries! { /// Records the type of every item. query type_of(key: DefId) -> Ty<'tcx> { - cache_on_disk_if { key.is_local() } desc { |tcx| "computing the type of `{}`", tcx.def_path_str(key) } + cache_on_disk + separate_provide_extern } ... }