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_macros::HashStable;
11use rustc_span::{ErrorGuaranteed, Span};
12pub use sealed::IntoQueryParam;
1314use crate::dep_graph::{DepKind, DepNodeIndex, SerializedDepNodeIndex};
15use crate::ich::StableHashingContext;
16use crate::queries::{ExternProviders, Providers, QueryArenas, QueryVTables};
17use crate::query::on_disk_cache::OnDiskCache;
18use crate::query::stack::{QueryStackDeferred, QueryStackFrame, QueryStackFrameExtra};
19use crate::query::{QueryCache, QueryInfo, QueryJob};
20use crate::ty::TyCtxt;
2122/// For a particular query, keeps track of "active" keys, i.e. keys whose
23/// evaluation has started but has not yet finished successfully.
24///
25/// (Successful query evaluation for a key is represented by an entry in the
26/// query's in-memory cache.)
27pub struct QueryState<'tcx, K> {
28pub active: Sharded<HashTable<(K, ActiveKeyStatus<'tcx>)>>,
29}
3031impl<'tcx, K> Defaultfor QueryState<'tcx, K> {
32fn default() -> QueryState<'tcx, K> {
33QueryState { active: Default::default() }
34 }
35}
3637/// For a particular query and key, tracks the status of a query evaluation
38/// that has started, but has not yet finished successfully.
39///
40/// (Successful query evaluation for a key is represented by an entry in the
41/// query's in-memory cache.)
42pub enum ActiveKeyStatus<'tcx> {
43/// Some thread is already evaluating the query for this key.
44 ///
45 /// The enclosed [`QueryJob`] can be used to wait for it to finish.
46Started(QueryJob<'tcx>),
4748/// The query panicked. Queries trying to wait on this will raise a fatal error which will
49 /// silently panic.
50Poisoned,
51}
5253/// How a particular query deals with query cycle errors.
54///
55/// Inspected by the code that actually handles cycle errors, to decide what
56/// approach to use.
57#[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)]
58pub enum CycleErrorHandling {
59 Error,
60 DelayBug,
61 Stash,
62}
6364#[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)]
65pub struct CycleError<I = QueryStackFrameExtra> {
66/// The query and related span that uses the cycle.
67pub usage: Option<(Span, QueryStackFrame<I>)>,
68pub cycle: Vec<QueryInfo<I>>,
69}
7071impl<'tcx> CycleError<QueryStackDeferred<'tcx>> {
72pub fn lift(&self) -> CycleError<QueryStackFrameExtra> {
73CycleError {
74 usage: self.usage.as_ref().map(|(span, frame)| (*span, frame.lift())),
75 cycle: self.cycle.iter().map(|info| info.lift()).collect(),
76 }
77 }
78}
7980#[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)]
81pub enum QueryMode {
82/// This is a normal query call to `tcx.$query(..)` or `tcx.at(span).$query(..)`.
83Get,
84/// This is a call to `tcx.ensure_ok().$query(..)` or `tcx.ensure_done().$query(..)`.
85Ensure { ensure_mode: EnsureMode },
86}
8788/// Distinguishes between `tcx.ensure_ok()` and `tcx.ensure_done()` in shared
89/// code paths that handle both modes.
90#[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)]
91pub enum EnsureMode {
92/// Corresponds to [`TyCtxt::ensure_ok`].
93Ok,
94/// Corresponds to [`TyCtxt::ensure_done`].
95Done,
96}
9798/// Stores data and metadata (e.g. function pointers) for a particular query.
99pub struct QueryVTable<'tcx, C: QueryCache> {
100pub name: &'static str,
101102/// True if this query has the `anon` modifier.
103pub anon: bool,
104/// True if this query has the `eval_always` modifier.
105pub eval_always: bool,
106/// True if this query has the `depth_limit` modifier.
107pub depth_limit: bool,
108/// True if this query has the `feedable` modifier.
109pub feedable: bool,
110111pub dep_kind: DepKind,
112/// How this query deals with query cycle errors.
113pub cycle_error_handling: CycleErrorHandling,
114pub state: QueryState<'tcx, C::Key>,
115pub cache: C,
116117/// Function pointer that actually calls this query's provider.
118 /// Also performs some associated secondary tasks; see the macro-defined
119 /// implementation in `mod invoke_provider_fn` for more details.
120 ///
121 /// This should be the only code that calls the provider function.
122pub invoke_provider_fn: fn(tcx: TyCtxt<'tcx>, key: C::Key) -> C::Value,
123124pub will_cache_on_disk_for_key_fn: fn(tcx: TyCtxt<'tcx>, key: C::Key) -> bool,
125126pub try_load_from_disk_fn: fn(
127 tcx: TyCtxt<'tcx>,
128 key: C::Key,
129 prev_index: SerializedDepNodeIndex,
130 index: DepNodeIndex,
131 ) -> Option<C::Value>,
132133pub is_loadable_from_disk_fn:
134fn(tcx: TyCtxt<'tcx>, key: C::Key, index: SerializedDepNodeIndex) -> bool,
135136/// Function pointer that hashes this query's result values.
137 ///
138 /// For `no_hash` queries, this function pointer is None.
139pub hash_value_fn: Option<fn(&mut StableHashingContext<'_>, &C::Value) -> Fingerprint>,
140141pub value_from_cycle_error:
142fn(tcx: TyCtxt<'tcx>, cycle_error: CycleError, guar: ErrorGuaranteed) -> C::Value,
143pub format_value: fn(&C::Value) -> String,
144145/// Formats a human-readable description of this query and its key, as
146 /// specified by the `desc` query modifier.
147 ///
148 /// Used when reporting query cycle errors and similar problems.
149pub description_fn: fn(TyCtxt<'tcx>, C::Key) -> String,
150151/// Function pointer that is called by the query methods on [`TyCtxt`] and
152 /// friends[^1], after they have checked the in-memory cache and found no
153 /// existing value for this key.
154 ///
155 /// Transitive responsibilities include trying to load a disk-cached value
156 /// if possible (incremental only), invoking the query provider if necessary,
157 /// and putting the obtained value into the in-memory cache.
158 ///
159 /// [^1]: [`TyCtxt`], [`TyCtxtAt`], [`TyCtxtEnsureOk`], [`TyCtxtEnsureDone`]
160pub execute_query_fn: fn(TyCtxt<'tcx>, Span, C::Key, QueryMode) -> Option<C::Value>,
161}
162163impl<'tcx, C: QueryCache> fmt::Debugfor QueryVTable<'tcx, C> {
164fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
165// When debug-printing a query vtable (e.g. for ICE or tracing),
166 // just print the query name to know what query we're dealing with.
167 // The other fields and flags are probably just unhelpful noise.
168 //
169 // If there is need for a more detailed dump of all flags and fields,
170 // consider writing a separate dump method and calling it explicitly.
171f.write_str(self.name)
172 }
173}
174175pub struct QuerySystem<'tcx> {
176pub arenas: WorkerLocal<QueryArenas<'tcx>>,
177pub query_vtables: QueryVTables<'tcx>,
178179/// This provides access to the incremental compilation on-disk cache for query results.
180 /// Do not access this directly. It is only meant to be used by
181 /// `DepGraph::try_mark_green()` and the query infrastructure.
182 /// This is `None` if we are not incremental compilation mode
183pub on_disk_cache: Option<OnDiskCache>,
184185pub local_providers: Providers,
186pub extern_providers: ExternProviders,
187188pub jobs: AtomicU64,
189}
190191#[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)]
192pub struct TyCtxtAt<'tcx> {
193pub tcx: TyCtxt<'tcx>,
194pub span: Span,
195}
196197impl<'tcx> Dereffor TyCtxtAt<'tcx> {
198type Target = TyCtxt<'tcx>;
199#[inline(always)]
200fn deref(&self) -> &Self::Target {
201&self.tcx
202 }
203}
204205#[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)]
206#[must_use]
207pub struct TyCtxtEnsureOk<'tcx> {
208pub tcx: TyCtxt<'tcx>,
209}
210211#[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)]
212#[must_use]
213pub struct TyCtxtEnsureResult<'tcx> {
214pub tcx: TyCtxt<'tcx>,
215}
216217#[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)]
218#[must_use]
219pub struct TyCtxtEnsureDone<'tcx> {
220pub tcx: TyCtxt<'tcx>,
221}
222223impl<'tcx> TyCtxt<'tcx> {
224/// 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 in a special "ensure done" mode, for callers
262 /// that don't need the return value and just want to guarantee that the
263 /// query won't be executed in the future, by executing it now if necessary.
264 ///
265 /// This is useful for queries that read from a [`Steal`] value, to ensure
266 /// that they are executed before the query that will steal the value.
267 ///
268 /// Unlike [`Self::ensure_ok`], a query with all-green inputs will only be
269 /// skipped if its return value is stored in the disk-cache. This is still
270 /// more efficient than a regular query, because in that situation the
271 /// return value doesn't necessarily need to be decoded.
272 ///
273 /// (As with all query calls, execution is also skipped if the query result
274 /// is already cached in memory.)
275 ///
276 /// [`Steal`]: rustc_data_structures::steal::Steal
277#[inline(always)]
278pub fn ensure_done(self) -> TyCtxtEnsureDone<'tcx> {
279TyCtxtEnsureDone { tcx: self }
280 }
281282/// Returns a transparent wrapper for `TyCtxt` which uses
283 /// `span` as the location of queries performed through it.
284#[inline(always)]
285pub fn at(self, span: Span) -> TyCtxtAt<'tcx> {
286TyCtxtAt { tcx: self, span }
287 }
288}
289290macro_rules!query_helper_param_ty {
291 (DefId) => { impl $crate::query::IntoQueryParam<DefId> };
292 (LocalDefId) => { impl $crate::query::IntoQueryParam<LocalDefId> };
293 ($K:ty) => { $K };
294}
295296macro_rules!define_callbacks {
297 (
298// You might expect the key to be `$K:ty`, but it needs to be `$($K:tt)*` so that
299 // `query_helper_param_ty!` can match on specific type names.
300queries {
301 $(
302 $(#[$attr:meta])*
303fn $name:ident($($K:tt)*) -> $V:ty
304 {
305// Search for (QMODLIST) to find all occurrences of this query modifier list.
306anon: $anon:literal,
307 arena_cache: $arena_cache:literal,
308 cache_on_disk: $cache_on_disk:literal,
309 cycle_error_handling: $cycle_error_handling:ident,
310 depth_limit: $depth_limit:literal,
311 eval_always: $eval_always:literal,
312 feedable: $feedable:literal,
313 no_hash: $no_hash:literal,
314 returns_error_guaranteed: $returns_error_guaranteed:literal,
315 separate_provide_extern: $separate_provide_extern:literal,
316 }
317 )*
318 }
319// Non-queries are unused here.
320non_queries { $($_:tt)* }
321 ) => {
322 $(
323#[allow(unused_lifetimes)]
324pub mod $name {
325use super::*;
326use $crate::query::erase::{self, Erased};
327328pub type Key<'tcx> = $($K)*;
329pub type Value<'tcx> = $V;
330331/// Key type used by provider functions in `local_providers`.
332 /// This query has the `separate_provide_extern` modifier.
333#[cfg($separate_provide_extern)]
334pub type LocalKey<'tcx> =
335 <Key<'tcx> as $crate::query::AsLocalQueryKey>::LocalQueryKey;
336/// Key type used by provider functions in `local_providers`.
337#[cfg(not($separate_provide_extern))]
338pub type LocalKey<'tcx> = Key<'tcx>;
339340/// Type returned from query providers and loaded from disk-cache.
341#[cfg($arena_cache)]
342pub type ProvidedValue<'tcx> =
343 <Value<'tcx> as $crate::query::arena_cached::ArenaCached<'tcx>>::Provided;
344/// Type returned from query providers and loaded from disk-cache.
345#[cfg(not($arena_cache))]
346pub type ProvidedValue<'tcx> = Value<'tcx>;
347348/// This helper function takes a value returned by the query provider
349 /// (or loaded from disk, or supplied by query feeding), allocates
350 /// it in an arena if requested by the `arena_cache` modifier, and
351 /// then returns an erased copy of it.
352#[inline(always)]
353pub fn provided_to_erased<'tcx>(
354 tcx: TyCtxt<'tcx>,
355 provided_value: ProvidedValue<'tcx>,
356 ) -> Erased<Value<'tcx>> {
357// For queries with the `arena_cache` modifier, store the
358 // provided value in an arena and get a reference to it.
359#[cfg($arena_cache)]
360let value: Value<'tcx> = {
361use $crate::query::arena_cached::ArenaCached;
362 <Value<'tcx> as ArenaCached>::alloc_in_arena(
363 tcx,
364&tcx.query_system.arenas.$name,
365 provided_value,
366 )
367 };
368369// Otherwise, the provided value is the value (and `tcx` is unused).
370#[cfg(not($arena_cache))]
371let value: Value<'tcx> = {
372let _ = tcx;
373 provided_value
374 };
375376 erase::erase_val(value)
377 }
378379pub type Cache<'tcx> =
380 <Key<'tcx> as $crate::query::QueryKey>::Cache<Erased<Value<'tcx>>>;
381382// Ensure that keys grow no larger than 88 bytes by accident.
383 // Increase this limit if necessary, but do try to keep the size low if possible
384#[cfg(target_pointer_width = "64")]
385const _: () = {
386if size_of::<Key<'static>>() > 88 {
387panic!("{}", concat!(
388"the query `",
389stringify!($name),
390"` has a key type `",
391stringify!($($K)*),
392"` that is too large"
393));
394 }
395 };
396397// Ensure that values grow no larger than 64 bytes by accident.
398 // Increase this limit if necessary, but do try to keep the size low if possible
399#[cfg(target_pointer_width = "64")]
400 #[cfg(not(feature = "rustc_randomized_layouts"))]
401const _: () = {
402if size_of::<Value<'static>>() > 64 {
403panic!("{}", concat!(
404"the query `",
405stringify!($name),
406"` has a value type `",
407stringify!($V),
408"` that is too large"
409));
410 }
411 };
412 }
413 )*
414415/// Holds per-query arenas for queries with the `arena_cache` modifier.
416#[derive(Default)]
417pub struct QueryArenas<'tcx> {
418 $(
419// Use the `ArenaCached` helper trait to determine the arena's value type.
420#[cfg($arena_cache)]
421pub $name: TypedArena<
422 <$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Allocated,
423 >,
424 )*
425 }
426427impl<'tcx> $crate::query::TyCtxtEnsureOk<'tcx> {
428 $(
429 $(#[$attr])*
430#[inline(always)]
431pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
432crate::query::inner::query_ensure_ok_or_done(
433self.tcx,
434&self.tcx.query_system.query_vtables.$name,
435$crate::query::IntoQueryParam::into_query_param(key),
436$crate::query::EnsureMode::Ok,
437 )
438 }
439 )*
440 }
441442// Only defined when the `ensure_result` modifier is present.
443impl<'tcx> $crate::query::TyCtxtEnsureResult<'tcx> {
444 $(
445#[cfg($returns_error_guaranteed)]
446$(#[$attr])*
447#[inline(always)]
448pub fn $name(
449self,
450 key: query_helper_param_ty!($($K)*),
451 ) -> Result<(), rustc_errors::ErrorGuaranteed> {
452crate::query::inner::query_ensure_result(
453self.tcx,
454&self.tcx.query_system.query_vtables.$name,
455$crate::query::IntoQueryParam::into_query_param(key),
456 )
457 }
458 )*
459 }
460461impl<'tcx> $crate::query::TyCtxtEnsureDone<'tcx> {
462 $(
463 $(#[$attr])*
464#[inline(always)]
465pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
466crate::query::inner::query_ensure_ok_or_done(
467self.tcx,
468&self.tcx.query_system.query_vtables.$name,
469$crate::query::IntoQueryParam::into_query_param(key),
470$crate::query::EnsureMode::Done,
471 );
472 }
473 )*
474 }
475476impl<'tcx> TyCtxt<'tcx> {
477 $(
478 $(#[$attr])*
479#[inline(always)]
480 #[must_use]
481pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V {
482self.at(DUMMY_SP).$name(key)
483 }
484 )*
485 }
486487impl<'tcx> $crate::query::TyCtxtAt<'tcx> {
488 $(
489 $(#[$attr])*
490#[inline(always)]
491pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V {
492use $crate::query::{erase, inner};
493494 erase::restore_val::<$V>(inner::query_get_at(
495self.tcx,
496self.span,
497&self.tcx.query_system.query_vtables.$name,
498$crate::query::IntoQueryParam::into_query_param(key),
499 ))
500 }
501 )*
502 }
503504 $(
505#[cfg($feedable)]
506impl<'tcx, K: $crate::query::IntoQueryParam<$name::Key<'tcx>> + Copy>
507TyCtxtFeed<'tcx, K>
508 {
509 $(#[$attr])*
510#[inline(always)]
511pub fn $name(self, value: $name::ProvidedValue<'tcx>) {
512let key = self.key().into_query_param();
513let erased_value = $name::provided_to_erased(self.tcx, value);
514$crate::query::inner::query_feed(
515self.tcx,
516 dep_graph::DepKind::$name,
517&self.tcx.query_system.query_vtables.$name,
518 key,
519 erased_value,
520 );
521 }
522 }
523 )*
524525/// Holds a `QueryVTable` for each query.
526pub struct QueryVTables<'tcx> {
527 $(
528pub $name: ::rustc_middle::query::plumbing::QueryVTable<'tcx, $name::Cache<'tcx>>,
529 )*
530 }
531532pub struct Providers {
533 $(
534/// This is the provider for the query. Use `Find references` on this to
535 /// navigate between the provider assignment and the query definition.
536pub $name: for<'tcx> fn(
537TyCtxt<'tcx>,
538$name::LocalKey<'tcx>,
539 ) -> $name::ProvidedValue<'tcx>,
540 )*
541 }
542543pub struct ExternProviders {
544 $(
545#[cfg($separate_provide_extern)]
546pub $name: for<'tcx> fn(
547TyCtxt<'tcx>,
548$name::Key<'tcx>,
549 ) -> $name::ProvidedValue<'tcx>,
550 )*
551 }
552553impl Default for Providers {
554fn default() -> Self {
555 Providers {
556 $(
557$name: |_, key| {
558$crate::query::plumbing::default_query(stringify!($name), &key)
559 },
560 )*
561 }
562 }
563 }
564565impl Default for ExternProviders {
566fn default() -> Self {
567 ExternProviders {
568 $(
569#[cfg($separate_provide_extern)]
570$name: |_, key| $crate::query::plumbing::default_extern_query(
571stringify!($name),
572&key,
573 ),
574 )*
575 }
576 }
577 }
578579impl Copy for Providers {}
580impl Clone for Providers {
581fn clone(&self) -> Self { *self }
582 }
583584impl Copy for ExternProviders {}
585impl Clone for ExternProviders {
586fn clone(&self) -> Self { *self }
587 }
588 };
589}
590591mod sealed {
592use rustc_hir::def_id::{LocalModDefId, ModDefId};
593594use super::{DefId, LocalDefId, OwnerId};
595596/// An analogue of the `Into` trait that's intended only for query parameters.
597 ///
598 /// This exists to allow queries to accept either `DefId` or `LocalDefId` while requiring that the
599 /// user call `to_def_id` to convert between them everywhere else.
600pub trait IntoQueryParam<P> {
601fn into_query_param(self) -> P;
602 }
603604impl<P> IntoQueryParam<P> for P {
605#[inline(always)]
606fn into_query_param(self) -> P {
607self608 }
609 }
610611impl IntoQueryParam<LocalDefId> for OwnerId {
612#[inline(always)]
613fn into_query_param(self) -> LocalDefId {
614self.def_id
615 }
616 }
617618impl IntoQueryParam<DefId> for LocalDefId {
619#[inline(always)]
620fn into_query_param(self) -> DefId {
621self.to_def_id()
622 }
623 }
624625impl IntoQueryParam<DefId> for OwnerId {
626#[inline(always)]
627fn into_query_param(self) -> DefId {
628self.to_def_id()
629 }
630 }
631632impl IntoQueryParam<DefId> for ModDefId {
633#[inline(always)]
634fn into_query_param(self) -> DefId {
635self.to_def_id()
636 }
637 }
638639impl IntoQueryParam<DefId> for LocalModDefId {
640#[inline(always)]
641fn into_query_param(self) -> DefId {
642self.to_def_id()
643 }
644 }
645646impl IntoQueryParam<LocalDefId> for LocalModDefId {
647#[inline(always)]
648fn into_query_param(self) -> LocalDefId {
649self.into()
650 }
651 }
652}
653654#[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)]
655pub struct CyclePlaceholder(pub ErrorGuaranteed);
656657#[cold]
658pub(crate) fn default_query(name: &str, key: &dyn std::fmt::Debug) -> ! {
659crate::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!(
660"`tcx.{name}({key:?})` is not supported for this key;\n\
661 hint: Queries can be either made to the local crate, or the external crate. \
662 This error means you tried to use it for one that's not supported.\n\
663 If that's not the case, {name} was likely never assigned to a provider function.\n",
664 )665}
666667#[cold]
668pub(crate) fn default_extern_query(name: &str, key: &dyn std::fmt::Debug) -> ! {
669crate::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!(
670"`tcx.{name}({key:?})` unsupported by its crate; \
671 perhaps the `{name}` query was never assigned a provider function",
672 )673}