1use std::fmt;
2use std::ops::Deref;
34use rustc_data_structures::fingerprint::Fingerprint;
5use rustc_data_structures::fx::FxIndexMap;
6use rustc_data_structures::hash_table::HashTable;
7use rustc_data_structures::sharded::Sharded;
8use rustc_data_structures::sync::{AtomicU64, Lock, WorkerLocal};
9use rustc_errors::Diag;
10use rustc_hir::def_id::LocalDefId;
11use rustc_span::Span;
1213use crate::dep_graph::{DepKind, DepNodeIndex, QuerySideEffect, SerializedDepNodeIndex};
14use crate::ich::StableHashState;
15use crate::queries::{ExternProviders, Providers, QueryArenas, QueryVTables, TaggedQueryKey};
16use crate::query::on_disk_cache::OnDiskCache;
17use crate::query::{IntoQueryKey, QueryCache, QueryJob, QueryKey, QueryStackFrame};
18use crate::ty::{self, TyCtxt};
1920/// For a particular query, keeps track of "active" keys, i.e. keys whose
21/// evaluation has started but has not yet finished successfully.
22///
23/// (Successful query evaluation for a key is represented by an entry in the
24/// query's in-memory cache.)
25pub struct QueryState<'tcx, K> {
26pub active: Sharded<HashTable<(K, ActiveKeyStatus<'tcx>)>>,
27}
2829impl<'tcx, K> Defaultfor QueryState<'tcx, K> {
30fn default() -> QueryState<'tcx, K> {
31QueryState { active: Default::default() }
32 }
33}
3435/// For a particular query and key, tracks the status of a query evaluation
36/// that has started, but has not yet finished successfully.
37///
38/// (Successful query evaluation for a key is represented by an entry in the
39/// query's in-memory cache.)
40pub enum ActiveKeyStatus<'tcx> {
41/// Some thread is already evaluating the query for this key.
42 ///
43 /// The enclosed [`QueryJob`] can be used to wait for it to finish.
44Started(QueryJob<'tcx>),
4546/// The query panicked. Queries trying to wait on this will raise a fatal error which will
47 /// silently panic.
48Poisoned,
49}
5051#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for Cycle<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f, "Cycle",
"usage", &self.usage, "frames", &&self.frames)
}
}Debug)]
52pub struct Cycle<'tcx> {
53/// The query and related span that uses the cycle.
54pub usage: Option<QueryStackFrame<'tcx>>,
5556/// The span here corresponds to the reason for which this query was required.
57pub frames: Vec<QueryStackFrame<'tcx>>,
58}
5960#[derive(#[automatically_derived]
impl ::core::fmt::Debug for QueryMode {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
QueryMode::Get => "Get",
QueryMode::EnsureOk => "EnsureOk",
})
}
}Debug)]
61pub enum QueryMode {
62/// This is a normal query call to `tcx.$query(..)` or `tcx.at(span).$query(..)`.
63Get,
64/// This is a call to `tcx.ensure_ok().$query(..)`.
65EnsureOk,
66}
6768/// Stores data and metadata (e.g. function pointers) for a particular query.
69pub struct QueryVTable<'tcx, C: QueryCache> {
70pub name: &'static str,
7172/// True if this query has the `eval_always` modifier.
73pub eval_always: bool,
74/// True if this query has the `depth_limit` modifier.
75pub depth_limit: bool,
76/// True if this query has the `feedable` modifier.
77pub feedable: bool,
7879pub cache_on_disk_local: bool,
80pub separate_provide_extern: bool,
8182pub dep_kind: DepKind,
83pub state: QueryState<'tcx, C::Key>,
84pub cache: C,
8586/// Function pointer that actually calls this query's provider.
87 /// Also performs some associated secondary tasks; see the macro-defined
88 /// implementation in `mod invoke_provider_fn` for more details.
89 ///
90 /// This should be the only code that calls the provider function.
91pub invoke_provider_fn: fn(tcx: TyCtxt<'tcx>, key: C::Key) -> C::Value,
9293/// Function pointer that tries to load a query value from disk.
94 ///
95 /// This should only be called after a successful check of [`Self::will_cache_on_disk_for_key`].
96pub try_load_from_disk_fn:
97fn(tcx: TyCtxt<'tcx>, prev_index: SerializedDepNodeIndex) -> Option<C::Value>,
9899/// Function pointer that hashes this query's result values.
100 ///
101 /// For `no_hash` queries, this function pointer is None.
102pub hash_value_fn: Option<fn(&mut StableHashState<'_>, &C::Value) -> Fingerprint>,
103104/// Function pointer that handles a cycle error. `error` must be consumed, e.g. with `emit` (if
105 /// it should be emitted) or `delay_as_bug` (if it need not be emitted because an alternative
106 /// error is created and emitted). A value may be returned, or (more commonly) the function may
107 /// just abort after emitting the error.
108pub handle_cycle_error_fn:
109fn(tcx: TyCtxt<'tcx>, key: C::Key, cycle: Cycle<'tcx>, error: Diag<'_>) -> C::Value,
110111pub format_value: fn(&C::Value) -> String,
112113pub create_tagged_key: fn(C::Key) -> TaggedQueryKey<'tcx>,
114115/// Function pointer that is called by the query methods on [`TyCtxt`] and
116 /// friends[^1], after they have checked the in-memory cache and found no
117 /// existing value for this key.
118 ///
119 /// Transitive responsibilities include trying to load a disk-cached value
120 /// if possible (incremental only), invoking the query provider if necessary,
121 /// and putting the obtained value into the in-memory cache.
122 ///
123 /// [^1]: [`TyCtxt`], [`TyCtxtAt`], [`TyCtxtEnsureOk`], [`TyCtxtEnsureDone`]
124pub execute_query_fn: fn(TyCtxt<'tcx>, Span, C::Key, QueryMode) -> Option<C::Value>,
125}
126127impl<'tcx, C: QueryCache> QueryVTable<'tcx, C> {
128pub fn will_cache_on_disk_for_key(&self, key: C::Key) -> bool {
129self.cache_on_disk_local && (!self.separate_provide_extern || key.as_local_key().is_some())
130 }
131}
132133impl<'tcx, C: QueryCache> fmt::Debugfor QueryVTable<'tcx, C> {
134fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135// When debug-printing a query vtable (e.g. for ICE or tracing),
136 // just print the query name to know what query we're dealing with.
137 // The other fields and flags are probably just unhelpful noise.
138 //
139 // If there is need for a more detailed dump of all flags and fields,
140 // consider writing a separate dump method and calling it explicitly.
141f.write_str(self.name)
142 }
143}
144145pub struct QuerySystem<'tcx> {
146pub arenas: WorkerLocal<QueryArenas<'tcx>>,
147pub query_vtables: QueryVTables<'tcx>,
148149/// Side-effect associated with each [`DepKind::SideEffect`] node in the
150 /// current incremental-compilation session. Side effects will be written
151 /// to disk, and loaded by [`OnDiskCache`] in the next session.
152 ///
153 /// Always empty if incremental compilation is off.
154pub side_effects: Lock<FxIndexMap<DepNodeIndex, QuerySideEffect>>,
155156/// This provides access to the incremental compilation on-disk cache for query results.
157 /// Do not access this directly. It is only meant to be used by
158 /// `DepGraph::try_mark_green()` and the query infrastructure.
159 /// This is `None` if we are not incremental compilation mode
160pub on_disk_cache: Option<OnDiskCache>,
161162pub local_providers: Providers,
163pub extern_providers: ExternProviders,
164165pub jobs: AtomicU64,
166167pub cycle_handler_nesting: Lock<u8>,
168}
169170#[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)]
171pub struct TyCtxtAt<'tcx> {
172pub tcx: TyCtxt<'tcx>,
173pub span: Span,
174}
175176impl<'tcx> Dereffor TyCtxtAt<'tcx> {
177type Target = TyCtxt<'tcx>;
178#[inline(always)]
179fn deref(&self) -> &Self::Target {
180&self.tcx
181 }
182}
183184#[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)]
185#[must_use]
186pub struct TyCtxtEnsureOk<'tcx> {
187pub tcx: TyCtxt<'tcx>,
188}
189190#[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)]
191#[must_use]
192pub struct TyCtxtEnsureResult<'tcx> {
193pub tcx: TyCtxt<'tcx>,
194}
195196#[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)]
197#[must_use]
198pub struct TyCtxtEnsureDone<'tcx> {
199pub tcx: TyCtxt<'tcx>,
200}
201202impl<'tcx> TyCtxtEnsureOk<'tcx> {
203pub fn typeck(self, def_id: impl IntoQueryKey<LocalDefId>) {
204self.typeck_root(
205self.tcx.typeck_root_def_id(def_id.into_query_key().to_def_id()).expect_local(),
206 )
207 }
208}
209210impl<'tcx> TyCtxt<'tcx> {
211pub fn typeck(self, def_id: impl IntoQueryKey<LocalDefId>) -> &'tcx ty::TypeckResults<'tcx> {
212self.typeck_root(
213self.typeck_root_def_id(def_id.into_query_key().to_def_id()).expect_local(),
214 )
215 }
216217/// Returns a transparent wrapper for `TyCtxt` which uses
218 /// `span` as the location of queries performed through it.
219#[inline(always)]
220pub fn at(self, span: Span) -> TyCtxtAt<'tcx> {
221TyCtxtAt { tcx: self, span }
222 }
223224/// FIXME: `ensure_ok`'s effects are subtle. Is this comment fully accurate?
225 ///
226 /// Wrapper that calls queries in a special "ensure OK" mode, for callers
227 /// that don't need the return value and just want to invoke a query for
228 /// its potential side-effect of emitting fatal errors.
229 ///
230 /// This can be more efficient than a normal query call, because if the
231 /// query's inputs are all green, the call can return immediately without
232 /// needing to obtain a value (by decoding one from disk or by executing
233 /// the query).
234 ///
235 /// (As with all query calls, execution is also skipped if the query result
236 /// is already cached in memory.)
237 ///
238 /// ## WARNING
239 /// A subsequent normal call to the same query might still cause it to be
240 /// executed! This can occur when the inputs are all green, but the query's
241 /// result is not cached on disk, so the query must be executed to obtain a
242 /// return value.
243 ///
244 /// Therefore, this call mode is not appropriate for callers that want to
245 /// ensure that the query is _never_ executed in the future.
246#[inline(always)]
247pub fn ensure_ok(self) -> TyCtxtEnsureOk<'tcx> {
248TyCtxtEnsureOk { tcx: self }
249 }
250251/// This is a variant of `ensure_ok` only usable with queries that return
252 /// `Result<_, ErrorGuaranteed>`. Queries calls through this function will
253 /// return `Result<(), ErrorGuaranteed>`. I.e. the error status is returned
254 /// but nothing else. As with `ensure_ok`, this can be more efficient than
255 /// a normal query call.
256#[inline(always)]
257pub fn ensure_result(self) -> TyCtxtEnsureResult<'tcx> {
258TyCtxtEnsureResult { tcx: self }
259 }
260261/// Wrapper that calls queries where callers don't need the return value and
262 /// just want to guarantee that the query won't be executed in the future.
263 ///
264 /// This is useful for queries that read from a [`Steal`] value, to ensure
265 /// that they are executed before the query that will steal the value.
266 ///
267 /// Currently this causes the query to be executed normally, but this behavior may change.
268 ///
269 /// [`Steal`]: rustc_data_structures::steal::Steal
270#[inline(always)]
271pub fn ensure_done(self) -> TyCtxtEnsureDone<'tcx> {
272TyCtxtEnsureDone { tcx: self }
273 }
274}
275276macro_rules!maybe_into_query_key {
277 (DefId) => { impl $crate::query::IntoQueryKey<DefId> };
278 (LocalDefId) => { impl $crate::query::IntoQueryKey<LocalDefId> };
279 ($K:ty) => { $K };
280}
281282macro_rules!define_callbacks {
283 (
284// You might expect the key to be `$K:ty`, but it needs to be `$($K:tt)*` so that
285 // `maybe_into_query_key!` can match on specific type names.
286queries {
287 $(
288 $(#[$attr:meta])*
289fn $name:ident($($K:tt)*) -> $V:ty
290 {
291// Search for (QMODLIST) to find all occurrences of this query modifier list.
292arena_cache: $arena_cache:literal,
293 cache_on_disk: $cache_on_disk:literal,
294 depth_limit: $depth_limit:literal,
295 desc: $desc:expr,
296 eval_always: $eval_always:literal,
297 feedable: $feedable:literal,
298 handle_cycle_error: $handle_cycle_error:literal,
299 no_force: $no_force:literal,
300 no_hash: $no_hash:literal,
301 returns_error_guaranteed: $returns_error_guaranteed:literal,
302 separate_provide_extern: $separate_provide_extern:literal,
303 }
304 )*
305 }
306// Non-queries are unused here.
307non_queries { $($_:tt)* }
308 ) => {
309 $(
310pub mod $name {
311use super::*;
312use $crate::query::erase::{self, Erased};
313314pub type Key<'tcx> = $($K)*;
315pub type Value<'tcx> = $V;
316317/// Key type used by provider functions in `local_providers`.
318 /// This query has the `separate_provide_extern` modifier.
319#[cfg($separate_provide_extern)]
320pub type LocalKey<'tcx> =
321 <Key<'tcx> as $crate::query::QueryKey>::LocalQueryKey;
322/// Key type used by provider functions in `local_providers`.
323#[cfg(not($separate_provide_extern))]
324pub type LocalKey<'tcx> = Key<'tcx>;
325326/// Type returned from query providers and loaded from disk-cache.
327#[cfg($arena_cache)]
328pub type ProvidedValue<'tcx> =
329 <Value<'tcx> as $crate::query::arena_cached::ArenaCached<'tcx>>::Provided;
330/// Type returned from query providers and loaded from disk-cache.
331#[cfg(not($arena_cache))]
332pub type ProvidedValue<'tcx> = Value<'tcx>;
333334pub type Cache<'tcx> =
335 <Key<'tcx> as $crate::query::QueryKey>::Cache<Erased<Value<'tcx>>>;
336337/// This helper function takes a value returned by the query provider
338 /// (or loaded from disk, or supplied by query feeding), allocates
339 /// it in an arena if requested by the `arena_cache` modifier, and
340 /// then returns an erased copy of it.
341#[inline(always)]
342pub fn provided_to_erased<'tcx>(
343 tcx: TyCtxt<'tcx>,
344 provided_value: ProvidedValue<'tcx>,
345 ) -> Erased<Value<'tcx>> {
346// For queries with the `arena_cache` modifier, store the
347 // provided value in an arena and get a reference to it.
348#[cfg($arena_cache)]
349let value: Value<'tcx> = {
350use $crate::query::arena_cached::ArenaCached;
351 <Value<'tcx> as ArenaCached>::alloc_in_arena(
352 tcx,
353&tcx.query_system.arenas.$name,
354 provided_value,
355 )
356 };
357358// Otherwise, the provided value is the value (and `tcx` is unused).
359#[cfg(not($arena_cache))]
360let value: Value<'tcx> = {
361let _ = tcx;
362 provided_value
363 };
364365 erase::erase_val(value)
366 }
367368// Ensure that keys grow no larger than 88 bytes by accident.
369 // Increase this limit if necessary, but do try to keep the size low if possible
370#[cfg(target_pointer_width = "64")]
371const _: () = {
372if size_of::<Key<'static>>() > 88 {
373panic!("{}", concat!(
374"the query `",
375stringify!($name),
376"` has a key type `",
377stringify!($($K)*),
378"` that is too large"
379));
380 }
381 };
382383// Ensure that values grow no larger than 64 bytes by accident.
384 // Increase this limit if necessary, but do try to keep the size low if possible
385#[cfg(target_pointer_width = "64")]
386 #[cfg(not(feature = "rustc_randomized_layouts"))]
387const _: () = {
388if size_of::<Value<'static>>() > 64 {
389panic!("{}", concat!(
390"the query `",
391stringify!($name),
392"` has a value type `",
393stringify!($V),
394"` that is too large"
395));
396 }
397 };
398 }
399 )*
400401/// Identifies a query by kind and key. This is in contrast to `QueryJobId` which is just a
402 /// number.
403#[allow(non_camel_case_types)]
404 #[derive(Clone, Copy, Debug)]
405pub enum TaggedQueryKey<'tcx> {
406 $(
407$name($name::Key<'tcx>),
408 )*
409 }
410411impl<'tcx> TaggedQueryKey<'tcx> {
412/// Returns the name of the query this key is tagged with.
413 ///
414 /// This is useful for error/debug output, but don't use it to check for
415 /// specific query names. Instead, match on the `TaggedQueryKey` variant.
416pub fn query_name(&self) -> &'static str {
417match self {
418 $(
419 TaggedQueryKey::$name(_) => stringify!($name),
420 )*
421 }
422 }
423424/// Formats a human-readable description of this query and its key, as
425 /// specified by the `desc` query modifier.
426 ///
427 /// Used when reporting query cycle errors and similar problems.
428pub fn description(&self, tcx: TyCtxt<'tcx>) -> String {
429let (name, description) = ty::print::with_no_queries!(match self {
430 $(
431 TaggedQueryKey::$name(key) => (stringify!($name), ($desc)(tcx, *key)),
432 )*
433 });
434if tcx.sess.verbose_internals() {
435format!("{description} [{name:?}]")
436 } else {
437 description
438 }
439 }
440441/// Calls `self.description` or returns a fallback if there was a fatal error
442pub fn catch_description(&self, tcx: TyCtxt<'tcx>) -> String {
443 catch_fatal_errors(|| self.description(tcx)).unwrap_or_else(|_| format!("<error describing {}>", self.query_name()))
444 }
445446/// Returns the default span for this query if `span` is a dummy span.
447pub fn default_span(&self, tcx: TyCtxt<'tcx>, span: Span) -> Span {
448if !span.is_dummy() {
449return span
450 }
451if let TaggedQueryKey::def_span(..) = self {
452// The `def_span` query is used to calculate `default_span`,
453 // so exit to avoid infinite recursion.
454return DUMMY_SP
455 }
456match self {
457 $(
458 TaggedQueryKey::$name(key) =>
459$crate::query::QueryKey::default_span(key, tcx),
460 )*
461 }
462 }
463464/// Calls `self.default_span` or returns `DUMMY_SP` if there was a fatal error
465pub fn catch_default_span(&self, tcx: TyCtxt<'tcx>, span: Span) -> Span {
466 catch_fatal_errors(|| self.default_span(tcx, span)).unwrap_or(DUMMY_SP)
467 }
468 }
469470/// Holds a `QueryVTable` for each query.
471pub struct QueryVTables<'tcx> {
472 $(
473pub $name: $crate::query::QueryVTable<'tcx, $name::Cache<'tcx>>,
474 )*
475 }
476477/// Holds per-query arenas for queries with the `arena_cache` modifier.
478#[derive(Default)]
479pub struct QueryArenas<'tcx> {
480 $(
481// Use the `ArenaCached` helper trait to determine the arena's value type.
482#[cfg($arena_cache)]
483pub $name: TypedArena<
484 <$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Allocated,
485 >,
486 )*
487 }
488489pub struct Providers {
490 $(
491/// This is the provider for the query. Use `Find references` on this to
492 /// navigate between the provider assignment and the query definition.
493pub $name: for<'tcx> fn(
494TyCtxt<'tcx>,
495$name::LocalKey<'tcx>,
496 ) -> $name::ProvidedValue<'tcx>,
497 )*
498 }
499500pub struct ExternProviders {
501 $(
502#[cfg($separate_provide_extern)]
503pub $name: for<'tcx> fn(
504TyCtxt<'tcx>,
505$name::Key<'tcx>,
506 ) -> $name::ProvidedValue<'tcx>,
507 )*
508 }
509510impl Default for Providers {
511fn default() -> Self {
512 Providers {
513 $(
514$name: |_, key| {
515$crate::query::plumbing::default_query(stringify!($name), &key)
516 },
517 )*
518 }
519 }
520 }
521522impl Default for ExternProviders {
523fn default() -> Self {
524 ExternProviders {
525 $(
526#[cfg($separate_provide_extern)]
527$name: |_, key| $crate::query::plumbing::default_extern_query(
528stringify!($name),
529&key,
530 ),
531 )*
532 }
533 }
534 }
535536impl Copy for Providers {}
537impl Clone for Providers {
538fn clone(&self) -> Self { *self }
539 }
540541impl Copy for ExternProviders {}
542impl Clone for ExternProviders {
543fn clone(&self) -> Self { *self }
544 }
545546impl<'tcx> TyCtxt<'tcx> {
547 $(
548 $(#[$attr])*
549#[inline(always)]
550 #[must_use]
551pub fn $name(self, key: maybe_into_query_key!($($K)*)) -> $V {
552self.at(DUMMY_SP).$name(key)
553 }
554 )*
555 }
556557impl<'tcx> $crate::query::TyCtxtAt<'tcx> {
558 $(
559 $(#[$attr])*
560#[inline(always)]
561pub fn $name(self, key: maybe_into_query_key!($($K)*)) -> $V {
562use $crate::query::{erase, inner};
563564 erase::restore_val::<$V>(inner::query_get_at(
565self.tcx,
566self.span,
567&self.tcx.query_system.query_vtables.$name,
568$crate::query::IntoQueryKey::into_query_key(key),
569 ))
570 }
571 )*
572 }
573574impl<'tcx> $crate::query::TyCtxtEnsureOk<'tcx> {
575 $(
576 $(#[$attr])*
577#[inline(always)]
578pub fn $name(self, key: maybe_into_query_key!($($K)*)) {
579$crate::query::inner::query_ensure_ok(
580self.tcx,
581&self.tcx.query_system.query_vtables.$name,
582$crate::query::IntoQueryKey::into_query_key(key),
583 )
584 }
585 )*
586 }
587588// Only defined when the `returns_error_guaranteed` modifier is present.
589impl<'tcx> $crate::query::TyCtxtEnsureResult<'tcx> {
590 $(
591#[cfg($returns_error_guaranteed)]
592$(#[$attr])*
593#[inline(always)]
594pub fn $name(
595self,
596 key: maybe_into_query_key!($($K)*),
597 ) -> Result<(), rustc_errors::ErrorGuaranteed> {
598$crate::query::inner::query_ensure_result(
599self.tcx,
600&self.tcx.query_system.query_vtables.$name,
601$crate::query::IntoQueryKey::into_query_key(key),
602 )
603 }
604 )*
605 }
606607impl<'tcx> $crate::query::TyCtxtEnsureDone<'tcx> {
608 $(
609 $(#[$attr])*
610#[inline(always)]
611pub fn $name(self, key: maybe_into_query_key!($($K)*)) {
612// This has the same implementation as `tcx.$query(..)` as it isn't currently
613 // beneficial to have an optimized variant due to how promotion works.
614let _ = self.tcx.$name(key);
615 }
616 )*
617 }
618619 $(
620// Only defined when the `feedable` modifier is present.
621#[cfg($feedable)]
622impl<'tcx, K: $crate::query::IntoQueryKey<$name::Key<'tcx>> + Copy>
623TyCtxtFeed<'tcx, K>
624 {
625 $(#[$attr])*
626#[inline(always)]
627pub fn $name(self, value: $name::ProvidedValue<'tcx>) {
628$crate::query::inner::query_feed(
629self.tcx,
630&self.tcx.query_system.query_vtables.$name,
631self.key().into_query_key(),
632$name::provided_to_erased(self.tcx, value),
633 );
634 }
635 }
636 )*
637 };
638}
639640// Re-export `macro_rules!` macros as normal items, so that they can be imported normally.
641pub(crate) use define_callbacks;
642pub(crate) use maybe_into_query_key;
643644#[cold]
645pub(crate) fn default_query(name: &str, key: &dyn std::fmt::Debug) -> ! {
646crate::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!(
647"`tcx.{name}({key:?})` is not supported for this key;\n\
648 hint: Queries can be either made to the local crate, or the external crate. \
649 This error means you tried to use it for one that's not supported.\n\
650 If that's not the case, {name} was likely never assigned to a provider function.\n",
651 )652}
653654#[cold]
655pub(crate) fn default_extern_query(name: &str, key: &dyn std::fmt::Debug) -> ! {
656crate::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!(
657"`tcx.{name}({key:?})` unsupported by its crate; \
658 perhaps the `{name}` query was never assigned a provider function",
659 )660}