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::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex, OnDiskCache};
16use crate::query::{
17ExternProviders, PerQueryVTables, Providers, QueryArenas, QueryCaches, QueryEngine, QueryStates,
18};
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.
36pub struct QueryVTable<'tcx, C: QueryCache> {
37pub name: &'static str,
38pub eval_always: bool,
39pub dep_kind: DepKind,
40/// How this query deals with query cycle errors.
41pub cycle_error_handling: CycleErrorHandling,
42// Offset of this query's state field in the QueryStates struct
43pub query_state: usize,
44// Offset of this query's cache field in the QueryCaches struct
45pub query_cache: usize,
46pub will_cache_on_disk_for_key_fn: Option<WillCacheOnDiskForKeyFn<'tcx, C::Key>>,
47pub execute_query: fn(tcx: TyCtxt<'tcx>, k: C::Key) -> C::Value,
48pub compute: fn(tcx: TyCtxt<'tcx>, key: C::Key) -> C::Value,
49pub try_load_from_disk_fn: Option<TryLoadFromDiskFn<'tcx, C::Key, C::Value>>,
50pub is_loadable_from_disk_fn: Option<IsLoadableFromDiskFn<'tcx, C::Key>>,
51pub hash_result: HashResult<C::Value>,
52pub value_from_cycle_error:
53fn(tcx: TyCtxt<'tcx>, cycle_error: &CycleError, guar: ErrorGuaranteed) -> C::Value,
54pub format_value: fn(&C::Value) -> String,
55}
5657pub struct QuerySystemFns {
58pub engine: QueryEngine,
59pub local_providers: Providers,
60pub extern_providers: ExternProviders,
61pub encode_query_results: for<'tcx> fn(
62 tcx: TyCtxt<'tcx>,
63 encoder: &mut CacheEncoder<'_, 'tcx>,
64 query_result_index: &mut EncodedDepNodeIndex,
65 ),
66pub try_mark_green: for<'tcx> fn(tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool,
67}
6869pub struct QuerySystem<'tcx> {
70pub states: QueryStates<'tcx>,
71pub arenas: WorkerLocal<QueryArenas<'tcx>>,
72pub caches: QueryCaches<'tcx>,
73pub query_vtables: PerQueryVTables<'tcx>,
7475/// This provides access to the incremental compilation on-disk cache for query results.
76 /// Do not access this directly. It is only meant to be used by
77 /// `DepGraph::try_mark_green()` and the query infrastructure.
78 /// This is `None` if we are not incremental compilation mode
79pub on_disk_cache: Option<OnDiskCache>,
8081pub fns: QuerySystemFns,
8283pub jobs: AtomicU64,
84}
8586#[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)]
87pub struct TyCtxtAt<'tcx> {
88pub tcx: TyCtxt<'tcx>,
89pub span: Span,
90}
9192impl<'tcx> Dereffor TyCtxtAt<'tcx> {
93type Target = TyCtxt<'tcx>;
94#[inline(always)]
95fn deref(&self) -> &Self::Target {
96&self.tcx
97 }
98}
99100#[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)]
101#[must_use]
102pub struct TyCtxtEnsureOk<'tcx> {
103pub tcx: TyCtxt<'tcx>,
104}
105106#[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)]
107#[must_use]
108pub struct TyCtxtEnsureDone<'tcx> {
109pub tcx: TyCtxt<'tcx>,
110}
111112impl<'tcx> TyCtxt<'tcx> {
113/// Wrapper that calls queries in a special "ensure OK" mode, for callers
114 /// that don't need the return value and just want to invoke a query for
115 /// its potential side-effect of emitting fatal errors.
116 ///
117 /// This can be more efficient than a normal query call, because if the
118 /// query's inputs are all green, the call can return immediately without
119 /// needing to obtain a value (by decoding one from disk or by executing
120 /// the query).
121 ///
122 /// (As with all query calls, execution is also skipped if the query result
123 /// is already cached in memory.)
124 ///
125 /// ## WARNING
126 /// A subsequent normal call to the same query might still cause it to be
127 /// executed! This can occur when the inputs are all green, but the query's
128 /// result is not cached on disk, so the query must be executed to obtain a
129 /// return value.
130 ///
131 /// Therefore, this call mode is not appropriate for callers that want to
132 /// ensure that the query is _never_ executed in the future.
133 ///
134 /// ## `return_result_from_ensure_ok`
135 /// If a query has the `return_result_from_ensure_ok` modifier, calls via
136 /// `ensure_ok` will instead return `Result<(), ErrorGuaranteed>`. If the
137 /// query needs to be executed, and execution returns an error, that error
138 /// is returned to the caller.
139#[inline(always)]
140pub fn ensure_ok(self) -> TyCtxtEnsureOk<'tcx> {
141TyCtxtEnsureOk { tcx: self }
142 }
143144/// Wrapper that calls queries in a special "ensure done" mode, for callers
145 /// that don't need the return value and just want to guarantee that the
146 /// query won't be executed in the future, by executing it now if necessary.
147 ///
148 /// This is useful for queries that read from a [`Steal`] value, to ensure
149 /// that they are executed before the query that will steal the value.
150 ///
151 /// Unlike [`Self::ensure_ok`], a query with all-green inputs will only be
152 /// skipped if its return value is stored in the disk-cache. This is still
153 /// more efficient than a regular query, because in that situation the
154 /// return value doesn't necessarily need to be decoded.
155 ///
156 /// (As with all query calls, execution is also skipped if the query result
157 /// is already cached in memory.)
158 ///
159 /// [`Steal`]: rustc_data_structures::steal::Steal
160#[inline(always)]
161pub fn ensure_done(self) -> TyCtxtEnsureDone<'tcx> {
162TyCtxtEnsureDone { tcx: self }
163 }
164165/// Returns a transparent wrapper for `TyCtxt` which uses
166 /// `span` as the location of queries performed through it.
167#[inline(always)]
168pub fn at(self, span: Span) -> TyCtxtAt<'tcx> {
169TyCtxtAt { tcx: self, span }
170 }
171172pub fn try_mark_green(self, dep_node: &dep_graph::DepNode) -> bool {
173 (self.query_system.fns.try_mark_green)(self, dep_node)
174 }
175}
176177/// Calls either `query_ensure` or `query_ensure_error_guaranteed`, depending
178/// on whether the list of modifiers contains `return_result_from_ensure_ok`.
179macro_rules!query_ensure_select {
180 ([]$($args:tt)*) => {
181crate::query::inner::query_ensure($($args)*)
182 };
183 ([(return_result_from_ensure_ok) $($rest:tt)*]$($args:tt)*) => {
184crate::query::inner::query_ensure_error_guaranteed($($args)*)
185 };
186 ([$other:tt $($modifiers:tt)*]$($args:tt)*) => {
187query_ensure_select!([$($modifiers)*]$($args)*)
188 };
189}
190191macro_rules!query_helper_param_ty {
192 (DefId) => { impl IntoQueryParam<DefId> };
193 (LocalDefId) => { impl IntoQueryParam<LocalDefId> };
194 ($K:ty) => { $K };
195}
196197macro_rules!query_if_arena {
198 ([] $arena:tt $no_arena:tt) => {
199$no_arena
200};
201 ([(arena_cache) $($rest:tt)*] $arena:tt $no_arena:tt) => {
202$arena
203};
204 ([$other:tt $($modifiers:tt)*]$($args:tt)*) => {
205query_if_arena!([$($modifiers)*]$($args)*)
206 };
207}
208209/// If `separate_provide_extern`, then the key can be projected to its
210/// local key via `<$K as AsLocalKey>::LocalKey`.
211macro_rules!local_key_if_separate_extern {
212 ([] $($K:tt)*) => {
213 $($K)*
214 };
215 ([(separate_provide_extern) $($rest:tt)*] $($K:tt)*) => {
216 <$($K)* as AsLocalKey>::LocalKey217 };
218 ([$other:tt $($modifiers:tt)*] $($K:tt)*) => {
219local_key_if_separate_extern!([$($modifiers)*] $($K)*)
220 };
221}
222223macro_rules!separate_provide_extern_decl {
224 ([][$name:ident]) => {
225 ()
226 };
227 ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
228for<'tcx> fn(
229TyCtxt<'tcx>,
230 queries::$name::Key<'tcx>,
231 ) -> queries::$name::ProvidedValue<'tcx>
232 };
233 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
234separate_provide_extern_decl!([$($modifiers)*][$($args)*])
235 };
236}
237238macro_rules!ensure_ok_result {
239 ( [] ) => {
240 ()
241 };
242 ( [(return_result_from_ensure_ok) $($rest:tt)*] ) => {
243Result<(), ErrorGuaranteed>
244 };
245 ( [$other:tt $($modifiers:tt)*] ) => {
246ensure_ok_result!( [$($modifiers)*] )
247 };
248}
249250macro_rules!separate_provide_extern_default {
251 ([][$name:ident]) => {
252 ()
253 };
254 ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
255 |_, key| $crate::query::plumbing::default_extern_query(stringify!($name), &key)
256 };
257 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
258separate_provide_extern_default!([$($modifiers)*][$($args)*])
259 };
260}
261262macro_rules!define_callbacks {
263 (
264 $(
265 $(#[$attr:meta])*
266 [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,
267 )*
268 ) => {
269270#[allow(unused_lifetimes)]
271pub mod queries {
272 $(pub mod $name {
273use super::super::*;
274use $crate::query::erase::{self, Erased};
275276pub type Key<'tcx> = $($K)*;
277pub type Value<'tcx> = $V;
278279pub type LocalKey<'tcx> = local_key_if_separate_extern!([$($modifiers)*] $($K)*);
280281/// This type alias specifies the type returned from query providers and the type
282 /// used for decoding. For regular queries this is the declared returned type `V`,
283 /// but `arena_cache` will use `<V as ArenaCached>::Provided` instead.
284pub type ProvidedValue<'tcx> = query_if_arena!(
285 [$($modifiers)*]
286 (<$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Provided)
287 ($V)
288 );
289290/// This function takes `ProvidedValue` and converts it to an erased `Value` by
291 /// allocating it on an arena if the query has the `arena_cache` modifier. The
292 /// value is then erased and returned. This will happen when computing the query
293 /// using a provider or decoding a stored result.
294#[inline(always)]
295pub fn provided_to_erased<'tcx>(
296 _tcx: TyCtxt<'tcx>,
297 provided_value: ProvidedValue<'tcx>,
298 ) -> Erased<Value<'tcx>> {
299// Store the provided value in an arena and get a reference
300 // to it, for queries with `arena_cache`.
301let value: Value<'tcx> = query_if_arena!([$($modifiers)*]
302 {
303use $crate::query::arena_cached::ArenaCached;
304305if mem::needs_drop::<<$V as ArenaCached<'tcx>>::Allocated>() {
306 <$V as ArenaCached>::alloc_in_arena(
307 |v| _tcx.query_system.arenas.$name.alloc(v),
308 provided_value,
309 )
310 } else {
311 <$V as ArenaCached>::alloc_in_arena(
312 |v| _tcx.arena.dropless.alloc(v),
313 provided_value,
314 )
315 }
316 }
317// Otherwise, the provided value is the value.
318(provided_value)
319 );
320 erase::erase_val(value)
321 }
322323pub type Storage<'tcx> = <$($K)* as keys::Key>::Cache<Erased<$V>>;
324325// Ensure that keys grow no larger than 88 bytes by accident.
326 // Increase this limit if necessary, but do try to keep the size low if possible
327#[cfg(target_pointer_width = "64")]
328const _: () = {
329if size_of::<Key<'static>>() > 88 {
330panic!("{}", concat!(
331"the query `",
332stringify!($name),
333"` has a key type `",
334stringify!($($K)*),
335"` that is too large"
336));
337 }
338 };
339340// Ensure that values grow no larger than 64 bytes by accident.
341 // Increase this limit if necessary, but do try to keep the size low if possible
342#[cfg(target_pointer_width = "64")]
343 #[cfg(not(feature = "rustc_randomized_layouts"))]
344const _: () = {
345if size_of::<Value<'static>>() > 64 {
346panic!("{}", concat!(
347"the query `",
348stringify!($name),
349"` has a value type `",
350stringify!($V),
351"` that is too large"
352));
353 }
354 };
355 })*
356 }
357358/// Holds per-query arenas for queries with the `arena_cache` modifier.
359#[derive(Default)]
360pub struct QueryArenas<'tcx> {
361 $(
362 $(#[$attr])*
363pub $name: query_if_arena!([$($modifiers)*]
364// Use the `ArenaCached` helper trait to determine the arena's value type.
365(TypedArena<<$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Allocated>)
366// No arena for this query, so the field type is `()`.
367()
368 ),
369 )*
370 }
371372#[derive(Default)]
373pub struct QueryCaches<'tcx> {
374 $($(#[$attr])* pub $name: queries::$name::Storage<'tcx>,)*
375 }
376377impl<'tcx> TyCtxtEnsureOk<'tcx> {
378 $($(#[$attr])*
379#[inline(always)]
380pub fn $name(
381self,
382 key: query_helper_param_ty!($($K)*),
383 ) -> ensure_ok_result!([$($modifiers)*]) {
384query_ensure_select!(
385 [$($modifiers)*]
386self.tcx,
387self.tcx.query_system.fns.engine.$name,
388&self.tcx.query_system.caches.$name,
389 key.into_query_param(),
390false,
391 )
392 })*
393 }
394395impl<'tcx> TyCtxtEnsureDone<'tcx> {
396 $($(#[$attr])*
397#[inline(always)]
398pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
399crate::query::inner::query_ensure(
400self.tcx,
401self.tcx.query_system.fns.engine.$name,
402&self.tcx.query_system.caches.$name,
403 key.into_query_param(),
404true,
405 );
406 })*
407 }
408409impl<'tcx> TyCtxt<'tcx> {
410 $($(#[$attr])*
411#[inline(always)]
412 #[must_use]
413pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V
414{
415self.at(DUMMY_SP).$name(key)
416 })*
417 }
418419impl<'tcx> TyCtxtAt<'tcx> {
420 $($(#[$attr])*
421#[inline(always)]
422pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V
423{
424use $crate::query::{erase, inner};
425426 erase::restore_val::<$V>(inner::query_get_at(
427self.tcx,
428self.tcx.query_system.fns.engine.$name,
429&self.tcx.query_system.caches.$name,
430self.span,
431 key.into_query_param(),
432 ))
433 })*
434 }
435436/// Holds a `QueryVTable` for each query.
437 ///
438 /// ("Per" just makes this pluralized name more visually distinct.)
439pub struct PerQueryVTables<'tcx> {
440 $(
441pub $name: ::rustc_middle::query::plumbing::QueryVTable<'tcx, queries::$name::Storage<'tcx>>,
442 )*
443 }
444445#[derive(Default)]
446pub struct QueryStates<'tcx> {
447 $(
448pub $name: QueryState<'tcx, $($K)*>,
449 )*
450 }
451452pub struct Providers {
453 $(pub $name: for<'tcx> fn(
454TyCtxt<'tcx>,
455 queries::$name::LocalKey<'tcx>,
456 ) -> queries::$name::ProvidedValue<'tcx>,)*
457 }
458459pub struct ExternProviders {
460 $(pub $name: separate_provide_extern_decl!([$($modifiers)*][$name]),)*
461 }
462463impl Default for Providers {
464fn default() -> Self {
465 Providers {
466 $($name: |_, key| $crate::query::plumbing::default_query(stringify!($name), &key)),*
467 }
468 }
469 }
470471impl Default for ExternProviders {
472fn default() -> Self {
473 ExternProviders {
474 $($name: separate_provide_extern_default!([$($modifiers)*][$name]),)*
475 }
476 }
477 }
478479impl Copy for Providers {}
480impl Clone for Providers {
481fn clone(&self) -> Self { *self }
482 }
483484impl Copy for ExternProviders {}
485impl Clone for ExternProviders {
486fn clone(&self) -> Self { *self }
487 }
488489pub struct QueryEngine {
490 $(pub $name: for<'tcx> fn(
491TyCtxt<'tcx>,
492Span,
493 queries::$name::Key<'tcx>,
494QueryMode,
495 ) -> Option<$crate::query::erase::Erased<$V>>,)*
496 }
497 };
498}
499500macro_rules!define_feedable {
501 ($($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
502 $(impl<'tcx, K: IntoQueryParam<$($K)*> + Copy> TyCtxtFeed<'tcx, K> {
503 $(#[$attr])*
504#[inline(always)]
505pub fn $name(self, value: queries::$name::ProvidedValue<'tcx>) {
506let key = self.key().into_query_param();
507508let tcx = self.tcx;
509let erased_value = queries::$name::provided_to_erased(tcx, value);
510511let dep_kind: dep_graph::DepKind = dep_graph::dep_kinds::$name;
512513$crate::query::inner::query_feed(
514 tcx,
515 dep_kind,
516&tcx.query_system.query_vtables.$name,
517&tcx.query_system.caches.$name,
518 key,
519 erased_value,
520 );
521 }
522 })*
523 }
524}
525526// Each of these queries corresponds to a function pointer field in the
527// `Providers` struct for requesting a value of that type, and a method
528// on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
529// which memoizes and does dep-graph tracking, wrapping around the actual
530// `Providers` that the driver creates (using several `rustc_*` crates).
531//
532// The result type of each query must implement `Clone`, and additionally
533// `ty::query::values::Value`, which produces an appropriate placeholder
534// (error) value if the query resulted in a query cycle.
535// Queries marked with `cycle_fatal` do not need the latter implementation,
536// as they will raise an fatal error on query cycles instead.
537538mod sealed {
539use rustc_hir::def_id::{LocalModDefId, ModDefId};
540541use super::{DefId, LocalDefId, OwnerId};
542543/// An analogue of the `Into` trait that's intended only for query parameters.
544 ///
545 /// This exists to allow queries to accept either `DefId` or `LocalDefId` while requiring that the
546 /// user call `to_def_id` to convert between them everywhere else.
547pub trait IntoQueryParam<P> {
548fn into_query_param(self) -> P;
549 }
550551impl<P> IntoQueryParam<P> for P {
552#[inline(always)]
553fn into_query_param(self) -> P {
554self555 }
556 }
557558impl<'a, P: Copy> IntoQueryParam<P> for &'a P {
559#[inline(always)]
560fn into_query_param(self) -> P {
561*self562 }
563 }
564565impl IntoQueryParam<LocalDefId> for OwnerId {
566#[inline(always)]
567fn into_query_param(self) -> LocalDefId {
568self.def_id
569 }
570 }
571572impl IntoQueryParam<DefId> for LocalDefId {
573#[inline(always)]
574fn into_query_param(self) -> DefId {
575self.to_def_id()
576 }
577 }
578579impl IntoQueryParam<DefId> for OwnerId {
580#[inline(always)]
581fn into_query_param(self) -> DefId {
582self.to_def_id()
583 }
584 }
585586impl IntoQueryParam<DefId> for ModDefId {
587#[inline(always)]
588fn into_query_param(self) -> DefId {
589self.to_def_id()
590 }
591 }
592593impl IntoQueryParam<DefId> for LocalModDefId {
594#[inline(always)]
595fn into_query_param(self) -> DefId {
596self.to_def_id()
597 }
598 }
599600impl IntoQueryParam<LocalDefId> for LocalModDefId {
601#[inline(always)]
602fn into_query_param(self) -> LocalDefId {
603self.into()
604 }
605 }
606}
607608#[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)]
609pub struct CyclePlaceholder(pub ErrorGuaranteed);
610611#[cold]
612pub(crate) fn default_query(name: &str, key: &dyn std::fmt::Debug) -> ! {
613crate::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!(
614"`tcx.{name}({key:?})` is not supported for this key;\n\
615 hint: Queries can be either made to the local crate, or the external crate. \
616 This error means you tried to use it for one that's not supported.\n\
617 If that's not the case, {name} was likely never assigned to a provider function.\n",
618 )619}
620621#[cold]
622pub(crate) fn default_extern_query(name: &str, key: &dyn std::fmt::Debug) -> ! {
623crate::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!(
624"`tcx.{name}({key:?})` unsupported by its crate; \
625 perhaps the `{name}` query was never assigned a provider function",
626 )627}