summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_query_impl
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:11:38 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:13:23 +0000
commit20431706a863f92cb37dc512fef6e48d192aaf2c (patch)
tree2867f13f5fd5437ba628c67d7f87309ccadcd286 /compiler/rustc_query_impl
parentReleasing progress-linux version 1.65.0+dfsg1-2~progress7.99u1. (diff)
downloadrustc-20431706a863f92cb37dc512fef6e48d192aaf2c.tar.xz
rustc-20431706a863f92cb37dc512fef6e48d192aaf2c.zip
Merging upstream version 1.66.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_query_impl')
-rw-r--r--compiler/rustc_query_impl/src/keys.rs42
-rw-r--r--compiler/rustc_query_impl/src/lib.rs13
-rw-r--r--compiler/rustc_query_impl/src/on_disk_cache.rs13
-rw-r--r--compiler/rustc_query_impl/src/plumbing.rs188
-rw-r--r--compiler/rustc_query_impl/src/profiling_support.rs25
5 files changed, 199 insertions, 82 deletions
diff --git a/compiler/rustc_query_impl/src/keys.rs b/compiler/rustc_query_impl/src/keys.rs
index 49175e97f..8be2e2be8 100644
--- a/compiler/rustc_query_impl/src/keys.rs
+++ b/compiler/rustc_query_impl/src/keys.rs
@@ -1,6 +1,7 @@
//! Defines the set of legal keys that can be used in queries.
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
+use rustc_hir::hir_id::{HirId, OwnerId};
use rustc_middle::infer::canonical::Canonical;
use rustc_middle::mir;
use rustc_middle::traits;
@@ -26,6 +27,10 @@ pub trait Key {
fn key_as_def_id(&self) -> Option<DefId> {
None
}
+
+ fn ty_adt_id(&self) -> Option<DefId> {
+ None
+ }
}
impl Key for () {
@@ -104,6 +109,19 @@ impl Key for CrateNum {
}
}
+impl Key for OwnerId {
+ #[inline(always)]
+ fn query_crate_is_local(&self) -> bool {
+ true
+ }
+ fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
+ self.to_def_id().default_span(tcx)
+ }
+ fn key_as_def_id(&self) -> Option<DefId> {
+ Some(self.to_def_id())
+ }
+}
+
impl Key for LocalDefId {
#[inline(always)]
fn query_crate_is_local(&self) -> bool {
@@ -275,7 +293,7 @@ impl<'tcx> Key for (DefId, SubstsRef<'tcx>) {
}
}
-impl<'tcx> Key for (ty::Unevaluated<'tcx, ()>, ty::Unevaluated<'tcx, ()>) {
+impl<'tcx> Key for (ty::UnevaluatedConst<'tcx>, ty::UnevaluatedConst<'tcx>) {
#[inline(always)]
fn query_crate_is_local(&self) -> bool {
(self.0).def.did.krate == LOCAL_CRATE
@@ -393,6 +411,12 @@ impl<'tcx> Key for Ty<'tcx> {
fn default_span(&self, _: TyCtxt<'_>) -> Span {
DUMMY_SP
}
+ fn ty_adt_id(&self) -> Option<DefId> {
+ match self.kind() {
+ ty::Adt(adt, _) => Some(adt.did()),
+ _ => None,
+ }
+ }
}
impl<'tcx> Key for TyAndLayout<'tcx> {
@@ -543,3 +567,19 @@ impl<'tcx> Key for (Ty<'tcx>, ty::ValTree<'tcx>) {
DUMMY_SP
}
}
+
+impl Key for HirId {
+ #[inline(always)]
+ fn query_crate_is_local(&self) -> bool {
+ true
+ }
+
+ fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
+ tcx.hir().span(*self)
+ }
+
+ #[inline(always)]
+ fn key_as_def_id(&self) -> Option<DefId> {
+ None
+ }
+}
diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs
index c87d26b39..11d4c97e7 100644
--- a/compiler/rustc_query_impl/src/lib.rs
+++ b/compiler/rustc_query_impl/src/lib.rs
@@ -1,6 +1,8 @@
//! Support for serializing the dep-graph and reloading it.
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
+// this shouldn't be necessary, but the check for `&mut _` is too naive and denies returning a function pointer that takes a mut ref
+#![feature(const_mut_refs)]
#![feature(min_specialization)]
#![feature(never_type)]
#![feature(once_cell)]
@@ -20,8 +22,7 @@ use rustc_middle::arena::Arena;
use rustc_middle::dep_graph::{self, DepKindStruct};
use rustc_middle::ty::query::{query_keys, query_storage, query_stored, query_values};
use rustc_middle::ty::query::{ExternProviders, Providers, QueryEngine};
-use rustc_middle::ty::{self, TyCtxt};
-use rustc_span::def_id::{LocalDefId, LOCAL_CRATE};
+use rustc_middle::ty::TyCtxt;
use rustc_span::Span;
#[macro_use]
@@ -43,14 +44,6 @@ pub use on_disk_cache::OnDiskCache;
mod profiling_support;
pub use self::profiling_support::alloc_self_profile_query_strings;
-fn describe_as_module(def_id: LocalDefId, tcx: TyCtxt<'_>) -> String {
- if def_id.is_top_level_module() {
- "top-level module".to_string()
- } else {
- format!("module `{}`", tcx.def_path_str(def_id.to_def_id()))
- }
-}
-
rustc_query_append! { define_queries! }
impl<'tcx> Queries<'tcx> {
diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs
index 0e93f3ce1..9000f81d9 100644
--- a/compiler/rustc_query_impl/src/on_disk_cache.rs
+++ b/compiler/rustc_query_impl/src/on_disk_cache.rs
@@ -1,8 +1,9 @@
use crate::QueryCtxt;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
+use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
use rustc_data_structures::memmap::Mmap;
use rustc_data_structures::sync::{HashMapExt, Lock, Lrc, RwLock};
use rustc_data_structures::unhash::UnhashMap;
+use rustc_data_structures::unord::UnordSet;
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, StableCrateId, LOCAL_CRATE};
use rustc_hir::definitions::DefPathHash;
use rustc_index::vec::{Idx, IndexVec};
@@ -118,12 +119,11 @@ pub type EncodedDepNodeIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>;
struct SourceFileIndex(u32);
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Encodable, Decodable)]
-pub struct AbsoluteBytePos(u32);
+pub struct AbsoluteBytePos(u64);
impl AbsoluteBytePos {
fn new(pos: usize) -> AbsoluteBytePos {
- debug_assert!(pos <= u32::MAX as usize);
- AbsoluteBytePos(pos as u32)
+ AbsoluteBytePos(pos.try_into().expect("Incremental cache file size overflowed u64."))
}
fn to_usize(self) -> usize {
@@ -792,7 +792,7 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for DefId {
}
}
-impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx FxHashSet<LocalDefId> {
+impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx UnordSet<LocalDefId> {
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
RefDecodable::decode(d)
}
@@ -848,6 +848,7 @@ impl_ref_decoder! {<'tcx>
rustc_span::def_id::DefId,
rustc_span::def_id::LocalDefId,
(rustc_middle::middle::exported_symbols::ExportedSymbol<'tcx>, rustc_middle::middle::exported_symbols::SymbolExportInfo),
+ ty::DeducedParamAttrs,
}
//- ENCODING -------------------------------------------------------------------
@@ -1067,7 +1068,7 @@ pub fn encode_query_results<'a, 'tcx, CTX, Q>(
let _timer = tcx
.dep_context()
.profiler()
- .extra_verbose_generic_activity("encode_query_results_for", std::any::type_name::<Q>());
+ .verbose_generic_activity_with_arg("encode_query_results_for", std::any::type_name::<Q>());
assert!(Q::query_state(tcx).all_inactive());
let cache = Q::query_cache(tcx);
diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs
index 6f39bbfc0..1d17f4221 100644
--- a/compiler/rustc_query_impl/src/plumbing.rs
+++ b/compiler/rustc_query_impl/src/plumbing.rs
@@ -3,7 +3,8 @@
//! manage the caches, and so forth.
use crate::keys::Key;
-use crate::on_disk_cache::CacheDecoder;
+use crate::on_disk_cache::{CacheDecoder, CacheEncoder, EncodedDepNodeIndex};
+use crate::profiling_support::QueryKeyStringCache;
use crate::{on_disk_cache, Queries};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::{AtomicU64, Lock};
@@ -19,8 +20,10 @@ use rustc_query_system::query::{
force_query, QueryConfig, QueryContext, QueryDescription, QueryJobId, QueryMap,
QuerySideEffects, QueryStackFrame,
};
-use rustc_query_system::Value;
+use rustc_query_system::{LayoutOfDepth, QueryOverflow, Value};
use rustc_serialize::Decodable;
+use rustc_session::Limit;
+use rustc_span::def_id::LOCAL_CRATE;
use std::any::Any;
use std::num::NonZeroU64;
use thin_vec::ThinVec;
@@ -109,7 +112,7 @@ impl QueryContext for QueryCtxt<'_> {
// when accessing the `ImplicitCtxt`.
tls::with_related_context(**self, move |current_icx| {
if depth_limit && !self.recursion_limit().value_within_limit(current_icx.query_depth) {
- self.depth_limit_error();
+ self.depth_limit_error(token);
}
// Update the `ImplicitCtxt` to point to our new query job.
@@ -127,6 +130,29 @@ impl QueryContext for QueryCtxt<'_> {
})
})
}
+
+ fn depth_limit_error(&self, job: QueryJobId) {
+ let mut span = None;
+ let mut layout_of_depth = None;
+ if let Some(map) = self.try_collect_active_jobs() {
+ if let Some((info, depth)) = job.try_find_layout_root(map) {
+ span = Some(info.job.span);
+ layout_of_depth = Some(LayoutOfDepth { desc: info.query.description, depth });
+ }
+ }
+
+ let suggested_limit = match self.recursion_limit() {
+ Limit(0) => Limit(2),
+ limit => limit * 2,
+ };
+
+ self.sess.emit_fatal(QueryOverflow {
+ span,
+ layout_of_depth,
+ suggested_limit,
+ crate_name: self.crate_name(LOCAL_CRATE),
+ });
+ }
}
impl<'tcx> QueryCtxt<'tcx> {
@@ -148,34 +174,14 @@ impl<'tcx> QueryCtxt<'tcx> {
pub(super) fn encode_query_results(
self,
- encoder: &mut on_disk_cache::CacheEncoder<'_, 'tcx>,
- query_result_index: &mut on_disk_cache::EncodedDepNodeIndex,
+ encoder: &mut CacheEncoder<'_, 'tcx>,
+ query_result_index: &mut EncodedDepNodeIndex,
) {
- macro_rules! expand_if_cached {
- ([] $encode:expr) => {};
- ([(cache) $($rest:tt)*] $encode:expr) => {
- $encode
- };
- ([$other:tt $($modifiers:tt)*] $encode:expr) => {
- expand_if_cached!([$($modifiers)*] $encode)
- };
- }
-
- macro_rules! encode_queries {
- (
- $($(#[$attr:meta])*
- [$($modifiers:tt)*] fn $query:ident($($K:tt)*) -> $V:ty,)*) => {
- $(
- expand_if_cached!([$($modifiers)*] on_disk_cache::encode_query_results::<_, super::queries::$query<'_>>(
- self,
- encoder,
- query_result_index
- ));
- )*
+ for query in &self.queries.query_structs {
+ if let Some(encode) = query.encode_query_results {
+ encode(self, encoder, query_result_index);
}
}
-
- rustc_query_append!(encode_queries!);
}
pub fn try_print_query_stack(
@@ -188,6 +194,14 @@ impl<'tcx> QueryCtxt<'tcx> {
}
}
+#[derive(Clone, Copy)]
+pub(crate) struct QueryStruct<'tcx> {
+ pub try_collect_active_jobs: fn(QueryCtxt<'tcx>, &mut QueryMap) -> Option<()>,
+ pub alloc_self_profile_query_strings: fn(TyCtxt<'tcx>, &mut QueryKeyStringCache),
+ pub encode_query_results:
+ Option<fn(QueryCtxt<'tcx>, &mut CacheEncoder<'_, 'tcx>, &mut EncodedDepNodeIndex)>,
+}
+
macro_rules! handle_cycle_error {
([]) => {{
rustc_query_system::HandleCycleError::Error
@@ -284,7 +298,7 @@ pub(crate) fn create_query_frame<
K: Copy + Key + for<'a> HashStable<StableHashingContext<'a>>,
>(
tcx: QueryCtxt<'tcx>,
- do_describe: fn(QueryCtxt<'tcx>, K) -> String,
+ do_describe: fn(TyCtxt<'tcx>, K) -> String,
key: K,
kind: DepKind,
name: &'static str,
@@ -293,7 +307,7 @@ pub(crate) fn create_query_frame<
// Showing visible path instead of any path is not that important in production.
let description = ty::print::with_no_visible_paths!(
// Force filename-line mode to avoid invoking `type_of` query.
- ty::print::with_forced_impl_filename_line!(do_describe(tcx, key))
+ ty::print::with_forced_impl_filename_line!(do_describe(tcx.tcx, key))
);
let description =
if tcx.sess.verbose() { format!("{} [{}]", description, name) } else { description };
@@ -304,13 +318,12 @@ pub(crate) fn create_query_frame<
} else {
Some(key.default_span(*tcx))
};
+ let def_id = key.key_as_def_id();
let def_kind = if kind == dep_graph::DepKind::opt_def_kind {
// Try to avoid infinite recursion.
None
} else {
- key.key_as_def_id()
- .and_then(|def_id| def_id.as_local())
- .and_then(|def_id| tcx.opt_def_kind(def_id))
+ def_id.and_then(|def_id| def_id.as_local()).and_then(|def_id| tcx.opt_def_kind(def_id))
};
let hash = || {
tcx.with_stable_hashing_context(|mut hcx| {
@@ -320,8 +333,9 @@ pub(crate) fn create_query_frame<
hasher.finish::<u64>()
})
};
+ let ty_adt_id = key.ty_adt_id();
- QueryStackFrame::new(name, description, span, def_kind, hash)
+ QueryStackFrame::new(name, description, span, def_id, def_kind, ty_adt_id, hash)
}
fn try_load_from_on_disk_cache<'tcx, Q>(tcx: TyCtxt<'tcx>, dep_node: DepNode)
@@ -355,6 +369,24 @@ where
Q::Key: DepNodeParams<TyCtxt<'tcx>>,
Q::Value: Value<TyCtxt<'tcx>>,
{
+ // We must avoid ever having to call `force_from_dep_node()` for a
+ // `DepNode::codegen_unit`:
+ // Since we cannot reconstruct the query key of a `DepNode::codegen_unit`, we
+ // would always end up having to evaluate the first caller of the
+ // `codegen_unit` query that *is* reconstructible. This might very well be
+ // the `compile_codegen_unit` query, thus re-codegenning the whole CGU just
+ // to re-trigger calling the `codegen_unit` query with the right key. At
+ // that point we would already have re-done all the work we are trying to
+ // avoid doing in the first place.
+ // The solution is simple: Just explicitly call the `codegen_unit` query for
+ // each CGU, right after partitioning. This way `try_mark_green` will always
+ // hit the cache instead of having to go through `force_from_dep_node`.
+ // This assertion makes sure, we actually keep applying the solution above.
+ debug_assert!(
+ dep_node.kind != DepKind::codegen_unit,
+ "calling force_from_dep_node() on DepKind::codegen_unit"
+ );
+
if let Some(key) = Q::Key::recover(tcx, &dep_node) {
#[cfg(debug_assertions)]
let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered();
@@ -395,6 +427,18 @@ where
}
}
+macro_rules! expand_if_cached {
+ ([], $tokens:expr) => {{
+ None
+ }};
+ ([(cache) $($rest:tt)*], $tokens:expr) => {{
+ Some($tokens)
+ }};
+ ([$other:tt $($modifiers:tt)*], $tokens:expr) => {
+ expand_if_cached!([$($modifiers)*], $tokens)
+ };
+}
+
// NOTE: `$V` isn't used here, but we still need to match on it so it can be passed to other macros
// invoked by `rustc_query_append`.
macro_rules! define_queries {
@@ -422,7 +466,10 @@ macro_rules! define_queries {
}
impl<'tcx> QueryDescription<QueryCtxt<'tcx>> for queries::$name<'tcx> {
- rustc_query_description! { $name }
+ #[inline]
+ fn cache_on_disk(tcx: TyCtxt<'tcx>, key: &Self::Key) -> bool {
+ ::rustc_middle::query::cached::$name(tcx, key)
+ }
type Cache = query_storage::$name<'tcx>;
@@ -528,6 +575,59 @@ macro_rules! define_queries {
})*
}
+ mod query_structs {
+ use rustc_middle::ty::TyCtxt;
+ use $crate::plumbing::{QueryStruct, QueryCtxt};
+ use $crate::profiling_support::QueryKeyStringCache;
+ use rustc_query_system::query::QueryMap;
+
+ pub(super) const fn dummy_query_struct<'tcx>() -> QueryStruct<'tcx> {
+ fn noop_try_collect_active_jobs(_: QueryCtxt<'_>, _: &mut QueryMap) -> Option<()> {
+ None
+ }
+ fn noop_alloc_self_profile_query_strings(_: TyCtxt<'_>, _: &mut QueryKeyStringCache) {}
+
+ QueryStruct {
+ try_collect_active_jobs: noop_try_collect_active_jobs,
+ alloc_self_profile_query_strings: noop_alloc_self_profile_query_strings,
+ encode_query_results: None,
+ }
+ }
+
+ pub(super) use dummy_query_struct as Null;
+ pub(super) use dummy_query_struct as Red;
+ pub(super) use dummy_query_struct as TraitSelect;
+ pub(super) use dummy_query_struct as CompileCodegenUnit;
+ pub(super) use dummy_query_struct as CompileMonoItem;
+
+ $(
+ pub(super) const fn $name<'tcx>() -> QueryStruct<'tcx> { QueryStruct {
+ try_collect_active_jobs: |tcx, qmap| {
+ let make_query = |tcx, key| {
+ let kind = rustc_middle::dep_graph::DepKind::$name;
+ let name = stringify!($name);
+ $crate::plumbing::create_query_frame(tcx, rustc_middle::query::descs::$name, key, kind, name)
+ };
+ tcx.queries.$name.try_collect_active_jobs(
+ tcx,
+ make_query,
+ qmap,
+ )
+ },
+ alloc_self_profile_query_strings: |tcx, string_cache| {
+ $crate::profiling_support::alloc_self_profile_query_strings_for_query_cache(
+ tcx,
+ stringify!($name),
+ &tcx.query_caches.$name,
+ string_cache,
+ )
+ },
+ encode_query_results: expand_if_cached!([$($modifiers)*], |tcx, encoder, query_result_index|
+ $crate::on_disk_cache::encode_query_results::<_, super::queries::$name<'_>>(tcx, encoder, query_result_index)
+ ),
+ }})*
+ }
+
pub fn query_callbacks<'tcx>(arena: &'tcx Arena<'tcx>) -> &'tcx [DepKindStruct<'tcx>] {
arena.alloc_from_iter(make_dep_kind_array!(query_callbacks))
}
@@ -542,9 +642,11 @@ impl<'tcx> Queries<'tcx> {
extern_providers: ExternProviders,
on_disk_cache: Option<OnDiskCache<'tcx>>,
) -> Self {
+ use crate::query_structs;
Queries {
local_providers: Box::new(local_providers),
extern_providers: Box::new(extern_providers),
+ query_structs: make_dep_kind_array!(query_structs).to_vec(),
on_disk_cache,
jobs: AtomicU64::new(1),
..Queries::default()
@@ -559,6 +661,7 @@ macro_rules! define_queries_struct {
pub struct Queries<'tcx> {
local_providers: Box<Providers>,
extern_providers: Box<ExternProviders>,
+ query_structs: Vec<$crate::plumbing::QueryStruct<'tcx>>,
pub on_disk_cache: Option<OnDiskCache<'tcx>>,
@@ -575,18 +678,9 @@ macro_rules! define_queries_struct {
let tcx = QueryCtxt { tcx, queries: self };
let mut jobs = QueryMap::default();
- $(
- let make_query = |tcx, key| {
- let kind = dep_graph::DepKind::$name;
- let name = stringify!($name);
- $crate::plumbing::create_query_frame(tcx, queries::$name::describe, key, kind, name)
- };
- self.$name.try_collect_active_jobs(
- tcx,
- make_query,
- &mut jobs,
- )?;
- )*
+ for query in &self.query_structs {
+ (query.try_collect_active_jobs)(tcx, &mut jobs);
+ }
Some(jobs)
}
diff --git a/compiler/rustc_query_impl/src/profiling_support.rs b/compiler/rustc_query_impl/src/profiling_support.rs
index 98ec3bc09..2cc311d48 100644
--- a/compiler/rustc_query_impl/src/profiling_support.rs
+++ b/compiler/rustc_query_impl/src/profiling_support.rs
@@ -1,3 +1,4 @@
+use crate::QueryCtxt;
use measureme::{StringComponent, StringId};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::profiling::SelfProfiler;
@@ -8,7 +9,7 @@ use rustc_query_system::query::QueryCache;
use std::fmt::Debug;
use std::io::Write;
-struct QueryKeyStringCache {
+pub(crate) struct QueryKeyStringCache {
def_id_cache: FxHashMap<DefId, StringId>,
}
@@ -226,7 +227,7 @@ where
/// Allocate the self-profiling query strings for a single query cache. This
/// method is called from `alloc_self_profile_query_strings` which knows all
/// the queries via macro magic.
-fn alloc_self_profile_query_strings_for_query_cache<'tcx, C>(
+pub(crate) fn alloc_self_profile_query_strings_for_query_cache<'tcx, C>(
tcx: TyCtxt<'tcx>,
query_name: &'static str,
query_cache: &C,
@@ -298,27 +299,15 @@ fn alloc_self_profile_query_strings_for_query_cache<'tcx, C>(
/// If we are recording only summary data, the ids will point to
/// just the query names. If we are recording query keys too, we
/// allocate the corresponding strings here.
-pub fn alloc_self_profile_query_strings(tcx: TyCtxt<'_>) {
+pub fn alloc_self_profile_query_strings<'tcx>(tcx: TyCtxt<'tcx>) {
if !tcx.prof.enabled() {
return;
}
let mut string_cache = QueryKeyStringCache::new();
+ let queries = QueryCtxt::from_tcx(tcx);
- macro_rules! alloc_once {
- (
- $($(#[$attr:meta])*
- [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
- $(
- alloc_self_profile_query_strings_for_query_cache(
- tcx,
- stringify!($name),
- &tcx.query_caches.$name,
- &mut string_cache,
- );
- )+
- }
+ for query in &queries.queries.query_structs {
+ (query.alloc_self_profile_query_strings)(tcx, &mut string_cache);
}
-
- rustc_query_append! { alloc_once! }
}