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_hir::def_id::{DefId, LocalDefId};
9use rustc_hir::hir_id::OwnerId;
10use rustc_span::{ErrorGuaranteed, Span};
11pub use sealed::IntoQueryParam;
1213use crate::dep_graph::{DepKind, DepNodeIndex, SerializedDepNodeIndex};
14use crate::ich::StableHashingContext;
15use crate::queries::{ExternProviders, Providers, QueryArenas, QueryVTables};
16use crate::query::on_disk_cache::OnDiskCache;
17use crate::query::stack::{QueryStackDeferred, QueryStackFrame, QueryStackFrameExtra};
18use crate::query::{QueryCache, QueryInfo, QueryJob};
19use crate::ty::TyCtxt;
2021/// For a particular query, keeps track of "active" keys, i.e. keys whose
22/// evaluation has started but has not yet finished successfully.
23///
24/// (Successful query evaluation for a key is represented by an entry in the
25/// query's in-memory cache.)
26pub struct QueryState<'tcx, K> {
27pub active: Sharded<HashTable<(K, ActiveKeyStatus<'tcx>)>>,
28}
2930impl<'tcx, K> Defaultfor QueryState<'tcx, K> {
31fn default() -> QueryState<'tcx, K> {
32QueryState { active: Default::default() }
33 }
34}
3536/// For a particular query and key, tracks the status of a query evaluation
37/// that has started, but has not yet finished successfully.
38///
39/// (Successful query evaluation for a key is represented by an entry in the
40/// query's in-memory cache.)
41pub enum ActiveKeyStatus<'tcx> {
42/// Some thread is already evaluating the query for this key.
43 ///
44 /// The enclosed [`QueryJob`] can be used to wait for it to finish.
45Started(QueryJob<'tcx>),
4647/// The query panicked. Queries trying to wait on this will raise a fatal error which will
48 /// silently panic.
49Poisoned,
50}
5152/// How a particular query deals with query cycle errors.
53///
54/// Inspected by the code that actually handles cycle errors, to decide what
55/// approach to use.
56#[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)]
57pub enum CycleErrorHandling {
58 Error,
59 DelayBug,
60}
6162#[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)]
63pub struct CycleError<I = QueryStackFrameExtra> {
64/// The query and related span that uses the cycle.
65pub usage: Option<(Span, QueryStackFrame<I>)>,
66pub cycle: Vec<QueryInfo<I>>,
67}
6869impl<'tcx> CycleError<QueryStackDeferred<'tcx>> {
70pub fn lift(&self) -> CycleError<QueryStackFrameExtra> {
71CycleError {
72 usage: self.usage.as_ref().map(|(span, frame)| (*span, frame.lift())),
73 cycle: self.cycle.iter().map(|info| info.lift()).collect(),
74 }
75 }
76}
7778#[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)]
79pub enum QueryMode {
80/// This is a normal query call to `tcx.$query(..)` or `tcx.at(span).$query(..)`.
81Get,
82/// This is a call to `tcx.ensure_ok().$query(..)` or `tcx.ensure_done().$query(..)`.
83Ensure { ensure_mode: EnsureMode },
84}
8586/// Distinguishes between `tcx.ensure_ok()` and `tcx.ensure_done()` in shared
87/// code paths that handle both modes.
88#[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)]
89pub enum EnsureMode {
90/// Corresponds to [`TyCtxt::ensure_ok`].
91Ok,
92/// Corresponds to [`TyCtxt::ensure_done`].
93Done,
94}
9596/// Stores data and metadata (e.g. function pointers) for a particular query.
97pub struct QueryVTable<'tcx, C: QueryCache> {
98pub name: &'static str,
99100/// True if this query has the `anon` modifier.
101pub anon: bool,
102/// True if this query has the `eval_always` modifier.
103pub eval_always: bool,
104/// True if this query has the `depth_limit` modifier.
105pub depth_limit: bool,
106/// True if this query has the `feedable` modifier.
107pub feedable: bool,
108109pub dep_kind: DepKind,
110/// How this query deals with query cycle errors.
111pub cycle_error_handling: CycleErrorHandling,
112pub state: QueryState<'tcx, C::Key>,
113pub cache: C,
114115/// Function pointer that actually calls this query's provider.
116 /// Also performs some associated secondary tasks; see the macro-defined
117 /// implementation in `mod invoke_provider_fn` for more details.
118 ///
119 /// This should be the only code that calls the provider function.
120pub invoke_provider_fn: fn(tcx: TyCtxt<'tcx>, key: C::Key) -> C::Value,
121122pub will_cache_on_disk_for_key_fn: fn(tcx: TyCtxt<'tcx>, key: C::Key) -> bool,
123124pub try_load_from_disk_fn: fn(
125 tcx: TyCtxt<'tcx>,
126 key: C::Key,
127 prev_index: SerializedDepNodeIndex,
128 index: DepNodeIndex,
129 ) -> Option<C::Value>,
130131pub is_loadable_from_disk_fn:
132fn(tcx: TyCtxt<'tcx>, key: C::Key, index: SerializedDepNodeIndex) -> bool,
133134/// Function pointer that hashes this query's result values.
135 ///
136 /// For `no_hash` queries, this function pointer is None.
137pub hash_value_fn: Option<fn(&mut StableHashingContext<'_>, &C::Value) -> Fingerprint>,
138139pub value_from_cycle_error: fn(
140 tcx: TyCtxt<'tcx>,
141 key: C::Key,
142 cycle_error: CycleError,
143 guar: ErrorGuaranteed,
144 ) -> C::Value,
145pub format_value: fn(&C::Value) -> String,
146147/// Formats a human-readable description of this query and its key, as
148 /// specified by the `desc` query modifier.
149 ///
150 /// Used when reporting query cycle errors and similar problems.
151pub description_fn: fn(TyCtxt<'tcx>, C::Key) -> String,
152153/// Function pointer that is called by the query methods on [`TyCtxt`] and
154 /// friends[^1], after they have checked the in-memory cache and found no
155 /// existing value for this key.
156 ///
157 /// Transitive responsibilities include trying to load a disk-cached value
158 /// if possible (incremental only), invoking the query provider if necessary,
159 /// and putting the obtained value into the in-memory cache.
160 ///
161 /// [^1]: [`TyCtxt`], [`TyCtxtAt`], [`TyCtxtEnsureOk`], [`TyCtxtEnsureDone`]
162pub execute_query_fn: fn(TyCtxt<'tcx>, Span, C::Key, QueryMode) -> Option<C::Value>,
163}
164165impl<'tcx, C: QueryCache> fmt::Debugfor QueryVTable<'tcx, C> {
166fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
167// When debug-printing a query vtable (e.g. for ICE or tracing),
168 // just print the query name to know what query we're dealing with.
169 // The other fields and flags are probably just unhelpful noise.
170 //
171 // If there is need for a more detailed dump of all flags and fields,
172 // consider writing a separate dump method and calling it explicitly.
173f.write_str(self.name)
174 }
175}
176177pub struct QuerySystem<'tcx> {
178pub arenas: WorkerLocal<QueryArenas<'tcx>>,
179pub query_vtables: QueryVTables<'tcx>,
180181/// This provides access to the incremental compilation on-disk cache for query results.
182 /// Do not access this directly. It is only meant to be used by
183 /// `DepGraph::try_mark_green()` and the query infrastructure.
184 /// This is `None` if we are not incremental compilation mode
185pub on_disk_cache: Option<OnDiskCache>,
186187pub local_providers: Providers,
188pub extern_providers: ExternProviders,
189190pub jobs: AtomicU64,
191}
192193#[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)]
194pub struct TyCtxtAt<'tcx> {
195pub tcx: TyCtxt<'tcx>,
196pub span: Span,
197}
198199impl<'tcx> Dereffor TyCtxtAt<'tcx> {
200type Target = TyCtxt<'tcx>;
201#[inline(always)]
202fn deref(&self) -> &Self::Target {
203&self.tcx
204 }
205}
206207#[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)]
208#[must_use]
209pub struct TyCtxtEnsureOk<'tcx> {
210pub tcx: TyCtxt<'tcx>,
211}
212213#[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)]
214#[must_use]
215pub struct TyCtxtEnsureResult<'tcx> {
216pub tcx: TyCtxt<'tcx>,
217}
218219#[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)]
220#[must_use]
221pub struct TyCtxtEnsureDone<'tcx> {
222pub tcx: TyCtxt<'tcx>,
223}
224225impl<'tcx> TyCtxt<'tcx> {
226/// 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 }
283284/// Returns a transparent wrapper for `TyCtxt` which uses
285 /// `span` as the location of queries performed through it.
286#[inline(always)]
287pub fn at(self, span: Span) -> TyCtxtAt<'tcx> {
288TyCtxtAt { tcx: self, span }
289 }
290}
291292macro_rules!query_helper_param_ty {
293 (DefId) => { impl $crate::query::IntoQueryParam<DefId> };
294 (LocalDefId) => { impl $crate::query::IntoQueryParam<LocalDefId> };
295 ($K:ty) => { $K };
296}
297298macro_rules!define_callbacks {
299 (
300// You might expect the key to be `$K:ty`, but it needs to be `$($K:tt)*` so that
301 // `query_helper_param_ty!` can match on specific type names.
302queries {
303 $(
304 $(#[$attr:meta])*
305fn $name:ident($($K:tt)*) -> $V:ty
306 {
307// Search for (QMODLIST) to find all occurrences of this query modifier list.
308anon: $anon:literal,
309 arena_cache: $arena_cache:literal,
310 cache_on_disk: $cache_on_disk:literal,
311 cycle_error_handling: $cycle_error_handling:ident,
312 depth_limit: $depth_limit:literal,
313 eval_always: $eval_always:literal,
314 feedable: $feedable:literal,
315 no_hash: $no_hash:literal,
316 returns_error_guaranteed: $returns_error_guaranteed:literal,
317 separate_provide_extern: $separate_provide_extern:literal,
318 }
319 )*
320 }
321// Non-queries are unused here.
322non_queries { $($_:tt)* }
323 ) => {
324 $(
325#[allow(unused_lifetimes)]
326pub mod $name {
327use super::*;
328use $crate::query::erase::{self, Erased};
329330pub type Key<'tcx> = $($K)*;
331pub type Value<'tcx> = $V;
332333/// Key type used by provider functions in `local_providers`.
334 /// This query has the `separate_provide_extern` modifier.
335#[cfg($separate_provide_extern)]
336pub type LocalKey<'tcx> =
337 <Key<'tcx> as $crate::query::AsLocalQueryKey>::LocalQueryKey;
338/// Key type used by provider functions in `local_providers`.
339#[cfg(not($separate_provide_extern))]
340pub type LocalKey<'tcx> = Key<'tcx>;
341342/// Type returned from query providers and loaded from disk-cache.
343#[cfg($arena_cache)]
344pub type ProvidedValue<'tcx> =
345 <Value<'tcx> as $crate::query::arena_cached::ArenaCached<'tcx>>::Provided;
346/// Type returned from query providers and loaded from disk-cache.
347#[cfg(not($arena_cache))]
348pub type ProvidedValue<'tcx> = Value<'tcx>;
349350/// This helper function takes a value returned by the query provider
351 /// (or loaded from disk, or supplied by query feeding), allocates
352 /// it in an arena if requested by the `arena_cache` modifier, and
353 /// then returns an erased copy of it.
354#[inline(always)]
355pub fn provided_to_erased<'tcx>(
356 tcx: TyCtxt<'tcx>,
357 provided_value: ProvidedValue<'tcx>,
358 ) -> Erased<Value<'tcx>> {
359// For queries with the `arena_cache` modifier, store the
360 // provided value in an arena and get a reference to it.
361#[cfg($arena_cache)]
362let value: Value<'tcx> = {
363use $crate::query::arena_cached::ArenaCached;
364 <Value<'tcx> as ArenaCached>::alloc_in_arena(
365 tcx,
366&tcx.query_system.arenas.$name,
367 provided_value,
368 )
369 };
370371// Otherwise, the provided value is the value (and `tcx` is unused).
372#[cfg(not($arena_cache))]
373let value: Value<'tcx> = {
374let _ = tcx;
375 provided_value
376 };
377378 erase::erase_val(value)
379 }
380381pub type Cache<'tcx> =
382 <Key<'tcx> as $crate::query::QueryKey>::Cache<Erased<Value<'tcx>>>;
383384// Ensure that keys grow no larger than 88 bytes by accident.
385 // Increase this limit if necessary, but do try to keep the size low if possible
386#[cfg(target_pointer_width = "64")]
387const _: () = {
388if size_of::<Key<'static>>() > 88 {
389panic!("{}", concat!(
390"the query `",
391stringify!($name),
392"` has a key type `",
393stringify!($($K)*),
394"` that is too large"
395));
396 }
397 };
398399// Ensure that values grow no larger than 64 bytes by accident.
400 // Increase this limit if necessary, but do try to keep the size low if possible
401#[cfg(target_pointer_width = "64")]
402 #[cfg(not(feature = "rustc_randomized_layouts"))]
403const _: () = {
404if size_of::<Value<'static>>() > 64 {
405panic!("{}", concat!(
406"the query `",
407stringify!($name),
408"` has a value type `",
409stringify!($V),
410"` that is too large"
411));
412 }
413 };
414 }
415 )*
416417/// Holds per-query arenas for queries with the `arena_cache` modifier.
418#[derive(Default)]
419pub struct QueryArenas<'tcx> {
420 $(
421// Use the `ArenaCached` helper trait to determine the arena's value type.
422#[cfg($arena_cache)]
423pub $name: TypedArena<
424 <$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Allocated,
425 >,
426 )*
427 }
428429impl<'tcx> $crate::query::TyCtxtEnsureOk<'tcx> {
430 $(
431 $(#[$attr])*
432#[inline(always)]
433pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
434crate::query::inner::query_ensure_ok_or_done(
435self.tcx,
436&self.tcx.query_system.query_vtables.$name,
437$crate::query::IntoQueryParam::into_query_param(key),
438$crate::query::EnsureMode::Ok,
439 )
440 }
441 )*
442 }
443444// Only defined when the `ensure_result` modifier is present.
445impl<'tcx> $crate::query::TyCtxtEnsureResult<'tcx> {
446 $(
447#[cfg($returns_error_guaranteed)]
448$(#[$attr])*
449#[inline(always)]
450pub fn $name(
451self,
452 key: query_helper_param_ty!($($K)*),
453 ) -> Result<(), rustc_errors::ErrorGuaranteed> {
454crate::query::inner::query_ensure_result(
455self.tcx,
456&self.tcx.query_system.query_vtables.$name,
457$crate::query::IntoQueryParam::into_query_param(key),
458 )
459 }
460 )*
461 }
462463impl<'tcx> $crate::query::TyCtxtEnsureDone<'tcx> {
464 $(
465 $(#[$attr])*
466#[inline(always)]
467pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
468crate::query::inner::query_ensure_ok_or_done(
469self.tcx,
470&self.tcx.query_system.query_vtables.$name,
471$crate::query::IntoQueryParam::into_query_param(key),
472$crate::query::EnsureMode::Done,
473 );
474 }
475 )*
476 }
477478impl<'tcx> TyCtxt<'tcx> {
479 $(
480 $(#[$attr])*
481#[inline(always)]
482 #[must_use]
483pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V {
484self.at(DUMMY_SP).$name(key)
485 }
486 )*
487 }
488489impl<'tcx> $crate::query::TyCtxtAt<'tcx> {
490 $(
491 $(#[$attr])*
492#[inline(always)]
493pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V {
494use $crate::query::{erase, inner};
495496 erase::restore_val::<$V>(inner::query_get_at(
497self.tcx,
498self.span,
499&self.tcx.query_system.query_vtables.$name,
500$crate::query::IntoQueryParam::into_query_param(key),
501 ))
502 }
503 )*
504 }
505506 $(
507#[cfg($feedable)]
508impl<'tcx, K: $crate::query::IntoQueryParam<$name::Key<'tcx>> + Copy>
509TyCtxtFeed<'tcx, K>
510 {
511 $(#[$attr])*
512#[inline(always)]
513pub fn $name(self, value: $name::ProvidedValue<'tcx>) {
514let key = self.key().into_query_param();
515let erased_value = $name::provided_to_erased(self.tcx, value);
516$crate::query::inner::query_feed(
517self.tcx,
518 dep_graph::DepKind::$name,
519&self.tcx.query_system.query_vtables.$name,
520 key,
521 erased_value,
522 );
523 }
524 }
525 )*
526527/// Holds a `QueryVTable` for each query.
528pub struct QueryVTables<'tcx> {
529 $(
530pub $name: ::rustc_middle::query::plumbing::QueryVTable<'tcx, $name::Cache<'tcx>>,
531 )*
532 }
533534pub struct Providers {
535 $(
536/// This is the provider for the query. Use `Find references` on this to
537 /// navigate between the provider assignment and the query definition.
538pub $name: for<'tcx> fn(
539TyCtxt<'tcx>,
540$name::LocalKey<'tcx>,
541 ) -> $name::ProvidedValue<'tcx>,
542 )*
543 }
544545pub struct ExternProviders {
546 $(
547#[cfg($separate_provide_extern)]
548pub $name: for<'tcx> fn(
549TyCtxt<'tcx>,
550$name::Key<'tcx>,
551 ) -> $name::ProvidedValue<'tcx>,
552 )*
553 }
554555impl Default for Providers {
556fn default() -> Self {
557 Providers {
558 $(
559$name: |_, key| {
560$crate::query::plumbing::default_query(stringify!($name), &key)
561 },
562 )*
563 }
564 }
565 }
566567impl Default for ExternProviders {
568fn default() -> Self {
569 ExternProviders {
570 $(
571#[cfg($separate_provide_extern)]
572$name: |_, key| $crate::query::plumbing::default_extern_query(
573stringify!($name),
574&key,
575 ),
576 )*
577 }
578 }
579 }
580581impl Copy for Providers {}
582impl Clone for Providers {
583fn clone(&self) -> Self { *self }
584 }
585586impl Copy for ExternProviders {}
587impl Clone for ExternProviders {
588fn clone(&self) -> Self { *self }
589 }
590 };
591}
592593mod sealed {
594use rustc_hir::def_id::{LocalModDefId, ModDefId};
595596use super::{DefId, LocalDefId, OwnerId};
597598/// An analogue of the `Into` trait that's intended only for query parameters.
599 ///
600 /// This exists to allow queries to accept either `DefId` or `LocalDefId` while requiring that the
601 /// user call `to_def_id` to convert between them everywhere else.
602pub trait IntoQueryParam<P> {
603fn into_query_param(self) -> P;
604 }
605606impl<P> IntoQueryParam<P> for P {
607#[inline(always)]
608fn into_query_param(self) -> P {
609self610 }
611 }
612613impl IntoQueryParam<LocalDefId> for OwnerId {
614#[inline(always)]
615fn into_query_param(self) -> LocalDefId {
616self.def_id
617 }
618 }
619620impl IntoQueryParam<DefId> for LocalDefId {
621#[inline(always)]
622fn into_query_param(self) -> DefId {
623self.to_def_id()
624 }
625 }
626627impl IntoQueryParam<DefId> for OwnerId {
628#[inline(always)]
629fn into_query_param(self) -> DefId {
630self.to_def_id()
631 }
632 }
633634impl IntoQueryParam<DefId> for ModDefId {
635#[inline(always)]
636fn into_query_param(self) -> DefId {
637self.to_def_id()
638 }
639 }
640641impl IntoQueryParam<DefId> for LocalModDefId {
642#[inline(always)]
643fn into_query_param(self) -> DefId {
644self.to_def_id()
645 }
646 }
647648impl IntoQueryParam<LocalDefId> for LocalModDefId {
649#[inline(always)]
650fn into_query_param(self) -> LocalDefId {
651self.into()
652 }
653 }
654}
655656#[cold]
657pub(crate) fn default_query(name: &str, key: &dyn std::fmt::Debug) -> ! {
658crate::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!(
659"`tcx.{name}({key:?})` is not supported for this key;\n\
660 hint: Queries can be either made to the local crate, or the external crate. \
661 This error means you tried to use it for one that's not supported.\n\
662 If that's not the case, {name} was likely never assigned to a provider function.\n",
663 )664}
665666#[cold]
667pub(crate) fn default_extern_query(name: &str, key: &dyn std::fmt::Debug) -> ! {
668crate::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!(
669"`tcx.{name}({key:?})` unsupported by its crate; \
670 perhaps the `{name}` query was never assigned a provider function",
671 )672}