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::StableHashingContext;
15use crate::queries::{ExternProviders, Providers, QueryArenas, QueryVTables, TaggedQueryKey};
16use crate::query::on_disk_cache::OnDiskCache;
17use crate::query::{IntoQueryKey, QueryCache, QueryJob, 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 {
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)]
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(..)` or `tcx.ensure_done().$query(..)`.
65Ensure { ensure_mode: EnsureMode },
66}
6768/// Distinguishes between `tcx.ensure_ok()` and `tcx.ensure_done()` in shared
69/// code paths that handle both modes.
70#[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)]
71pub enum EnsureMode {
72/// Corresponds to [`TyCtxt::ensure_ok`].
73Ok,
74/// Corresponds to [`TyCtxt::ensure_done`].
75Done,
76}
7778/// Stores data and metadata (e.g. function pointers) for a particular query.
79pub struct QueryVTable<'tcx, C: QueryCache> {
80pub name: &'static str,
8182/// 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(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>,
108109/// Function pointer that hashes this query's result values.
110 ///
111 /// For `no_hash` queries, this function pointer is None.
112pub hash_value_fn: Option<fn(&mut StableHashingContext<'_>, &C::Value) -> Fingerprint>,
113114/// Function pointer that handles a cycle error. `error` must be consumed, e.g. with `emit` (if
115 /// it should be emitted) or `delay_as_bug` (if it need not be emitted because an alternative
116 /// error is created and emitted). A value may be returned, or (more commonly) the function may
117 /// just abort after emitting the error.
118pub handle_cycle_error_fn:
119fn(tcx: TyCtxt<'tcx>, key: C::Key, cycle: Cycle<'tcx>, error: Diag<'_>) -> C::Value,
120121pub format_value: fn(&C::Value) -> String,
122123pub create_tagged_key: fn(C::Key) -> TaggedQueryKey<'tcx>,
124125/// Function pointer that is called by the query methods on [`TyCtxt`] and
126 /// friends[^1], after they have checked the in-memory cache and found no
127 /// existing value for this key.
128 ///
129 /// Transitive responsibilities include trying to load a disk-cached value
130 /// if possible (incremental only), invoking the query provider if necessary,
131 /// and putting the obtained value into the in-memory cache.
132 ///
133 /// [^1]: [`TyCtxt`], [`TyCtxtAt`], [`TyCtxtEnsureOk`], [`TyCtxtEnsureDone`]
134pub execute_query_fn: fn(TyCtxt<'tcx>, Span, C::Key, QueryMode) -> Option<C::Value>,
135}
136137impl<'tcx, C: QueryCache> fmt::Debugfor QueryVTable<'tcx, C> {
138fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
139// When debug-printing a query vtable (e.g. for ICE or tracing),
140 // just print the query name to know what query we're dealing with.
141 // The other fields and flags are probably just unhelpful noise.
142 //
143 // If there is need for a more detailed dump of all flags and fields,
144 // consider writing a separate dump method and calling it explicitly.
145f.write_str(self.name)
146 }
147}
148149pub struct QuerySystem<'tcx> {
150pub arenas: WorkerLocal<QueryArenas<'tcx>>,
151pub query_vtables: QueryVTables<'tcx>,
152153/// Side-effect associated with each [`DepKind::SideEffect`] node in the
154 /// current incremental-compilation session. Side effects will be written
155 /// to disk, and loaded by [`OnDiskCache`] in the next session.
156 ///
157 /// Always empty if incremental compilation is off.
158pub side_effects: Lock<FxIndexMap<DepNodeIndex, QuerySideEffect>>,
159160/// This provides access to the incremental compilation on-disk cache for query results.
161 /// Do not access this directly. It is only meant to be used by
162 /// `DepGraph::try_mark_green()` and the query infrastructure.
163 /// This is `None` if we are not incremental compilation mode
164pub on_disk_cache: Option<OnDiskCache>,
165166pub local_providers: Providers,
167pub extern_providers: ExternProviders,
168169pub jobs: AtomicU64,
170}
171172#[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)]
173pub struct TyCtxtAt<'tcx> {
174pub tcx: TyCtxt<'tcx>,
175pub span: Span,
176}
177178impl<'tcx> Dereffor TyCtxtAt<'tcx> {
179type Target = TyCtxt<'tcx>;
180#[inline(always)]
181fn deref(&self) -> &Self::Target {
182&self.tcx
183 }
184}
185186#[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)]
187#[must_use]
188pub struct TyCtxtEnsureOk<'tcx> {
189pub tcx: TyCtxt<'tcx>,
190}
191192#[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)]
193#[must_use]
194pub struct TyCtxtEnsureResult<'tcx> {
195pub tcx: TyCtxt<'tcx>,
196}
197198#[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)]
199#[must_use]
200pub struct TyCtxtEnsureDone<'tcx> {
201pub tcx: TyCtxt<'tcx>,
202}
203204impl<'tcx> TyCtxtEnsureOk<'tcx> {
205pub fn typeck(self, def_id: impl IntoQueryKey<LocalDefId>) {
206self.typeck_root(
207self.tcx.typeck_root_def_id(def_id.into_query_key().to_def_id()).expect_local(),
208 )
209 }
210}
211212impl<'tcx> TyCtxt<'tcx> {
213pub fn typeck(self, def_id: impl IntoQueryKey<LocalDefId>) -> &'tcx ty::TypeckResults<'tcx> {
214self.typeck_root(
215self.typeck_root_def_id(def_id.into_query_key().to_def_id()).expect_local(),
216 )
217 }
218219/// Returns a transparent wrapper for `TyCtxt` which uses
220 /// `span` as the location of queries performed through it.
221#[inline(always)]
222pub fn at(self, span: Span) -> TyCtxtAt<'tcx> {
223TyCtxtAt { tcx: self, span }
224 }
225226/// FIXME: `ensure_ok`'s effects are subtle. Is this comment fully accurate?
227 ///
228 /// Wrapper that calls queries in a special "ensure OK" mode, for callers
229 /// that don't need the return value and just want to invoke a query for
230 /// its potential side-effect of emitting fatal errors.
231 ///
232 /// This can be more efficient than a normal query call, because if the
233 /// query's inputs are all green, the call can return immediately without
234 /// needing to obtain a value (by decoding one from disk or by executing
235 /// the query).
236 ///
237 /// (As with all query calls, execution is also skipped if the query result
238 /// is already cached in memory.)
239 ///
240 /// ## WARNING
241 /// A subsequent normal call to the same query might still cause it to be
242 /// executed! This can occur when the inputs are all green, but the query's
243 /// result is not cached on disk, so the query must be executed to obtain a
244 /// return value.
245 ///
246 /// Therefore, this call mode is not appropriate for callers that want to
247 /// ensure that the query is _never_ executed in the future.
248#[inline(always)]
249pub fn ensure_ok(self) -> TyCtxtEnsureOk<'tcx> {
250TyCtxtEnsureOk { tcx: self }
251 }
252253/// This is a variant of `ensure_ok` only usable with queries that return
254 /// `Result<_, ErrorGuaranteed>`. Queries calls through this function will
255 /// return `Result<(), ErrorGuaranteed>`. I.e. the error status is returned
256 /// but nothing else. As with `ensure_ok`, this can be more efficient than
257 /// a normal query call.
258#[inline(always)]
259pub fn ensure_result(self) -> TyCtxtEnsureResult<'tcx> {
260TyCtxtEnsureResult { tcx: self }
261 }
262263/// Wrapper that calls queries in a special "ensure done" mode, for callers
264 /// that don't need the return value and just want to guarantee that the
265 /// query won't be executed in the future, by executing it now if necessary.
266 ///
267 /// This is useful for queries that read from a [`Steal`] value, to ensure
268 /// that they are executed before the query that will steal the value.
269 ///
270 /// Unlike [`Self::ensure_ok`], a query with all-green inputs will only be
271 /// skipped if its return value is stored in the disk-cache. This is still
272 /// more efficient than a regular query, because in that situation the
273 /// return value doesn't necessarily need to be decoded.
274 ///
275 /// (As with all query calls, execution is also skipped if the query result
276 /// is already cached in memory.)
277 ///
278 /// [`Steal`]: rustc_data_structures::steal::Steal
279#[inline(always)]
280pub fn ensure_done(self) -> TyCtxtEnsureDone<'tcx> {
281TyCtxtEnsureDone { tcx: self }
282 }
283}
284285macro_rules!maybe_into_query_key {
286 (DefId) => { impl $crate::query::IntoQueryKey<DefId> };
287 (LocalDefId) => { impl $crate::query::IntoQueryKey<LocalDefId> };
288 ($K:ty) => { $K };
289}
290291macro_rules!define_callbacks {
292 (
293// You might expect the key to be `$K:ty`, but it needs to be `$($K:tt)*` so that
294 // `maybe_into_query_key!` can match on specific type names.
295queries {
296 $(
297 $(#[$attr:meta])*
298fn $name:ident($($K:tt)*) -> $V:ty
299 {
300// Search for (QMODLIST) to find all occurrences of this query modifier list.
301arena_cache: $arena_cache:literal,
302 cache_on_disk: $cache_on_disk:literal,
303 depth_limit: $depth_limit:literal,
304 desc: $desc:expr,
305 eval_always: $eval_always:literal,
306 feedable: $feedable:literal,
307 handle_cycle_error: $handle_cycle_error:literal,
308 no_force: $no_force:literal,
309 no_hash: $no_hash:literal,
310 returns_error_guaranteed: $returns_error_guaranteed:literal,
311 separate_provide_extern: $separate_provide_extern:literal,
312 }
313 )*
314 }
315// Non-queries are unused here.
316non_queries { $($_:tt)* }
317 ) => {
318 $(
319pub mod $name {
320use super::*;
321use $crate::query::erase::{self, Erased};
322323pub type Key<'tcx> = $($K)*;
324pub type Value<'tcx> = $V;
325326/// Key type used by provider functions in `local_providers`.
327 /// This query has the `separate_provide_extern` modifier.
328#[cfg($separate_provide_extern)]
329pub type LocalKey<'tcx> =
330 <Key<'tcx> as $crate::query::AsLocalQueryKey>::LocalQueryKey;
331/// Key type used by provider functions in `local_providers`.
332#[cfg(not($separate_provide_extern))]
333pub type LocalKey<'tcx> = Key<'tcx>;
334335/// Type returned from query providers and loaded from disk-cache.
336#[cfg($arena_cache)]
337pub type ProvidedValue<'tcx> =
338 <Value<'tcx> as $crate::query::arena_cached::ArenaCached<'tcx>>::Provided;
339/// Type returned from query providers and loaded from disk-cache.
340#[cfg(not($arena_cache))]
341pub type ProvidedValue<'tcx> = Value<'tcx>;
342343pub type Cache<'tcx> =
344 <Key<'tcx> as $crate::query::QueryKey>::Cache<Erased<Value<'tcx>>>;
345346/// This helper function takes a value returned by the query provider
347 /// (or loaded from disk, or supplied by query feeding), allocates
348 /// it in an arena if requested by the `arena_cache` modifier, and
349 /// then returns an erased copy of it.
350#[inline(always)]
351pub fn provided_to_erased<'tcx>(
352 tcx: TyCtxt<'tcx>,
353 provided_value: ProvidedValue<'tcx>,
354 ) -> Erased<Value<'tcx>> {
355// For queries with the `arena_cache` modifier, store the
356 // provided value in an arena and get a reference to it.
357#[cfg($arena_cache)]
358let value: Value<'tcx> = {
359use $crate::query::arena_cached::ArenaCached;
360 <Value<'tcx> as ArenaCached>::alloc_in_arena(
361 tcx,
362&tcx.query_system.arenas.$name,
363 provided_value,
364 )
365 };
366367// Otherwise, the provided value is the value (and `tcx` is unused).
368#[cfg(not($arena_cache))]
369let value: Value<'tcx> = {
370let _ = tcx;
371 provided_value
372 };
373374 erase::erase_val(value)
375 }
376377// Ensure that keys grow no larger than 88 bytes by accident.
378 // Increase this limit if necessary, but do try to keep the size low if possible
379#[cfg(target_pointer_width = "64")]
380const _: () = {
381if size_of::<Key<'static>>() > 88 {
382panic!("{}", concat!(
383"the query `",
384stringify!($name),
385"` has a key type `",
386stringify!($($K)*),
387"` that is too large"
388));
389 }
390 };
391392// Ensure that values grow no larger than 64 bytes by accident.
393 // Increase this limit if necessary, but do try to keep the size low if possible
394#[cfg(target_pointer_width = "64")]
395 #[cfg(not(feature = "rustc_randomized_layouts"))]
396const _: () = {
397if size_of::<Value<'static>>() > 64 {
398panic!("{}", concat!(
399"the query `",
400stringify!($name),
401"` has a value type `",
402stringify!($V),
403"` that is too large"
404));
405 }
406 };
407 }
408 )*
409410/// Identifies a query by kind and key. This is in contrast to `QueryJobId` which is just a
411 /// number.
412#[allow(non_camel_case_types)]
413 #[derive(Clone, Copy, Debug)]
414pub enum TaggedQueryKey<'tcx> {
415 $(
416$name($name::Key<'tcx>),
417 )*
418 }
419420impl<'tcx> TaggedQueryKey<'tcx> {
421/// Returns the name of the query this key is tagged with.
422 ///
423 /// This is useful for error/debug output, but don't use it to check for
424 /// specific query names. Instead, match on the `TaggedQueryKey` variant.
425pub fn query_name(&self) -> &'static str {
426match self {
427 $(
428 TaggedQueryKey::$name(_) => stringify!($name),
429 )*
430 }
431 }
432433/// Formats a human-readable description of this query and its key, as
434 /// specified by the `desc` query modifier.
435 ///
436 /// Used when reporting query cycle errors and similar problems.
437pub fn description(&self, tcx: TyCtxt<'tcx>) -> String {
438let (name, description) = ty::print::with_no_queries!(match self {
439 $(
440 TaggedQueryKey::$name(key) => (stringify!($name), ($desc)(tcx, *key)),
441 )*
442 });
443if tcx.sess.verbose_internals() {
444format!("{description} [{name:?}]")
445 } else {
446 description
447 }
448 }
449450/// Returns the default span for this query if `span` is a dummy span.
451pub fn default_span(&self, tcx: TyCtxt<'tcx>, span: Span) -> Span {
452if !span.is_dummy() {
453return span
454 }
455if let TaggedQueryKey::def_span(..) = self {
456// The `def_span` query is used to calculate `default_span`,
457 // so exit to avoid infinite recursion.
458return DUMMY_SP
459 }
460match self {
461 $(
462 TaggedQueryKey::$name(key) =>
463$crate::query::QueryKey::default_span(key, tcx),
464 )*
465 }
466 }
467 }
468469/// Holds a `QueryVTable` for each query.
470pub struct QueryVTables<'tcx> {
471 $(
472pub $name: $crate::query::QueryVTable<'tcx, $name::Cache<'tcx>>,
473 )*
474 }
475476/// Holds per-query arenas for queries with the `arena_cache` modifier.
477#[derive(Default)]
478pub struct QueryArenas<'tcx> {
479 $(
480// Use the `ArenaCached` helper trait to determine the arena's value type.
481#[cfg($arena_cache)]
482pub $name: TypedArena<
483 <$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Allocated,
484 >,
485 )*
486 }
487488pub struct Providers {
489 $(
490/// This is the provider for the query. Use `Find references` on this to
491 /// navigate between the provider assignment and the query definition.
492pub $name: for<'tcx> fn(
493TyCtxt<'tcx>,
494$name::LocalKey<'tcx>,
495 ) -> $name::ProvidedValue<'tcx>,
496 )*
497 }
498499pub struct ExternProviders {
500 $(
501#[cfg($separate_provide_extern)]
502pub $name: for<'tcx> fn(
503TyCtxt<'tcx>,
504$name::Key<'tcx>,
505 ) -> $name::ProvidedValue<'tcx>,
506 )*
507 }
508509impl Default for Providers {
510fn default() -> Self {
511 Providers {
512 $(
513$name: |_, key| {
514$crate::query::plumbing::default_query(stringify!($name), &key)
515 },
516 )*
517 }
518 }
519 }
520521impl Default for ExternProviders {
522fn default() -> Self {
523 ExternProviders {
524 $(
525#[cfg($separate_provide_extern)]
526$name: |_, key| $crate::query::plumbing::default_extern_query(
527stringify!($name),
528&key,
529 ),
530 )*
531 }
532 }
533 }
534535impl Copy for Providers {}
536impl Clone for Providers {
537fn clone(&self) -> Self { *self }
538 }
539540impl Copy for ExternProviders {}
541impl Clone for ExternProviders {
542fn clone(&self) -> Self { *self }
543 }
544545impl<'tcx> TyCtxt<'tcx> {
546 $(
547 $(#[$attr])*
548#[inline(always)]
549 #[must_use]
550pub fn $name(self, key: maybe_into_query_key!($($K)*)) -> $V {
551self.at(DUMMY_SP).$name(key)
552 }
553 )*
554 }
555556impl<'tcx> $crate::query::TyCtxtAt<'tcx> {
557 $(
558 $(#[$attr])*
559#[inline(always)]
560pub fn $name(self, key: maybe_into_query_key!($($K)*)) -> $V {
561use $crate::query::{erase, inner};
562563 erase::restore_val::<$V>(inner::query_get_at(
564self.tcx,
565self.span,
566&self.tcx.query_system.query_vtables.$name,
567$crate::query::IntoQueryKey::into_query_key(key),
568 ))
569 }
570 )*
571 }
572573impl<'tcx> $crate::query::TyCtxtEnsureOk<'tcx> {
574 $(
575 $(#[$attr])*
576#[inline(always)]
577pub fn $name(self, key: maybe_into_query_key!($($K)*)) {
578$crate::query::inner::query_ensure_ok_or_done(
579self.tcx,
580&self.tcx.query_system.query_vtables.$name,
581$crate::query::IntoQueryKey::into_query_key(key),
582$crate::query::EnsureMode::Ok,
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$crate::query::inner::query_ensure_ok_or_done(
613self.tcx,
614&self.tcx.query_system.query_vtables.$name,
615$crate::query::IntoQueryKey::into_query_key(key),
616$crate::query::EnsureMode::Done,
617 );
618 }
619 )*
620 }
621622 $(
623// Only defined when the `feedable` modifier is present.
624#[cfg($feedable)]
625impl<'tcx, K: $crate::query::IntoQueryKey<$name::Key<'tcx>> + Copy>
626TyCtxtFeed<'tcx, K>
627 {
628 $(#[$attr])*
629#[inline(always)]
630pub fn $name(self, value: $name::ProvidedValue<'tcx>) {
631$crate::query::inner::query_feed(
632self.tcx,
633&self.tcx.query_system.query_vtables.$name,
634self.key().into_query_key(),
635$name::provided_to_erased(self.tcx, value),
636 );
637 }
638 }
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 maybe_into_query_key;
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}