1use std::fmt::Debug;
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_hir::def_id::{DefId, LocalDefId};
9use rustc_hir::hir_id::OwnerId;
10use rustc_macros::HashStable;
11use rustc_span::{ErrorGuaranteed, Span};
12pub use sealed::IntoQueryParam;
1314use crate::dep_graph;
15use crate::dep_graph::{DepKind, DepNodeIndex, SerializedDepNodeIndex};
16use crate::ich::StableHashingContext;
17use crate::queries::{
18ExternProviders, PerQueryVTables, Providers, QueryArenas, QueryCaches, QueryEngine, QueryStates,
19};
20use crate::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex, OnDiskCache};
21use crate::query::stack::{QueryStackDeferred, QueryStackFrame, QueryStackFrameExtra};
22use crate::query::{QueryCache, QueryInfo, QueryJob};
23use crate::ty::TyCtxt;
2425/// For a particular query, keeps track of "active" keys, i.e. keys whose
26/// evaluation has started but has not yet finished successfully.
27///
28/// (Successful query evaluation for a key is represented by an entry in the
29/// query's in-memory cache.)
30pub struct QueryState<'tcx, K> {
31pub active: Sharded<HashTable<(K, ActiveKeyStatus<'tcx>)>>,
32}
3334impl<'tcx, K> Defaultfor QueryState<'tcx, K> {
35fn default() -> QueryState<'tcx, K> {
36QueryState { active: Default::default() }
37 }
38}
3940/// For a particular query and key, tracks the status of a query evaluation
41/// that has started, but has not yet finished successfully.
42///
43/// (Successful query evaluation for a key is represented by an entry in the
44/// query's in-memory cache.)
45pub enum ActiveKeyStatus<'tcx> {
46/// Some thread is already evaluating the query for this key.
47 ///
48 /// The enclosed [`QueryJob`] can be used to wait for it to finish.
49Started(QueryJob<'tcx>),
5051/// The query panicked. Queries trying to wait on this will raise a fatal error which will
52 /// silently panic.
53Poisoned,
54}
5556/// How a particular query deals with query cycle errors.
57///
58/// Inspected by the code that actually handles cycle errors, to decide what
59/// approach to use.
60#[derive(#[automatically_derived]
impl ::core::marker::Copy for CycleErrorHandling { }Copy, #[automatically_derived]
impl ::core::clone::Clone for CycleErrorHandling {
#[inline]
fn clone(&self) -> CycleErrorHandling { *self }
}Clone)]
61pub enum CycleErrorHandling {
62 Error,
63 Fatal,
64 DelayBug,
65 Stash,
66}
6768pub type WillCacheOnDiskForKeyFn<'tcx, Key> = fn(tcx: TyCtxt<'tcx>, key: &Key) -> bool;
6970pub type TryLoadFromDiskFn<'tcx, Key, Value> = fn(
71 tcx: TyCtxt<'tcx>,
72 key: &Key,
73 prev_index: SerializedDepNodeIndex,
74 index: DepNodeIndex,
75) -> Option<Value>;
7677pub type IsLoadableFromDiskFn<'tcx, Key> =
78fn(tcx: TyCtxt<'tcx>, key: &Key, index: SerializedDepNodeIndex) -> bool;
7980pub type HashResult<V> = Option<fn(&mut StableHashingContext<'_>, &V) -> Fingerprint>;
8182#[derive(#[automatically_derived]
impl<I: ::core::clone::Clone> ::core::clone::Clone for CycleError<I> {
#[inline]
fn clone(&self) -> CycleError<I> {
CycleError {
usage: ::core::clone::Clone::clone(&self.usage),
cycle: ::core::clone::Clone::clone(&self.cycle),
}
}
}Clone, #[automatically_derived]
impl<I: ::core::fmt::Debug> ::core::fmt::Debug for CycleError<I> {
#[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)]
83pub struct CycleError<I = QueryStackFrameExtra> {
84/// The query and related span that uses the cycle.
85pub usage: Option<(Span, QueryStackFrame<I>)>,
86pub cycle: Vec<QueryInfo<I>>,
87}
8889impl<'tcx> CycleError<QueryStackDeferred<'tcx>> {
90pub fn lift(&self) -> CycleError<QueryStackFrameExtra> {
91CycleError {
92 usage: self.usage.as_ref().map(|(span, frame)| (*span, frame.lift())),
93 cycle: self.cycle.iter().map(|info| info.lift()).collect(),
94 }
95 }
96}
9798#[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 { check_cache: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"Ensure", "check_cache", &__self_0),
}
}
}Debug)]
99pub enum QueryMode {
100 Get,
101 Ensure { check_cache: bool },
102}
103104/// Stores function pointers and other metadata for a particular query.
105pub struct QueryVTable<'tcx, C: QueryCache> {
106pub name: &'static str,
107pub eval_always: bool,
108pub dep_kind: DepKind,
109/// How this query deals with query cycle errors.
110pub cycle_error_handling: CycleErrorHandling,
111// Offset of this query's state field in the QueryStates struct
112pub query_state: usize,
113// Offset of this query's cache field in the QueryCaches struct
114pub query_cache: usize,
115pub will_cache_on_disk_for_key_fn: Option<WillCacheOnDiskForKeyFn<'tcx, C::Key>>,
116117/// Function pointer that calls `tcx.$query(key)` for this query and
118 /// discards the returned value.
119 ///
120 /// This is a weird thing to be doing, and probably not what you want.
121 /// It is used for loading query results from disk-cache in some cases.
122pub call_query_method_fn: fn(tcx: TyCtxt<'tcx>, key: C::Key),
123124/// Function pointer that actually calls this query's provider.
125 /// Also performs some associated secondary tasks; see the macro-defined
126 /// implementation in `mod invoke_provider_fn` for more details.
127 ///
128 /// This should be the only code that calls the provider function.
129pub invoke_provider_fn: fn(tcx: TyCtxt<'tcx>, key: C::Key) -> C::Value,
130131pub try_load_from_disk_fn: Option<TryLoadFromDiskFn<'tcx, C::Key, C::Value>>,
132pub is_loadable_from_disk_fn: Option<IsLoadableFromDiskFn<'tcx, C::Key>>,
133pub hash_result: HashResult<C::Value>,
134pub value_from_cycle_error:
135fn(tcx: TyCtxt<'tcx>, cycle_error: &CycleError, guar: ErrorGuaranteed) -> C::Value,
136pub format_value: fn(&C::Value) -> String,
137138/// Formats a human-readable description of this query and its key, as
139 /// specified by the `desc` query modifier.
140 ///
141 /// Used when reporting query cycle errors and similar problems.
142pub description_fn: fn(TyCtxt<'tcx>, C::Key) -> String,
143}
144145pub struct QuerySystemFns {
146pub engine: QueryEngine,
147pub local_providers: Providers,
148pub extern_providers: ExternProviders,
149pub encode_query_results: for<'tcx> fn(
150 tcx: TyCtxt<'tcx>,
151 encoder: &mut CacheEncoder<'_, 'tcx>,
152 query_result_index: &mut EncodedDepNodeIndex,
153 ),
154pub try_mark_green: for<'tcx> fn(tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool,
155}
156157pub struct QuerySystem<'tcx> {
158pub states: QueryStates<'tcx>,
159pub arenas: WorkerLocal<QueryArenas<'tcx>>,
160pub caches: QueryCaches<'tcx>,
161pub query_vtables: PerQueryVTables<'tcx>,
162163/// This provides access to the incremental compilation on-disk cache for query results.
164 /// Do not access this directly. It is only meant to be used by
165 /// `DepGraph::try_mark_green()` and the query infrastructure.
166 /// This is `None` if we are not incremental compilation mode
167pub on_disk_cache: Option<OnDiskCache>,
168169pub fns: QuerySystemFns,
170171pub jobs: AtomicU64,
172}
173174#[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)]
175pub struct TyCtxtAt<'tcx> {
176pub tcx: TyCtxt<'tcx>,
177pub span: Span,
178}
179180impl<'tcx> Dereffor TyCtxtAt<'tcx> {
181type Target = TyCtxt<'tcx>;
182#[inline(always)]
183fn deref(&self) -> &Self::Target {
184&self.tcx
185 }
186}
187188#[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)]
189#[must_use]
190pub struct TyCtxtEnsureOk<'tcx> {
191pub tcx: TyCtxt<'tcx>,
192}
193194#[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)]
195#[must_use]
196pub struct TyCtxtEnsureDone<'tcx> {
197pub tcx: TyCtxt<'tcx>,
198}
199200impl<'tcx> TyCtxt<'tcx> {
201/// Wrapper that calls queries in a special "ensure OK" mode, for callers
202 /// that don't need the return value and just want to invoke a query for
203 /// its potential side-effect of emitting fatal errors.
204 ///
205 /// This can be more efficient than a normal query call, because if the
206 /// query's inputs are all green, the call can return immediately without
207 /// needing to obtain a value (by decoding one from disk or by executing
208 /// the query).
209 ///
210 /// (As with all query calls, execution is also skipped if the query result
211 /// is already cached in memory.)
212 ///
213 /// ## WARNING
214 /// A subsequent normal call to the same query might still cause it to be
215 /// executed! This can occur when the inputs are all green, but the query's
216 /// result is not cached on disk, so the query must be executed to obtain a
217 /// return value.
218 ///
219 /// Therefore, this call mode is not appropriate for callers that want to
220 /// ensure that the query is _never_ executed in the future.
221 ///
222 /// ## `return_result_from_ensure_ok`
223 /// If a query has the `return_result_from_ensure_ok` modifier, calls via
224 /// `ensure_ok` will instead return `Result<(), ErrorGuaranteed>`. If the
225 /// query needs to be executed, and execution returns an error, that error
226 /// is returned to the caller.
227#[inline(always)]
228pub fn ensure_ok(self) -> TyCtxtEnsureOk<'tcx> {
229TyCtxtEnsureOk { tcx: self }
230 }
231232/// Wrapper that calls queries in a special "ensure done" mode, for callers
233 /// that don't need the return value and just want to guarantee that the
234 /// query won't be executed in the future, by executing it now if necessary.
235 ///
236 /// This is useful for queries that read from a [`Steal`] value, to ensure
237 /// that they are executed before the query that will steal the value.
238 ///
239 /// Unlike [`Self::ensure_ok`], a query with all-green inputs will only be
240 /// skipped if its return value is stored in the disk-cache. This is still
241 /// more efficient than a regular query, because in that situation the
242 /// return value doesn't necessarily need to be decoded.
243 ///
244 /// (As with all query calls, execution is also skipped if the query result
245 /// is already cached in memory.)
246 ///
247 /// [`Steal`]: rustc_data_structures::steal::Steal
248#[inline(always)]
249pub fn ensure_done(self) -> TyCtxtEnsureDone<'tcx> {
250TyCtxtEnsureDone { tcx: self }
251 }
252253/// Returns a transparent wrapper for `TyCtxt` which uses
254 /// `span` as the location of queries performed through it.
255#[inline(always)]
256pub fn at(self, span: Span) -> TyCtxtAt<'tcx> {
257TyCtxtAt { tcx: self, span }
258 }
259260pub fn try_mark_green(self, dep_node: &dep_graph::DepNode) -> bool {
261 (self.query_system.fns.try_mark_green)(self, dep_node)
262 }
263}
264265/// Calls either `query_ensure` or `query_ensure_error_guaranteed`, depending
266/// on whether the list of modifiers contains `return_result_from_ensure_ok`.
267macro_rules!query_ensure_select {
268 ([]$($args:tt)*) => {
269crate::query::inner::query_ensure($($args)*)
270 };
271 ([(return_result_from_ensure_ok) $($rest:tt)*]$($args:tt)*) => {
272crate::query::inner::query_ensure_error_guaranteed($($args)*)
273 };
274 ([$other:tt $($modifiers:tt)*]$($args:tt)*) => {
275query_ensure_select!([$($modifiers)*]$($args)*)
276 };
277}
278279macro_rules!query_helper_param_ty {
280 (DefId) => { impl $crate::query::IntoQueryParam<DefId> };
281 (LocalDefId) => { impl $crate::query::IntoQueryParam<LocalDefId> };
282 ($K:ty) => { $K };
283}
284285macro_rules!query_if_arena {
286 ([] $arena:tt $no_arena:tt) => {
287$no_arena
288};
289 ([(arena_cache) $($rest:tt)*] $arena:tt $no_arena:tt) => {
290$arena
291};
292 ([$other:tt $($modifiers:tt)*]$($args:tt)*) => {
293query_if_arena!([$($modifiers)*]$($args)*)
294 };
295}
296297/// If `separate_provide_extern`, then the key can be projected to its
298/// local key via `<$K as AsLocalKey>::LocalKey`.
299macro_rules!local_key_if_separate_extern {
300 ([] $($K:tt)*) => {
301 $($K)*
302 };
303 ([(separate_provide_extern) $($rest:tt)*] $($K:tt)*) => {
304 <$($K)* as $crate::query::AsLocalKey>::LocalKey305 };
306 ([$other:tt $($modifiers:tt)*] $($K:tt)*) => {
307local_key_if_separate_extern!([$($modifiers)*] $($K)*)
308 };
309}
310311macro_rules!separate_provide_extern_decl {
312 ([][$name:ident]) => {
313 ()
314 };
315 ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
316for<'tcx> fn(
317TyCtxt<'tcx>,
318$name::Key<'tcx>,
319 ) -> $name::ProvidedValue<'tcx>
320 };
321 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
322separate_provide_extern_decl!([$($modifiers)*][$($args)*])
323 };
324}
325326macro_rules!ensure_ok_result {
327 ( [] ) => {
328 ()
329 };
330 ( [(return_result_from_ensure_ok) $($rest:tt)*] ) => {
331Result<(), ErrorGuaranteed>
332 };
333 ( [$other:tt $($modifiers:tt)*] ) => {
334ensure_ok_result!( [$($modifiers)*] )
335 };
336}
337338macro_rules!separate_provide_extern_default {
339 ([][$name:ident]) => {
340 ()
341 };
342 ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
343 |_, key| $crate::query::plumbing::default_extern_query(stringify!($name), &key)
344 };
345 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
346separate_provide_extern_default!([$($modifiers)*][$($args)*])
347 };
348}
349350macro_rules!define_callbacks {
351 (
352 $(
353 $(#[$attr:meta])*
354 [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,
355 )*
356 ) => {
357 $(#[allow(unused_lifetimes)] pub mod $name {
358use super::*;
359use $crate::query::erase::{self, Erased};
360361pub type Key<'tcx> = $($K)*;
362pub type Value<'tcx> = $V;
363364pub type LocalKey<'tcx> = local_key_if_separate_extern!([$($modifiers)*] $($K)*);
365366/// This type alias specifies the type returned from query providers and the type
367 /// used for decoding. For regular queries this is the declared returned type `V`,
368 /// but `arena_cache` will use `<V as ArenaCached>::Provided` instead.
369pub type ProvidedValue<'tcx> = query_if_arena!(
370 [$($modifiers)*]
371 (<$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Provided)
372 ($V)
373 );
374375/// This helper function takes a value returned by the query provider
376 /// (or loaded from disk, or supplied by query feeding), allocates
377 /// it in an arena if requested by the `arena_cache` modifier, and
378 /// then returns an erased copy of it.
379#[inline(always)]
380pub fn provided_to_erased<'tcx>(
381 tcx: TyCtxt<'tcx>,
382 provided_value: ProvidedValue<'tcx>,
383 ) -> Erased<Value<'tcx>> {
384// For queries with the `arena_cache` modifier, store the
385 // provided value in an arena and get a reference to it.
386let value: Value<'tcx> = query_if_arena!([$($modifiers)*] {
387 <$V as $crate::query::arena_cached::ArenaCached>::alloc_in_arena(
388 tcx,
389&tcx.query_system.arenas.$name,
390 provided_value,
391 )
392 } {
393// Otherwise, the provided value is the value (and `tcx` is unused).
394let _ = tcx;
395 provided_value
396 });
397 erase::erase_val(value)
398 }
399400pub type Storage<'tcx> = <$($K)* as $crate::query::Key>::Cache<Erased<$V>>;
401402// Ensure that keys grow no larger than 88 bytes by accident.
403 // Increase this limit if necessary, but do try to keep the size low if possible
404#[cfg(target_pointer_width = "64")]
405const _: () = {
406if size_of::<Key<'static>>() > 88 {
407panic!("{}", concat!(
408"the query `",
409stringify!($name),
410"` has a key type `",
411stringify!($($K)*),
412"` that is too large"
413));
414 }
415 };
416417// Ensure that values grow no larger than 64 bytes by accident.
418 // Increase this limit if necessary, but do try to keep the size low if possible
419#[cfg(target_pointer_width = "64")]
420 #[cfg(not(feature = "rustc_randomized_layouts"))]
421const _: () = {
422if size_of::<Value<'static>>() > 64 {
423panic!("{}", concat!(
424"the query `",
425stringify!($name),
426"` has a value type `",
427stringify!($V),
428"` that is too large"
429));
430 }
431 };
432 })*
433434/// Holds per-query arenas for queries with the `arena_cache` modifier.
435#[derive(Default)]
436pub struct QueryArenas<'tcx> {
437 $(
438 $(#[$attr])*
439pub $name: query_if_arena!([$($modifiers)*]
440// Use the `ArenaCached` helper trait to determine the arena's value type.
441(TypedArena<<$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Allocated>)
442// No arena for this query, so the field type is `()`.
443()
444 ),
445 )*
446 }
447448#[derive(Default)]
449pub struct QueryCaches<'tcx> {
450 $($(#[$attr])* pub $name: $name::Storage<'tcx>,)*
451 }
452453impl<'tcx> $crate::query::TyCtxtEnsureOk<'tcx> {
454 $($(#[$attr])*
455#[inline(always)]
456pub fn $name(
457self,
458 key: query_helper_param_ty!($($K)*),
459 ) -> ensure_ok_result!([$($modifiers)*]) {
460query_ensure_select!(
461 [$($modifiers)*]
462self.tcx,
463self.tcx.query_system.fns.engine.$name,
464&self.tcx.query_system.caches.$name,
465$crate::query::IntoQueryParam::into_query_param(key),
466false,
467 )
468 })*
469 }
470471impl<'tcx> $crate::query::TyCtxtEnsureDone<'tcx> {
472 $($(#[$attr])*
473#[inline(always)]
474pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
475crate::query::inner::query_ensure(
476self.tcx,
477self.tcx.query_system.fns.engine.$name,
478&self.tcx.query_system.caches.$name,
479$crate::query::IntoQueryParam::into_query_param(key),
480true,
481 );
482 })*
483 }
484485impl<'tcx> TyCtxt<'tcx> {
486 $($(#[$attr])*
487#[inline(always)]
488 #[must_use]
489pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V
490{
491self.at(DUMMY_SP).$name(key)
492 })*
493 }
494495impl<'tcx> $crate::query::TyCtxtAt<'tcx> {
496 $($(#[$attr])*
497#[inline(always)]
498pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V
499{
500use $crate::query::{erase, inner};
501502 erase::restore_val::<$V>(inner::query_get_at(
503self.tcx,
504self.tcx.query_system.fns.engine.$name,
505&self.tcx.query_system.caches.$name,
506self.span,
507$crate::query::IntoQueryParam::into_query_param(key),
508 ))
509 })*
510 }
511512/// Holds a `QueryVTable` for each query.
513 ///
514 /// ("Per" just makes this pluralized name more visually distinct.)
515pub struct PerQueryVTables<'tcx> {
516 $(
517pub $name: ::rustc_middle::query::plumbing::QueryVTable<'tcx, $name::Storage<'tcx>>,
518 )*
519 }
520521#[derive(Default)]
522pub struct QueryStates<'tcx> {
523 $(
524pub $name: $crate::query::QueryState<'tcx, $($K)*>,
525 )*
526 }
527528pub struct Providers {
529 $(
530/// This is the provider for the query. Use `Find references` on this to
531 /// navigate between the provider assignment and the query definition.
532pub $name: for<'tcx> fn(
533TyCtxt<'tcx>,
534$name::LocalKey<'tcx>,
535 ) -> $name::ProvidedValue<'tcx>,
536 )*
537 }
538539pub struct ExternProviders {
540 $(pub $name: separate_provide_extern_decl!([$($modifiers)*][$name]),)*
541 }
542543impl Default for Providers {
544fn default() -> Self {
545 Providers {
546 $($name: |_, key| $crate::query::plumbing::default_query(stringify!($name), &key)),*
547 }
548 }
549 }
550551impl Default for ExternProviders {
552fn default() -> Self {
553 ExternProviders {
554 $($name: separate_provide_extern_default!([$($modifiers)*][$name]),)*
555 }
556 }
557 }
558559impl Copy for Providers {}
560impl Clone for Providers {
561fn clone(&self) -> Self { *self }
562 }
563564impl Copy for ExternProviders {}
565impl Clone for ExternProviders {
566fn clone(&self) -> Self { *self }
567 }
568569pub struct QueryEngine {
570 $(pub $name: for<'tcx> fn(
571TyCtxt<'tcx>,
572Span,
573$name::Key<'tcx>,
574$crate::query::QueryMode,
575 ) -> Option<$crate::query::erase::Erased<$V>>,)*
576 }
577 };
578}
579580macro_rules!define_feedable {
581 ($($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
582 $(impl<'tcx, K: $crate::query::IntoQueryParam<$($K)*> + Copy> TyCtxtFeed<'tcx, K> {
583 $(#[$attr])*
584#[inline(always)]
585pub fn $name(self, value: $name::ProvidedValue<'tcx>) {
586let key = self.key().into_query_param();
587588let tcx = self.tcx;
589let erased_value = $name::provided_to_erased(tcx, value);
590591let dep_kind: dep_graph::DepKind = dep_graph::dep_kinds::$name;
592593$crate::query::inner::query_feed(
594 tcx,
595 dep_kind,
596&tcx.query_system.query_vtables.$name,
597&tcx.query_system.caches.$name,
598 key,
599 erased_value,
600 );
601 }
602 })*
603 }
604}
605606// Each of these queries corresponds to a function pointer field in the
607// `Providers` struct for requesting a value of that type, and a method
608// on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
609// which memoizes and does dep-graph tracking, wrapping around the actual
610// `Providers` that the driver creates (using several `rustc_*` crates).
611//
612// The result type of each query must implement `Clone`, and additionally
613// `ty::query::values::Value`, which produces an appropriate placeholder
614// (error) value if the query resulted in a query cycle.
615// Queries marked with `cycle_fatal` do not need the latter implementation,
616// as they will raise an fatal error on query cycles instead.
617618mod sealed {
619use rustc_hir::def_id::{LocalModDefId, ModDefId};
620621use super::{DefId, LocalDefId, OwnerId};
622623/// An analogue of the `Into` trait that's intended only for query parameters.
624 ///
625 /// This exists to allow queries to accept either `DefId` or `LocalDefId` while requiring that the
626 /// user call `to_def_id` to convert between them everywhere else.
627pub trait IntoQueryParam<P> {
628fn into_query_param(self) -> P;
629 }
630631impl<P> IntoQueryParam<P> for P {
632#[inline(always)]
633fn into_query_param(self) -> P {
634self635 }
636 }
637638impl<'a, P: Copy> IntoQueryParam<P> for &'a P {
639#[inline(always)]
640fn into_query_param(self) -> P {
641*self642 }
643 }
644645impl IntoQueryParam<LocalDefId> for OwnerId {
646#[inline(always)]
647fn into_query_param(self) -> LocalDefId {
648self.def_id
649 }
650 }
651652impl IntoQueryParam<DefId> for LocalDefId {
653#[inline(always)]
654fn into_query_param(self) -> DefId {
655self.to_def_id()
656 }
657 }
658659impl IntoQueryParam<DefId> for OwnerId {
660#[inline(always)]
661fn into_query_param(self) -> DefId {
662self.to_def_id()
663 }
664 }
665666impl IntoQueryParam<DefId> for ModDefId {
667#[inline(always)]
668fn into_query_param(self) -> DefId {
669self.to_def_id()
670 }
671 }
672673impl IntoQueryParam<DefId> for LocalModDefId {
674#[inline(always)]
675fn into_query_param(self) -> DefId {
676self.to_def_id()
677 }
678 }
679680impl IntoQueryParam<LocalDefId> for LocalModDefId {
681#[inline(always)]
682fn into_query_param(self) -> LocalDefId {
683self.into()
684 }
685 }
686}
687688#[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_middle::ich::StableHashingContext<'__ctx>>
for CyclePlaceholder {
#[inline]
fn hash_stable(&self,
__hcx: &mut ::rustc_middle::ich::StableHashingContext<'__ctx>,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
match *self {
CyclePlaceholder(ref __binding_0) => {
{ __binding_0.hash_stable(__hcx, __hasher); }
}
}
}
}
};HashStable)]
689pub struct CyclePlaceholder(pub ErrorGuaranteed);
690691#[cold]
692pub(crate) fn default_query(name: &str, key: &dyn std::fmt::Debug) -> ! {
693crate::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!(
694"`tcx.{name}({key:?})` is not supported for this key;\n\
695 hint: Queries can be either made to the local crate, or the external crate. \
696 This error means you tried to use it for one that's not supported.\n\
697 If that's not the case, {name} was likely never assigned to a provider function.\n",
698 )699}
700701#[cold]
702pub(crate) fn default_extern_query(name: &str, key: &dyn std::fmt::Debug) -> ! {
703crate::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!(
704"`tcx.{name}({key:?})` unsupported by its crate; \
705 perhaps the `{name}` query was never assigned a provider function",
706 )707}