1use std::fmt;
2use std::ops::Deref;
34use rustc_data_structures::fingerprint::Fingerprint;
5use rustc_data_structures::hash_table::HashTable;
6use rustc_data_structures::sharded::Sharded;
7use rustc_data_structures::sync::{AtomicU64, WorkerLocal};
8use rustc_errors::Diag;
9use rustc_span::Span;
1011use crate::dep_graph::{DepKind, DepNodeIndex, SerializedDepNodeIndex};
12use crate::ich::StableHashingContext;
13use crate::queries::{ExternProviders, Providers, QueryArenas, QueryVTables, TaggedQueryKey};
14use crate::query::on_disk_cache::OnDiskCache;
15use crate::query::{QueryCache, QueryJob, QueryStackFrame};
16use crate::ty::TyCtxt;
1718/// For a particular query, keeps track of "active" keys, i.e. keys whose
19/// evaluation has started but has not yet finished successfully.
20///
21/// (Successful query evaluation for a key is represented by an entry in the
22/// query's in-memory cache.)
23pub struct QueryState<'tcx, K> {
24pub active: Sharded<HashTable<(K, ActiveKeyStatus<'tcx>)>>,
25}
2627impl<'tcx, K> Defaultfor QueryState<'tcx, K> {
28fn default() -> QueryState<'tcx, K> {
29QueryState { active: Default::default() }
30 }
31}
3233/// For a particular query and key, tracks the status of a query evaluation
34/// that has started, but has not yet finished successfully.
35///
36/// (Successful query evaluation for a key is represented by an entry in the
37/// query's in-memory cache.)
38pub enum ActiveKeyStatus<'tcx> {
39/// Some thread is already evaluating the query for this key.
40 ///
41 /// The enclosed [`QueryJob`] can be used to wait for it to finish.
42Started(QueryJob<'tcx>),
4344/// The query panicked. Queries trying to wait on this will raise a fatal error which will
45 /// silently panic.
46Poisoned,
47}
4849#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for CycleError<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f, "CycleError",
"usage", &self.usage, "cycle", &&self.cycle)
}
}Debug)]
50pub struct CycleError<'tcx> {
51/// The query and related span that uses the cycle.
52pub usage: Option<QueryStackFrame<'tcx>>,
5354/// The span here corresponds to the reason for which this query was required.
55pub cycle: Vec<QueryStackFrame<'tcx>>,
56}
5758#[derive(#[automatically_derived]
impl ::core::fmt::Debug for QueryMode {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
QueryMode::Get => ::core::fmt::Formatter::write_str(f, "Get"),
QueryMode::Ensure { ensure_mode: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"Ensure", "ensure_mode", &__self_0),
}
}
}Debug)]
59pub enum QueryMode {
60/// This is a normal query call to `tcx.$query(..)` or `tcx.at(span).$query(..)`.
61Get,
62/// This is a call to `tcx.ensure_ok().$query(..)` or `tcx.ensure_done().$query(..)`.
63Ensure { ensure_mode: EnsureMode },
64}
6566/// Distinguishes between `tcx.ensure_ok()` and `tcx.ensure_done()` in shared
67/// code paths that handle both modes.
68#[derive(#[automatically_derived]
impl ::core::fmt::Debug for EnsureMode {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
EnsureMode::Ok => "Ok",
EnsureMode::Done => "Done",
})
}
}Debug)]
69pub enum EnsureMode {
70/// Corresponds to [`TyCtxt::ensure_ok`].
71Ok,
72/// Corresponds to [`TyCtxt::ensure_done`].
73Done,
74}
7576/// Stores data and metadata (e.g. function pointers) for a particular query.
77pub struct QueryVTable<'tcx, C: QueryCache> {
78pub name: &'static str,
7980/// True if this query has the `anon` modifier.
81pub anon: bool,
82/// True if this query has the `eval_always` modifier.
83pub eval_always: bool,
84/// True if this query has the `depth_limit` modifier.
85pub depth_limit: bool,
86/// True if this query has the `feedable` modifier.
87pub feedable: bool,
8889pub dep_kind: DepKind,
90pub state: QueryState<'tcx, C::Key>,
91pub cache: C,
9293/// Function pointer that actually calls this query's provider.
94 /// Also performs some associated secondary tasks; see the macro-defined
95 /// implementation in `mod invoke_provider_fn` for more details.
96 ///
97 /// This should be the only code that calls the provider function.
98pub invoke_provider_fn: fn(tcx: TyCtxt<'tcx>, key: C::Key) -> C::Value,
99100pub will_cache_on_disk_for_key_fn: fn(tcx: TyCtxt<'tcx>, key: C::Key) -> bool,
101102pub try_load_from_disk_fn: fn(
103 tcx: TyCtxt<'tcx>,
104 key: C::Key,
105 prev_index: SerializedDepNodeIndex,
106 index: DepNodeIndex,
107 ) -> Option<C::Value>,
108109pub is_loadable_from_disk_fn:
110fn(tcx: TyCtxt<'tcx>, key: C::Key, index: SerializedDepNodeIndex) -> bool,
111112/// Function pointer that hashes this query's result values.
113 ///
114 /// For `no_hash` queries, this function pointer is None.
115pub hash_value_fn: Option<fn(&mut StableHashingContext<'_>, &C::Value) -> Fingerprint>,
116117/// Function pointer that handles a cycle error. `error` must be consumed, e.g. with `emit` (if
118 /// it should be emitted) or `delay_as_bug` (if it need not be emitted because an alternative
119 /// error is created and emitted).
120pub value_from_cycle_error: fn(
121 tcx: TyCtxt<'tcx>,
122 key: C::Key,
123 cycle_error: CycleError<'tcx>,
124 error: Diag<'_>,
125 ) -> C::Value,
126127pub format_value: fn(&C::Value) -> String,
128129pub create_tagged_key: fn(C::Key) -> TaggedQueryKey<'tcx>,
130131/// Function pointer that is called by the query methods on [`TyCtxt`] and
132 /// friends[^1], after they have checked the in-memory cache and found no
133 /// existing value for this key.
134 ///
135 /// Transitive responsibilities include trying to load a disk-cached value
136 /// if possible (incremental only), invoking the query provider if necessary,
137 /// and putting the obtained value into the in-memory cache.
138 ///
139 /// [^1]: [`TyCtxt`], [`TyCtxtAt`], [`TyCtxtEnsureOk`], [`TyCtxtEnsureDone`]
140pub execute_query_fn: fn(TyCtxt<'tcx>, Span, C::Key, QueryMode) -> Option<C::Value>,
141}
142143impl<'tcx, C: QueryCache> fmt::Debugfor QueryVTable<'tcx, C> {
144fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
145// When debug-printing a query vtable (e.g. for ICE or tracing),
146 // just print the query name to know what query we're dealing with.
147 // The other fields and flags are probably just unhelpful noise.
148 //
149 // If there is need for a more detailed dump of all flags and fields,
150 // consider writing a separate dump method and calling it explicitly.
151f.write_str(self.name)
152 }
153}
154155pub struct QuerySystem<'tcx> {
156pub arenas: WorkerLocal<QueryArenas<'tcx>>,
157pub query_vtables: QueryVTables<'tcx>,
158159/// This provides access to the incremental compilation on-disk cache for query results.
160 /// Do not access this directly. It is only meant to be used by
161 /// `DepGraph::try_mark_green()` and the query infrastructure.
162 /// This is `None` if we are not incremental compilation mode
163pub on_disk_cache: Option<OnDiskCache>,
164165pub local_providers: Providers,
166pub extern_providers: ExternProviders,
167168pub jobs: AtomicU64,
169}
170171#[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)]
172pub struct TyCtxtAt<'tcx> {
173pub tcx: TyCtxt<'tcx>,
174pub span: Span,
175}
176177impl<'tcx> Dereffor TyCtxtAt<'tcx> {
178type Target = TyCtxt<'tcx>;
179#[inline(always)]
180fn deref(&self) -> &Self::Target {
181&self.tcx
182 }
183}
184185#[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)]
186#[must_use]
187pub struct TyCtxtEnsureOk<'tcx> {
188pub tcx: TyCtxt<'tcx>,
189}
190191#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for TyCtxtEnsureResult<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for TyCtxtEnsureResult<'tcx> {
#[inline]
fn clone(&self) -> TyCtxtEnsureResult<'tcx> {
let _: ::core::clone::AssertParamIsClone<TyCtxt<'tcx>>;
*self
}
}Clone)]
192#[must_use]
193pub struct TyCtxtEnsureResult<'tcx> {
194pub tcx: TyCtxt<'tcx>,
195}
196197#[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)]
198#[must_use]
199pub struct TyCtxtEnsureDone<'tcx> {
200pub tcx: TyCtxt<'tcx>,
201}
202203impl<'tcx> TyCtxt<'tcx> {
204/// FIXME: `ensure_ok`'s effects are subtle. Is this comment fully accurate?
205 ///
206 /// Wrapper that calls queries in a special "ensure OK" mode, for callers
207 /// that don't need the return value and just want to invoke a query for
208 /// its potential side-effect of emitting fatal errors.
209 ///
210 /// This can be more efficient than a normal query call, because if the
211 /// query's inputs are all green, the call can return immediately without
212 /// needing to obtain a value (by decoding one from disk or by executing
213 /// the query).
214 ///
215 /// (As with all query calls, execution is also skipped if the query result
216 /// is already cached in memory.)
217 ///
218 /// ## WARNING
219 /// A subsequent normal call to the same query might still cause it to be
220 /// executed! This can occur when the inputs are all green, but the query's
221 /// result is not cached on disk, so the query must be executed to obtain a
222 /// return value.
223 ///
224 /// Therefore, this call mode is not appropriate for callers that want to
225 /// ensure that the query is _never_ executed in the future.
226#[inline(always)]
227pub fn ensure_ok(self) -> TyCtxtEnsureOk<'tcx> {
228TyCtxtEnsureOk { tcx: self }
229 }
230231/// This is a variant of `ensure_ok` only usable with queries that return
232 /// `Result<_, ErrorGuaranteed>`. Queries calls through this function will
233 /// return `Result<(), ErrorGuaranteed>`. I.e. the error status is returned
234 /// but nothing else. As with `ensure_ok`, this can be more efficient than
235 /// a normal query call.
236#[inline(always)]
237pub fn ensure_result(self) -> TyCtxtEnsureResult<'tcx> {
238TyCtxtEnsureResult { tcx: self }
239 }
240241/// Wrapper that calls queries in a special "ensure done" mode, for callers
242 /// that don't need the return value and just want to guarantee that the
243 /// query won't be executed in the future, by executing it now if necessary.
244 ///
245 /// This is useful for queries that read from a [`Steal`] value, to ensure
246 /// that they are executed before the query that will steal the value.
247 ///
248 /// Unlike [`Self::ensure_ok`], a query with all-green inputs will only be
249 /// skipped if its return value is stored in the disk-cache. This is still
250 /// more efficient than a regular query, because in that situation the
251 /// return value doesn't necessarily need to be decoded.
252 ///
253 /// (As with all query calls, execution is also skipped if the query result
254 /// is already cached in memory.)
255 ///
256 /// [`Steal`]: rustc_data_structures::steal::Steal
257#[inline(always)]
258pub fn ensure_done(self) -> TyCtxtEnsureDone<'tcx> {
259TyCtxtEnsureDone { tcx: self }
260 }
261262/// Returns a transparent wrapper for `TyCtxt` which uses
263 /// `span` as the location of queries performed through it.
264#[inline(always)]
265pub fn at(self, span: Span) -> TyCtxtAt<'tcx> {
266TyCtxtAt { tcx: self, span }
267 }
268}
269270macro_rules!query_helper_param_ty {
271 (DefId) => { impl $crate::query::IntoQueryKey<DefId> };
272 (LocalDefId) => { impl $crate::query::IntoQueryKey<LocalDefId> };
273 ($K:ty) => { $K };
274}
275276macro_rules!define_callbacks {
277 (
278// You might expect the key to be `$K:ty`, but it needs to be `$($K:tt)*` so that
279 // `query_helper_param_ty!` can match on specific type names.
280queries {
281 $(
282 $(#[$attr:meta])*
283fn $name:ident($($K:tt)*) -> $V:ty
284 {
285// Search for (QMODLIST) to find all occurrences of this query modifier list.
286anon: $anon:literal,
287 arena_cache: $arena_cache:literal,
288 cache_on_disk: $cache_on_disk:literal,
289 depth_limit: $depth_limit:literal,
290 eval_always: $eval_always:literal,
291 feedable: $feedable:literal,
292 no_hash: $no_hash:literal,
293 returns_error_guaranteed: $returns_error_guaranteed:literal,
294 separate_provide_extern: $separate_provide_extern:literal,
295 }
296 )*
297 }
298// Non-queries are unused here.
299non_queries { $($_:tt)* }
300 ) => {
301 $(
302pub mod $name {
303use super::*;
304use $crate::query::erase::{self, Erased};
305306pub type Key<'tcx> = $($K)*;
307pub type Value<'tcx> = $V;
308309/// Key type used by provider functions in `local_providers`.
310 /// This query has the `separate_provide_extern` modifier.
311#[cfg($separate_provide_extern)]
312pub type LocalKey<'tcx> =
313 <Key<'tcx> as $crate::query::AsLocalQueryKey>::LocalQueryKey;
314/// Key type used by provider functions in `local_providers`.
315#[cfg(not($separate_provide_extern))]
316pub type LocalKey<'tcx> = Key<'tcx>;
317318/// Type returned from query providers and loaded from disk-cache.
319#[cfg($arena_cache)]
320pub type ProvidedValue<'tcx> =
321 <Value<'tcx> as $crate::query::arena_cached::ArenaCached<'tcx>>::Provided;
322/// Type returned from query providers and loaded from disk-cache.
323#[cfg(not($arena_cache))]
324pub type ProvidedValue<'tcx> = Value<'tcx>;
325326/// This helper function takes a value returned by the query provider
327 /// (or loaded from disk, or supplied by query feeding), allocates
328 /// it in an arena if requested by the `arena_cache` modifier, and
329 /// then returns an erased copy of it.
330#[inline(always)]
331pub fn provided_to_erased<'tcx>(
332 tcx: TyCtxt<'tcx>,
333 provided_value: ProvidedValue<'tcx>,
334 ) -> Erased<Value<'tcx>> {
335// For queries with the `arena_cache` modifier, store the
336 // provided value in an arena and get a reference to it.
337#[cfg($arena_cache)]
338let value: Value<'tcx> = {
339use $crate::query::arena_cached::ArenaCached;
340 <Value<'tcx> as ArenaCached>::alloc_in_arena(
341 tcx,
342&tcx.query_system.arenas.$name,
343 provided_value,
344 )
345 };
346347// Otherwise, the provided value is the value (and `tcx` is unused).
348#[cfg(not($arena_cache))]
349let value: Value<'tcx> = {
350let _ = tcx;
351 provided_value
352 };
353354 erase::erase_val(value)
355 }
356357pub type Cache<'tcx> =
358 <Key<'tcx> as $crate::query::QueryKey>::Cache<Erased<Value<'tcx>>>;
359360// Ensure that keys grow no larger than 88 bytes by accident.
361 // Increase this limit if necessary, but do try to keep the size low if possible
362#[cfg(target_pointer_width = "64")]
363const _: () = {
364if size_of::<Key<'static>>() > 88 {
365panic!("{}", concat!(
366"the query `",
367stringify!($name),
368"` has a key type `",
369stringify!($($K)*),
370"` that is too large"
371));
372 }
373 };
374375// Ensure that values grow no larger than 64 bytes by accident.
376 // Increase this limit if necessary, but do try to keep the size low if possible
377#[cfg(target_pointer_width = "64")]
378 #[cfg(not(feature = "rustc_randomized_layouts"))]
379const _: () = {
380if size_of::<Value<'static>>() > 64 {
381panic!("{}", concat!(
382"the query `",
383stringify!($name),
384"` has a value type `",
385stringify!($V),
386"` that is too large"
387));
388 }
389 };
390 }
391 )*
392393/// Holds per-query arenas for queries with the `arena_cache` modifier.
394#[derive(Default)]
395pub struct QueryArenas<'tcx> {
396 $(
397// Use the `ArenaCached` helper trait to determine the arena's value type.
398#[cfg($arena_cache)]
399pub $name: TypedArena<
400 <$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Allocated,
401 >,
402 )*
403 }
404405impl<'tcx> $crate::query::TyCtxtEnsureOk<'tcx> {
406 $(
407 $(#[$attr])*
408#[inline(always)]
409pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
410crate::query::inner::query_ensure_ok_or_done(
411self.tcx,
412&self.tcx.query_system.query_vtables.$name,
413$crate::query::IntoQueryKey::into_query_key(key),
414$crate::query::EnsureMode::Ok,
415 )
416 }
417 )*
418 }
419420// Only defined when the `ensure_result` modifier is present.
421impl<'tcx> $crate::query::TyCtxtEnsureResult<'tcx> {
422 $(
423#[cfg($returns_error_guaranteed)]
424$(#[$attr])*
425#[inline(always)]
426pub fn $name(
427self,
428 key: query_helper_param_ty!($($K)*),
429 ) -> Result<(), rustc_errors::ErrorGuaranteed> {
430crate::query::inner::query_ensure_result(
431self.tcx,
432&self.tcx.query_system.query_vtables.$name,
433$crate::query::IntoQueryKey::into_query_key(key),
434 )
435 }
436 )*
437 }
438439impl<'tcx> $crate::query::TyCtxtEnsureDone<'tcx> {
440 $(
441 $(#[$attr])*
442#[inline(always)]
443pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
444crate::query::inner::query_ensure_ok_or_done(
445self.tcx,
446&self.tcx.query_system.query_vtables.$name,
447$crate::query::IntoQueryKey::into_query_key(key),
448$crate::query::EnsureMode::Done,
449 );
450 }
451 )*
452 }
453454impl<'tcx> TyCtxt<'tcx> {
455 $(
456 $(#[$attr])*
457#[inline(always)]
458 #[must_use]
459pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V {
460self.at(DUMMY_SP).$name(key)
461 }
462 )*
463 }
464465impl<'tcx> $crate::query::TyCtxtAt<'tcx> {
466 $(
467 $(#[$attr])*
468#[inline(always)]
469pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V {
470use $crate::query::{erase, inner};
471472 erase::restore_val::<$V>(inner::query_get_at(
473self.tcx,
474self.span,
475&self.tcx.query_system.query_vtables.$name,
476$crate::query::IntoQueryKey::into_query_key(key),
477 ))
478 }
479 )*
480 }
481482 $(
483#[cfg($feedable)]
484impl<'tcx, K: $crate::query::IntoQueryKey<$name::Key<'tcx>> + Copy>
485TyCtxtFeed<'tcx, K>
486 {
487 $(#[$attr])*
488#[inline(always)]
489pub fn $name(self, value: $name::ProvidedValue<'tcx>) {
490let key = self.key().into_query_key();
491let erased_value = $name::provided_to_erased(self.tcx, value);
492$crate::query::inner::query_feed(
493self.tcx,
494&self.tcx.query_system.query_vtables.$name,
495 key,
496 erased_value,
497 );
498 }
499 }
500 )*
501502/// Identifies a query by kind and key. This is in contrast to `QueryJobId` which is just a number.
503#[allow(non_camel_case_types)]
504 #[derive(Clone, Copy, Debug)]
505pub enum TaggedQueryKey<'tcx> {
506 $(
507$name($name::Key<'tcx>),
508 )*
509 }
510511impl<'tcx> TaggedQueryKey<'tcx> {
512/// Returns the name of the query this key is tagged with.
513 ///
514 /// This is useful for error/debug output, but don't use it to check for
515 /// specific query names. Instead, match on the `TaggedQueryKey` variant.
516pub fn query_name(&self) -> &'static str {
517match self {
518 $(
519 TaggedQueryKey::$name(_) => stringify!($name),
520 )*
521 }
522 }
523524/// Formats a human-readable description of this query and its key, as
525 /// specified by the `desc` query modifier.
526 ///
527 /// Used when reporting query cycle errors and similar problems.
528pub fn description(&self, tcx: TyCtxt<'tcx>) -> String {
529let (name, description) = ty::print::with_no_queries!(match self {
530 $(
531 TaggedQueryKey::$name(key) => (stringify!($name), _description_fns::$name(tcx, *key)),
532 )*
533 });
534if tcx.sess.verbose_internals() {
535format!("{description} [{name:?}]")
536 } else {
537 description
538 }
539 }
540541/// Returns the default span for this query if `span` is a dummy span.
542pub fn default_span(&self, tcx: TyCtxt<'tcx>, span: Span) -> Span {
543if !span.is_dummy() {
544return span
545 }
546if let TaggedQueryKey::def_span(..) = self {
547// The `def_span` query is used to calculate `default_span`,
548 // so exit to avoid infinite recursion.
549return DUMMY_SP
550 }
551match self {
552 $(
553 TaggedQueryKey::$name(key) => crate::query::QueryKey::default_span(key, tcx),
554 )*
555 }
556 }
557558pub fn def_kind(&self, tcx: TyCtxt<'tcx>) -> Option<DefKind> {
559// This is used to reduce code generation as it
560 // can be reused for queries with the same key type.
561fn inner<'tcx>(key: &impl crate::query::QueryKey, tcx: TyCtxt<'tcx>) -> Option<DefKind> {
562 key.key_as_def_id().and_then(|def_id| def_id.as_local()).map(|def_id| tcx.def_kind(def_id))
563 }
564565if let TaggedQueryKey::def_kind(..) = self {
566// Try to avoid infinite recursion.
567return None
568}
569match self {
570 $(
571 TaggedQueryKey::$name(key) => inner(key, tcx),
572 )*
573 }
574 }
575 }
576577/// Holds a `QueryVTable` for each query.
578pub struct QueryVTables<'tcx> {
579 $(
580pub $name: crate::query::QueryVTable<'tcx, $name::Cache<'tcx>>,
581 )*
582 }
583584pub struct Providers {
585 $(
586/// This is the provider for the query. Use `Find references` on this to
587 /// navigate between the provider assignment and the query definition.
588pub $name: for<'tcx> fn(
589TyCtxt<'tcx>,
590$name::LocalKey<'tcx>,
591 ) -> $name::ProvidedValue<'tcx>,
592 )*
593 }
594595pub struct ExternProviders {
596 $(
597#[cfg($separate_provide_extern)]
598pub $name: for<'tcx> fn(
599TyCtxt<'tcx>,
600$name::Key<'tcx>,
601 ) -> $name::ProvidedValue<'tcx>,
602 )*
603 }
604605impl Default for Providers {
606fn default() -> Self {
607 Providers {
608 $(
609$name: |_, key| {
610$crate::query::plumbing::default_query(stringify!($name), &key)
611 },
612 )*
613 }
614 }
615 }
616617impl Default for ExternProviders {
618fn default() -> Self {
619 ExternProviders {
620 $(
621#[cfg($separate_provide_extern)]
622$name: |_, key| $crate::query::plumbing::default_extern_query(
623stringify!($name),
624&key,
625 ),
626 )*
627 }
628 }
629 }
630631impl Copy for Providers {}
632impl Clone for Providers {
633fn clone(&self) -> Self { *self }
634 }
635636impl Copy for ExternProviders {}
637impl Clone for ExternProviders {
638fn clone(&self) -> Self { *self }
639 }
640 };
641}
642643// Re-export `macro_rules!` macros as normal items, so that they can be imported normally.
644pub(crate) use define_callbacks;
645pub(crate) use query_helper_param_ty;
646647#[cold]
648pub(crate) fn default_query(name: &str, key: &dyn std::fmt::Debug) -> ! {
649crate::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!(
650"`tcx.{name}({key:?})` is not supported for this key;\n\
651 hint: Queries can be either made to the local crate, or the external crate. \
652 This error means you tried to use it for one that's not supported.\n\
653 If that's not the case, {name} was likely never assigned to a provider function.\n",
654 )655}
656657#[cold]
658pub(crate) fn default_extern_query(name: &str, key: &dyn std::fmt::Debug) -> ! {
659crate::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!(
660"`tcx.{name}({key:?})` unsupported by its crate; \
661 perhaps the `{name}` query was never assigned a provider function",
662 )663}