1use std::ops::Deref;
23use rustc_data_structures::sync::{AtomicU64, WorkerLocal};
4use rustc_hir::def_id::{DefId, LocalDefId};
5use rustc_hir::hir_id::OwnerId;
6use rustc_macros::HashStable;
7use rustc_query_system::dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
8pub(crate) use rustc_query_system::query::QueryJobId;
9use rustc_query_system::query::{CycleError, CycleErrorHandling, HashResult, QueryCache};
10use rustc_span::{ErrorGuaranteed, Span};
11pub use sealed::IntoQueryParam;
1213use crate::dep_graph;
14use crate::dep_graph::DepKind;
15use crate::queries::{
16ExternProviders, PerQueryVTables, Providers, QueryArenas, QueryCaches, QueryEngine, QueryStates,
17};
18use crate::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex, OnDiskCache};
19use crate::ty::TyCtxt;
2021pub type WillCacheOnDiskForKeyFn<'tcx, Key> = fn(tcx: TyCtxt<'tcx>, key: &Key) -> bool;
2223pub type TryLoadFromDiskFn<'tcx, Key, Value> = fn(
24 tcx: TyCtxt<'tcx>,
25 key: &Key,
26 prev_index: SerializedDepNodeIndex,
27 index: DepNodeIndex,
28) -> Option<Value>;
2930pub type IsLoadableFromDiskFn<'tcx, Key> =
31fn(tcx: TyCtxt<'tcx>, key: &Key, index: SerializedDepNodeIndex) -> bool;
3233/// Stores function pointers and other metadata for a particular query.
34///
35/// Used indirectly by query plumbing in `rustc_query_system` via a trait,
36/// and also used directly by query plumbing in `rustc_query_impl`.
37pub struct QueryVTable<'tcx, C: QueryCache> {
38pub name: &'static str,
39pub eval_always: bool,
40pub dep_kind: DepKind,
41/// How this query deals with query cycle errors.
42pub cycle_error_handling: CycleErrorHandling,
43// Offset of this query's state field in the QueryStates struct
44pub query_state: usize,
45// Offset of this query's cache field in the QueryCaches struct
46pub query_cache: usize,
47pub will_cache_on_disk_for_key_fn: Option<WillCacheOnDiskForKeyFn<'tcx, C::Key>>,
48pub execute_query: fn(tcx: TyCtxt<'tcx>, k: C::Key) -> C::Value,
49pub compute_fn: fn(tcx: TyCtxt<'tcx>, key: C::Key) -> C::Value,
50pub try_load_from_disk_fn: Option<TryLoadFromDiskFn<'tcx, C::Key, C::Value>>,
51pub is_loadable_from_disk_fn: Option<IsLoadableFromDiskFn<'tcx, C::Key>>,
52pub hash_result: HashResult<C::Value>,
53pub value_from_cycle_error:
54fn(tcx: TyCtxt<'tcx>, cycle_error: &CycleError, guar: ErrorGuaranteed) -> C::Value,
55pub format_value: fn(&C::Value) -> String,
5657/// Formats a human-readable description of this query and its key, as
58 /// specified by the `desc` query modifier.
59 ///
60 /// Used when reporting query cycle errors and similar problems.
61pub description_fn: fn(TyCtxt<'tcx>, C::Key) -> String,
62}
6364pub struct QuerySystemFns {
65pub engine: QueryEngine,
66pub local_providers: Providers,
67pub extern_providers: ExternProviders,
68pub encode_query_results: for<'tcx> fn(
69 tcx: TyCtxt<'tcx>,
70 encoder: &mut CacheEncoder<'_, 'tcx>,
71 query_result_index: &mut EncodedDepNodeIndex,
72 ),
73pub try_mark_green: for<'tcx> fn(tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool,
74}
7576pub struct QuerySystem<'tcx> {
77pub states: QueryStates<'tcx>,
78pub arenas: WorkerLocal<QueryArenas<'tcx>>,
79pub caches: QueryCaches<'tcx>,
80pub query_vtables: PerQueryVTables<'tcx>,
8182/// This provides access to the incremental compilation on-disk cache for query results.
83 /// Do not access this directly. It is only meant to be used by
84 /// `DepGraph::try_mark_green()` and the query infrastructure.
85 /// This is `None` if we are not incremental compilation mode
86pub on_disk_cache: Option<OnDiskCache>,
8788pub fns: QuerySystemFns,
8990pub jobs: AtomicU64,
91}
9293#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for TyCtxtAt<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for TyCtxtAt<'tcx> {
#[inline]
fn clone(&self) -> TyCtxtAt<'tcx> {
let _: ::core::clone::AssertParamIsClone<TyCtxt<'tcx>>;
let _: ::core::clone::AssertParamIsClone<Span>;
*self
}
}Clone)]
94pub struct TyCtxtAt<'tcx> {
95pub tcx: TyCtxt<'tcx>,
96pub span: Span,
97}
9899impl<'tcx> Dereffor TyCtxtAt<'tcx> {
100type Target = TyCtxt<'tcx>;
101#[inline(always)]
102fn deref(&self) -> &Self::Target {
103&self.tcx
104 }
105}
106107#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for TyCtxtEnsureOk<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for TyCtxtEnsureOk<'tcx> {
#[inline]
fn clone(&self) -> TyCtxtEnsureOk<'tcx> {
let _: ::core::clone::AssertParamIsClone<TyCtxt<'tcx>>;
*self
}
}Clone)]
108#[must_use]
109pub struct TyCtxtEnsureOk<'tcx> {
110pub tcx: TyCtxt<'tcx>,
111}
112113#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for TyCtxtEnsureDone<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for TyCtxtEnsureDone<'tcx> {
#[inline]
fn clone(&self) -> TyCtxtEnsureDone<'tcx> {
let _: ::core::clone::AssertParamIsClone<TyCtxt<'tcx>>;
*self
}
}Clone)]
114#[must_use]
115pub struct TyCtxtEnsureDone<'tcx> {
116pub tcx: TyCtxt<'tcx>,
117}
118119impl<'tcx> TyCtxt<'tcx> {
120/// Wrapper that calls queries in a special "ensure OK" mode, for callers
121 /// that don't need the return value and just want to invoke a query for
122 /// its potential side-effect of emitting fatal errors.
123 ///
124 /// This can be more efficient than a normal query call, because if the
125 /// query's inputs are all green, the call can return immediately without
126 /// needing to obtain a value (by decoding one from disk or by executing
127 /// the query).
128 ///
129 /// (As with all query calls, execution is also skipped if the query result
130 /// is already cached in memory.)
131 ///
132 /// ## WARNING
133 /// A subsequent normal call to the same query might still cause it to be
134 /// executed! This can occur when the inputs are all green, but the query's
135 /// result is not cached on disk, so the query must be executed to obtain a
136 /// return value.
137 ///
138 /// Therefore, this call mode is not appropriate for callers that want to
139 /// ensure that the query is _never_ executed in the future.
140 ///
141 /// ## `return_result_from_ensure_ok`
142 /// If a query has the `return_result_from_ensure_ok` modifier, calls via
143 /// `ensure_ok` will instead return `Result<(), ErrorGuaranteed>`. If the
144 /// query needs to be executed, and execution returns an error, that error
145 /// is returned to the caller.
146#[inline(always)]
147pub fn ensure_ok(self) -> TyCtxtEnsureOk<'tcx> {
148TyCtxtEnsureOk { tcx: self }
149 }
150151/// Wrapper that calls queries in a special "ensure done" mode, for callers
152 /// that don't need the return value and just want to guarantee that the
153 /// query won't be executed in the future, by executing it now if necessary.
154 ///
155 /// This is useful for queries that read from a [`Steal`] value, to ensure
156 /// that they are executed before the query that will steal the value.
157 ///
158 /// Unlike [`Self::ensure_ok`], a query with all-green inputs will only be
159 /// skipped if its return value is stored in the disk-cache. This is still
160 /// more efficient than a regular query, because in that situation the
161 /// return value doesn't necessarily need to be decoded.
162 ///
163 /// (As with all query calls, execution is also skipped if the query result
164 /// is already cached in memory.)
165 ///
166 /// [`Steal`]: rustc_data_structures::steal::Steal
167#[inline(always)]
168pub fn ensure_done(self) -> TyCtxtEnsureDone<'tcx> {
169TyCtxtEnsureDone { tcx: self }
170 }
171172/// Returns a transparent wrapper for `TyCtxt` which uses
173 /// `span` as the location of queries performed through it.
174#[inline(always)]
175pub fn at(self, span: Span) -> TyCtxtAt<'tcx> {
176TyCtxtAt { tcx: self, span }
177 }
178179pub fn try_mark_green(self, dep_node: &dep_graph::DepNode) -> bool {
180 (self.query_system.fns.try_mark_green)(self, dep_node)
181 }
182}
183184/// Calls either `query_ensure` or `query_ensure_error_guaranteed`, depending
185/// on whether the list of modifiers contains `return_result_from_ensure_ok`.
186macro_rules!query_ensure_select {
187 ([]$($args:tt)*) => {
188crate::query::inner::query_ensure($($args)*)
189 };
190 ([(return_result_from_ensure_ok) $($rest:tt)*]$($args:tt)*) => {
191crate::query::inner::query_ensure_error_guaranteed($($args)*)
192 };
193 ([$other:tt $($modifiers:tt)*]$($args:tt)*) => {
194query_ensure_select!([$($modifiers)*]$($args)*)
195 };
196}
197198macro_rules!query_helper_param_ty {
199 (DefId) => { impl $crate::query::IntoQueryParam<DefId> };
200 (LocalDefId) => { impl $crate::query::IntoQueryParam<LocalDefId> };
201 ($K:ty) => { $K };
202}
203204macro_rules!query_if_arena {
205 ([] $arena:tt $no_arena:tt) => {
206$no_arena
207};
208 ([(arena_cache) $($rest:tt)*] $arena:tt $no_arena:tt) => {
209$arena
210};
211 ([$other:tt $($modifiers:tt)*]$($args:tt)*) => {
212query_if_arena!([$($modifiers)*]$($args)*)
213 };
214}
215216/// If `separate_provide_extern`, then the key can be projected to its
217/// local key via `<$K as AsLocalKey>::LocalKey`.
218macro_rules!local_key_if_separate_extern {
219 ([] $($K:tt)*) => {
220 $($K)*
221 };
222 ([(separate_provide_extern) $($rest:tt)*] $($K:tt)*) => {
223 <$($K)* as $crate::query::AsLocalKey>::LocalKey224 };
225 ([$other:tt $($modifiers:tt)*] $($K:tt)*) => {
226local_key_if_separate_extern!([$($modifiers)*] $($K)*)
227 };
228}
229230macro_rules!separate_provide_extern_decl {
231 ([][$name:ident]) => {
232 ()
233 };
234 ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
235for<'tcx> fn(
236TyCtxt<'tcx>,
237$name::Key<'tcx>,
238 ) -> $name::ProvidedValue<'tcx>
239 };
240 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
241separate_provide_extern_decl!([$($modifiers)*][$($args)*])
242 };
243}
244245macro_rules!ensure_ok_result {
246 ( [] ) => {
247 ()
248 };
249 ( [(return_result_from_ensure_ok) $($rest:tt)*] ) => {
250Result<(), ErrorGuaranteed>
251 };
252 ( [$other:tt $($modifiers:tt)*] ) => {
253ensure_ok_result!( [$($modifiers)*] )
254 };
255}
256257macro_rules!separate_provide_extern_default {
258 ([][$name:ident]) => {
259 ()
260 };
261 ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
262 |_, key| $crate::query::plumbing::default_extern_query(stringify!($name), &key)
263 };
264 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
265separate_provide_extern_default!([$($modifiers)*][$($args)*])
266 };
267}
268269macro_rules!define_callbacks {
270 (
271 $(
272 $(#[$attr:meta])*
273 [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,
274 )*
275 ) => {
276 $(#[allow(unused_lifetimes)] pub mod $name {
277use super::*;
278use $crate::query::erase::{self, Erased};
279280pub type Key<'tcx> = $($K)*;
281pub type Value<'tcx> = $V;
282283pub type LocalKey<'tcx> = local_key_if_separate_extern!([$($modifiers)*] $($K)*);
284285/// This type alias specifies the type returned from query providers and the type
286 /// used for decoding. For regular queries this is the declared returned type `V`,
287 /// but `arena_cache` will use `<V as ArenaCached>::Provided` instead.
288pub type ProvidedValue<'tcx> = query_if_arena!(
289 [$($modifiers)*]
290 (<$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Provided)
291 ($V)
292 );
293294/// This function takes `ProvidedValue` and converts it to an erased `Value` by
295 /// allocating it on an arena if the query has the `arena_cache` modifier. The
296 /// value is then erased and returned. This will happen when computing the query
297 /// using a provider or decoding a stored result.
298#[inline(always)]
299pub fn provided_to_erased<'tcx>(
300 _tcx: TyCtxt<'tcx>,
301 provided_value: ProvidedValue<'tcx>,
302 ) -> Erased<Value<'tcx>> {
303// Store the provided value in an arena and get a reference
304 // to it, for queries with `arena_cache`.
305let value: Value<'tcx> = query_if_arena!([$($modifiers)*]
306 {
307use $crate::query::arena_cached::ArenaCached;
308309if mem::needs_drop::<<$V as ArenaCached<'tcx>>::Allocated>() {
310 <$V as ArenaCached>::alloc_in_arena(
311 |v| _tcx.query_system.arenas.$name.alloc(v),
312 provided_value,
313 )
314 } else {
315 <$V as ArenaCached>::alloc_in_arena(
316 |v| _tcx.arena.dropless.alloc(v),
317 provided_value,
318 )
319 }
320 }
321// Otherwise, the provided value is the value.
322(provided_value)
323 );
324 erase::erase_val(value)
325 }
326327pub type Storage<'tcx> = <$($K)* as $crate::query::Key>::Cache<Erased<$V>>;
328329// Ensure that keys grow no larger than 88 bytes by accident.
330 // Increase this limit if necessary, but do try to keep the size low if possible
331#[cfg(target_pointer_width = "64")]
332const _: () = {
333if size_of::<Key<'static>>() > 88 {
334panic!("{}", concat!(
335"the query `",
336stringify!($name),
337"` has a key type `",
338stringify!($($K)*),
339"` that is too large"
340));
341 }
342 };
343344// Ensure that values grow no larger than 64 bytes by accident.
345 // Increase this limit if necessary, but do try to keep the size low if possible
346#[cfg(target_pointer_width = "64")]
347 #[cfg(not(feature = "rustc_randomized_layouts"))]
348const _: () = {
349if size_of::<Value<'static>>() > 64 {
350panic!("{}", concat!(
351"the query `",
352stringify!($name),
353"` has a value type `",
354stringify!($V),
355"` that is too large"
356));
357 }
358 };
359 })*
360361/// Holds per-query arenas for queries with the `arena_cache` modifier.
362#[derive(Default)]
363pub struct QueryArenas<'tcx> {
364 $(
365 $(#[$attr])*
366pub $name: query_if_arena!([$($modifiers)*]
367// Use the `ArenaCached` helper trait to determine the arena's value type.
368(TypedArena<<$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Allocated>)
369// No arena for this query, so the field type is `()`.
370()
371 ),
372 )*
373 }
374375#[derive(Default)]
376pub struct QueryCaches<'tcx> {
377 $($(#[$attr])* pub $name: $name::Storage<'tcx>,)*
378 }
379380impl<'tcx> $crate::query::TyCtxtEnsureOk<'tcx> {
381 $($(#[$attr])*
382#[inline(always)]
383pub fn $name(
384self,
385 key: query_helper_param_ty!($($K)*),
386 ) -> ensure_ok_result!([$($modifiers)*]) {
387query_ensure_select!(
388 [$($modifiers)*]
389self.tcx,
390self.tcx.query_system.fns.engine.$name,
391&self.tcx.query_system.caches.$name,
392$crate::query::IntoQueryParam::into_query_param(key),
393false,
394 )
395 })*
396 }
397398impl<'tcx> $crate::query::TyCtxtEnsureDone<'tcx> {
399 $($(#[$attr])*
400#[inline(always)]
401pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
402crate::query::inner::query_ensure(
403self.tcx,
404self.tcx.query_system.fns.engine.$name,
405&self.tcx.query_system.caches.$name,
406$crate::query::IntoQueryParam::into_query_param(key),
407true,
408 );
409 })*
410 }
411412impl<'tcx> TyCtxt<'tcx> {
413 $($(#[$attr])*
414#[inline(always)]
415 #[must_use]
416pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V
417{
418self.at(DUMMY_SP).$name(key)
419 })*
420 }
421422impl<'tcx> $crate::query::TyCtxtAt<'tcx> {
423 $($(#[$attr])*
424#[inline(always)]
425pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V
426{
427use $crate::query::{erase, inner};
428429 erase::restore_val::<$V>(inner::query_get_at(
430self.tcx,
431self.tcx.query_system.fns.engine.$name,
432&self.tcx.query_system.caches.$name,
433self.span,
434$crate::query::IntoQueryParam::into_query_param(key),
435 ))
436 })*
437 }
438439/// Holds a `QueryVTable` for each query.
440 ///
441 /// ("Per" just makes this pluralized name more visually distinct.)
442pub struct PerQueryVTables<'tcx> {
443 $(
444pub $name: ::rustc_middle::query::plumbing::QueryVTable<'tcx, $name::Storage<'tcx>>,
445 )*
446 }
447448#[derive(Default)]
449pub struct QueryStates<'tcx> {
450 $(
451pub $name: $crate::query::QueryState<'tcx, $($K)*>,
452 )*
453 }
454455pub struct Providers {
456 $(pub $name: for<'tcx> fn(
457TyCtxt<'tcx>,
458$name::LocalKey<'tcx>,
459 ) -> $name::ProvidedValue<'tcx>,)*
460 }
461462pub struct ExternProviders {
463 $(pub $name: separate_provide_extern_decl!([$($modifiers)*][$name]),)*
464 }
465466impl Default for Providers {
467fn default() -> Self {
468 Providers {
469 $($name: |_, key| $crate::query::plumbing::default_query(stringify!($name), &key)),*
470 }
471 }
472 }
473474impl Default for ExternProviders {
475fn default() -> Self {
476 ExternProviders {
477 $($name: separate_provide_extern_default!([$($modifiers)*][$name]),)*
478 }
479 }
480 }
481482impl Copy for Providers {}
483impl Clone for Providers {
484fn clone(&self) -> Self { *self }
485 }
486487impl Copy for ExternProviders {}
488impl Clone for ExternProviders {
489fn clone(&self) -> Self { *self }
490 }
491492pub struct QueryEngine {
493 $(pub $name: for<'tcx> fn(
494TyCtxt<'tcx>,
495Span,
496$name::Key<'tcx>,
497$crate::query::QueryMode,
498 ) -> Option<$crate::query::erase::Erased<$V>>,)*
499 }
500 };
501}
502503macro_rules!define_feedable {
504 ($($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
505 $(impl<'tcx, K: $crate::query::IntoQueryParam<$($K)*> + Copy> TyCtxtFeed<'tcx, K> {
506 $(#[$attr])*
507#[inline(always)]
508pub fn $name(self, value: $name::ProvidedValue<'tcx>) {
509let key = self.key().into_query_param();
510511let tcx = self.tcx;
512let erased_value = $name::provided_to_erased(tcx, value);
513514let dep_kind: dep_graph::DepKind = dep_graph::dep_kinds::$name;
515516$crate::query::inner::query_feed(
517 tcx,
518 dep_kind,
519&tcx.query_system.query_vtables.$name,
520&tcx.query_system.caches.$name,
521 key,
522 erased_value,
523 );
524 }
525 })*
526 }
527}
528529// Each of these queries corresponds to a function pointer field in the
530// `Providers` struct for requesting a value of that type, and a method
531// on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
532// which memoizes and does dep-graph tracking, wrapping around the actual
533// `Providers` that the driver creates (using several `rustc_*` crates).
534//
535// The result type of each query must implement `Clone`, and additionally
536// `ty::query::values::Value`, which produces an appropriate placeholder
537// (error) value if the query resulted in a query cycle.
538// Queries marked with `cycle_fatal` do not need the latter implementation,
539// as they will raise an fatal error on query cycles instead.
540541mod sealed {
542use rustc_hir::def_id::{LocalModDefId, ModDefId};
543544use super::{DefId, LocalDefId, OwnerId};
545546/// An analogue of the `Into` trait that's intended only for query parameters.
547 ///
548 /// This exists to allow queries to accept either `DefId` or `LocalDefId` while requiring that the
549 /// user call `to_def_id` to convert between them everywhere else.
550pub trait IntoQueryParam<P> {
551fn into_query_param(self) -> P;
552 }
553554impl<P> IntoQueryParam<P> for P {
555#[inline(always)]
556fn into_query_param(self) -> P {
557self558 }
559 }
560561impl<'a, P: Copy> IntoQueryParam<P> for &'a P {
562#[inline(always)]
563fn into_query_param(self) -> P {
564*self565 }
566 }
567568impl IntoQueryParam<LocalDefId> for OwnerId {
569#[inline(always)]
570fn into_query_param(self) -> LocalDefId {
571self.def_id
572 }
573 }
574575impl IntoQueryParam<DefId> for LocalDefId {
576#[inline(always)]
577fn into_query_param(self) -> DefId {
578self.to_def_id()
579 }
580 }
581582impl IntoQueryParam<DefId> for OwnerId {
583#[inline(always)]
584fn into_query_param(self) -> DefId {
585self.to_def_id()
586 }
587 }
588589impl IntoQueryParam<DefId> for ModDefId {
590#[inline(always)]
591fn into_query_param(self) -> DefId {
592self.to_def_id()
593 }
594 }
595596impl IntoQueryParam<DefId> for LocalModDefId {
597#[inline(always)]
598fn into_query_param(self) -> DefId {
599self.to_def_id()
600 }
601 }
602603impl IntoQueryParam<LocalDefId> for LocalModDefId {
604#[inline(always)]
605fn into_query_param(self) -> LocalDefId {
606self.into()
607 }
608 }
609}
610611#[derive(#[automatically_derived]
impl ::core::marker::Copy for CyclePlaceholder { }Copy, #[automatically_derived]
impl ::core::clone::Clone for CyclePlaceholder {
#[inline]
fn clone(&self) -> CyclePlaceholder {
let _: ::core::clone::AssertParamIsClone<ErrorGuaranteed>;
*self
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for CyclePlaceholder {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"CyclePlaceholder", &&self.0)
}
}Debug, const _: () =
{
impl<'__ctx>
::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
for CyclePlaceholder {
#[inline]
fn hash_stable(&self,
__hcx:
&mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
match *self {
CyclePlaceholder(ref __binding_0) => {
{ __binding_0.hash_stable(__hcx, __hasher); }
}
}
}
}
};HashStable)]
612pub struct CyclePlaceholder(pub ErrorGuaranteed);
613614#[cold]
615pub(crate) fn default_query(name: &str, key: &dyn std::fmt::Debug) -> ! {
616crate::util::bug::bug_fmt(format_args!("`tcx.{0}({1:?})` is not supported for this key;\nhint: Queries can be either made to the local crate, or the external crate. This error means you tried to use it for one that\'s not supported.\nIf that\'s not the case, {0} was likely never assigned to a provider function.\n",
name, key))bug!(
617"`tcx.{name}({key:?})` is not supported for this key;\n\
618 hint: Queries can be either made to the local crate, or the external crate. \
619 This error means you tried to use it for one that's not supported.\n\
620 If that's not the case, {name} was likely never assigned to a provider function.\n",
621 )622}
623624#[cold]
625pub(crate) fn default_extern_query(name: &str, key: &dyn std::fmt::Debug) -> ! {
626crate::util::bug::bug_fmt(format_args!("`tcx.{0}({1:?})` unsupported by its crate; perhaps the `{0}` query was never assigned a provider function",
name, key))bug!(
627"`tcx.{name}({key:?})` unsupported by its crate; \
628 perhaps the `{name}` query was never assigned a provider function",
629 )630}