Skip to main content

rustc_middle/query/
plumbing.rs

1use std::ops::Deref;
2
3use rustc_data_structures::sync::{AtomicU64, WorkerLocal};
4use rustc_hir::def_id::{DefId, LocalDefId};
5use rustc_hir::hir_id::OwnerId;
6use rustc_macros::HashStable;
7use rustc_query_system::dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
8pub(crate) use rustc_query_system::query::QueryJobId;
9use rustc_query_system::query::{CycleError, CycleErrorHandling, HashResult, QueryCache};
10use rustc_span::{ErrorGuaranteed, Span};
11pub use sealed::IntoQueryParam;
12
13use crate::dep_graph;
14use crate::dep_graph::DepKind;
15use crate::queries::{
16    ExternProviders, PerQueryVTables, Providers, QueryArenas, QueryCaches, QueryEngine, QueryStates,
17};
18use crate::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex, OnDiskCache};
19use crate::ty::TyCtxt;
20
21pub type WillCacheOnDiskForKeyFn<'tcx, Key> = fn(tcx: TyCtxt<'tcx>, key: &Key) -> bool;
22
23pub type TryLoadFromDiskFn<'tcx, Key, Value> = fn(
24    tcx: TyCtxt<'tcx>,
25    key: &Key,
26    prev_index: SerializedDepNodeIndex,
27    index: DepNodeIndex,
28) -> Option<Value>;
29
30pub type IsLoadableFromDiskFn<'tcx, Key> =
31    fn(tcx: TyCtxt<'tcx>, key: &Key, index: SerializedDepNodeIndex) -> bool;
32
33/// Stores function pointers and other metadata for a particular query.
34///
35/// Used indirectly by query plumbing in `rustc_query_system` via a trait,
36/// and also used directly by query plumbing in `rustc_query_impl`.
37pub struct QueryVTable<'tcx, C: QueryCache> {
38    pub name: &'static str,
39    pub eval_always: bool,
40    pub dep_kind: DepKind,
41    /// How this query deals with query cycle errors.
42    pub cycle_error_handling: CycleErrorHandling,
43    // Offset of this query's state field in the QueryStates struct
44    pub query_state: usize,
45    // Offset of this query's cache field in the QueryCaches struct
46    pub query_cache: usize,
47    pub will_cache_on_disk_for_key_fn: Option<WillCacheOnDiskForKeyFn<'tcx, C::Key>>,
48    pub execute_query: fn(tcx: TyCtxt<'tcx>, k: C::Key) -> C::Value,
49    pub compute_fn: fn(tcx: TyCtxt<'tcx>, key: C::Key) -> C::Value,
50    pub try_load_from_disk_fn: Option<TryLoadFromDiskFn<'tcx, C::Key, C::Value>>,
51    pub is_loadable_from_disk_fn: Option<IsLoadableFromDiskFn<'tcx, C::Key>>,
52    pub hash_result: HashResult<C::Value>,
53    pub value_from_cycle_error:
54        fn(tcx: TyCtxt<'tcx>, cycle_error: &CycleError, guar: ErrorGuaranteed) -> C::Value,
55    pub format_value: fn(&C::Value) -> String,
56
57    /// Formats a human-readable description of this query and its key, as
58    /// specified by the `desc` query modifier.
59    ///
60    /// Used when reporting query cycle errors and similar problems.
61    pub description_fn: fn(TyCtxt<'tcx>, C::Key) -> String,
62}
63
64pub struct QuerySystemFns {
65    pub engine: QueryEngine,
66    pub local_providers: Providers,
67    pub extern_providers: ExternProviders,
68    pub encode_query_results: for<'tcx> fn(
69        tcx: TyCtxt<'tcx>,
70        encoder: &mut CacheEncoder<'_, 'tcx>,
71        query_result_index: &mut EncodedDepNodeIndex,
72    ),
73    pub try_mark_green: for<'tcx> fn(tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool,
74}
75
76pub struct QuerySystem<'tcx> {
77    pub states: QueryStates<'tcx>,
78    pub arenas: WorkerLocal<QueryArenas<'tcx>>,
79    pub caches: QueryCaches<'tcx>,
80    pub query_vtables: PerQueryVTables<'tcx>,
81
82    /// This provides access to the incremental compilation on-disk cache for query results.
83    /// Do not access this directly. It is only meant to be used by
84    /// `DepGraph::try_mark_green()` and the query infrastructure.
85    /// This is `None` if we are not incremental compilation mode
86    pub on_disk_cache: Option<OnDiskCache>,
87
88    pub fns: QuerySystemFns,
89
90    pub jobs: AtomicU64,
91}
92
93#[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)]
94pub struct TyCtxtAt<'tcx> {
95    pub tcx: TyCtxt<'tcx>,
96    pub span: Span,
97}
98
99impl<'tcx> Deref for TyCtxtAt<'tcx> {
100    type Target = TyCtxt<'tcx>;
101    #[inline(always)]
102    fn deref(&self) -> &Self::Target {
103        &self.tcx
104    }
105}
106
107#[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)]
108#[must_use]
109pub struct TyCtxtEnsureOk<'tcx> {
110    pub tcx: TyCtxt<'tcx>,
111}
112
113#[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)]
114#[must_use]
115pub struct TyCtxtEnsureDone<'tcx> {
116    pub tcx: TyCtxt<'tcx>,
117}
118
119impl<'tcx> TyCtxt<'tcx> {
120    /// Wrapper that calls queries in a special "ensure OK" mode, for callers
121    /// that don't need the return value and just want to invoke a query for
122    /// its potential side-effect of emitting fatal errors.
123    ///
124    /// This can be more efficient than a normal query call, because if the
125    /// query's inputs are all green, the call can return immediately without
126    /// needing to obtain a value (by decoding one from disk or by executing
127    /// the query).
128    ///
129    /// (As with all query calls, execution is also skipped if the query result
130    /// is already cached in memory.)
131    ///
132    /// ## WARNING
133    /// A subsequent normal call to the same query might still cause it to be
134    /// executed! This can occur when the inputs are all green, but the query's
135    /// result is not cached on disk, so the query must be executed to obtain a
136    /// return value.
137    ///
138    /// Therefore, this call mode is not appropriate for callers that want to
139    /// ensure that the query is _never_ executed in the future.
140    ///
141    /// ## `return_result_from_ensure_ok`
142    /// If a query has the `return_result_from_ensure_ok` modifier, calls via
143    /// `ensure_ok` will instead return `Result<(), ErrorGuaranteed>`. If the
144    /// query needs to be executed, and execution returns an error, that error
145    /// is returned to the caller.
146    #[inline(always)]
147    pub fn ensure_ok(self) -> TyCtxtEnsureOk<'tcx> {
148        TyCtxtEnsureOk { tcx: self }
149    }
150
151    /// Wrapper that calls queries in a special "ensure done" mode, for callers
152    /// that don't need the return value and just want to guarantee that the
153    /// query won't be executed in the future, by executing it now if necessary.
154    ///
155    /// This is useful for queries that read from a [`Steal`] value, to ensure
156    /// that they are executed before the query that will steal the value.
157    ///
158    /// Unlike [`Self::ensure_ok`], a query with all-green inputs will only be
159    /// skipped if its return value is stored in the disk-cache. This is still
160    /// more efficient than a regular query, because in that situation the
161    /// return value doesn't necessarily need to be decoded.
162    ///
163    /// (As with all query calls, execution is also skipped if the query result
164    /// is already cached in memory.)
165    ///
166    /// [`Steal`]: rustc_data_structures::steal::Steal
167    #[inline(always)]
168    pub fn ensure_done(self) -> TyCtxtEnsureDone<'tcx> {
169        TyCtxtEnsureDone { tcx: self }
170    }
171
172    /// Returns a transparent wrapper for `TyCtxt` which uses
173    /// `span` as the location of queries performed through it.
174    #[inline(always)]
175    pub fn at(self, span: Span) -> TyCtxtAt<'tcx> {
176        TyCtxtAt { tcx: self, span }
177    }
178
179    pub fn try_mark_green(self, dep_node: &dep_graph::DepNode) -> bool {
180        (self.query_system.fns.try_mark_green)(self, dep_node)
181    }
182}
183
184/// Calls either `query_ensure` or `query_ensure_error_guaranteed`, depending
185/// on whether the list of modifiers contains `return_result_from_ensure_ok`.
186macro_rules! query_ensure_select {
187    ([]$($args:tt)*) => {
188        crate::query::inner::query_ensure($($args)*)
189    };
190    ([(return_result_from_ensure_ok) $($rest:tt)*]$($args:tt)*) => {
191        crate::query::inner::query_ensure_error_guaranteed($($args)*)
192    };
193    ([$other:tt $($modifiers:tt)*]$($args:tt)*) => {
194        query_ensure_select!([$($modifiers)*]$($args)*)
195    };
196}
197
198macro_rules! query_helper_param_ty {
199    (DefId) => { impl $crate::query::IntoQueryParam<DefId> };
200    (LocalDefId) => { impl $crate::query::IntoQueryParam<LocalDefId> };
201    ($K:ty) => { $K };
202}
203
204macro_rules! query_if_arena {
205    ([] $arena:tt $no_arena:tt) => {
206        $no_arena
207    };
208    ([(arena_cache) $($rest:tt)*] $arena:tt $no_arena:tt) => {
209        $arena
210    };
211    ([$other:tt $($modifiers:tt)*]$($args:tt)*) => {
212        query_if_arena!([$($modifiers)*]$($args)*)
213    };
214}
215
216/// If `separate_provide_extern`, then the key can be projected to its
217/// local key via `<$K as AsLocalKey>::LocalKey`.
218macro_rules! local_key_if_separate_extern {
219    ([] $($K:tt)*) => {
220        $($K)*
221    };
222    ([(separate_provide_extern) $($rest:tt)*] $($K:tt)*) => {
223        <$($K)* as $crate::query::AsLocalKey>::LocalKey
224    };
225    ([$other:tt $($modifiers:tt)*] $($K:tt)*) => {
226        local_key_if_separate_extern!([$($modifiers)*] $($K)*)
227    };
228}
229
230macro_rules! separate_provide_extern_decl {
231    ([][$name:ident]) => {
232        ()
233    };
234    ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
235        for<'tcx> fn(
236            TyCtxt<'tcx>,
237            $name::Key<'tcx>,
238        ) -> $name::ProvidedValue<'tcx>
239    };
240    ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
241        separate_provide_extern_decl!([$($modifiers)*][$($args)*])
242    };
243}
244
245macro_rules! ensure_ok_result {
246    ( [] ) => {
247        ()
248    };
249    ( [(return_result_from_ensure_ok) $($rest:tt)*] ) => {
250        Result<(), ErrorGuaranteed>
251    };
252    ( [$other:tt $($modifiers:tt)*] ) => {
253        ensure_ok_result!( [$($modifiers)*] )
254    };
255}
256
257macro_rules! separate_provide_extern_default {
258    ([][$name:ident]) => {
259        ()
260    };
261    ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
262        |_, key| $crate::query::plumbing::default_extern_query(stringify!($name), &key)
263    };
264    ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
265        separate_provide_extern_default!([$($modifiers)*][$($args)*])
266    };
267}
268
269macro_rules! define_callbacks {
270    (
271        $(
272            $(#[$attr:meta])*
273            [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,
274        )*
275    ) => {
276        $(#[allow(unused_lifetimes)] pub mod $name {
277            use super::*;
278            use $crate::query::erase::{self, Erased};
279
280            pub type Key<'tcx> = $($K)*;
281            pub type Value<'tcx> = $V;
282
283            pub type LocalKey<'tcx> = local_key_if_separate_extern!([$($modifiers)*] $($K)*);
284
285            /// This type alias specifies the type returned from query providers and the type
286            /// used for decoding. For regular queries this is the declared returned type `V`,
287            /// but `arena_cache` will use `<V as ArenaCached>::Provided` instead.
288            pub type ProvidedValue<'tcx> = query_if_arena!(
289                [$($modifiers)*]
290                (<$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Provided)
291                ($V)
292            );
293
294            /// This function takes `ProvidedValue` and converts it to an erased `Value` by
295            /// allocating it on an arena if the query has the `arena_cache` modifier. The
296            /// value is then erased and returned. This will happen when computing the query
297            /// using a provider or decoding a stored result.
298            #[inline(always)]
299            pub fn provided_to_erased<'tcx>(
300                _tcx: TyCtxt<'tcx>,
301                provided_value: ProvidedValue<'tcx>,
302            ) -> Erased<Value<'tcx>> {
303                // Store the provided value in an arena and get a reference
304                // to it, for queries with `arena_cache`.
305                let value: Value<'tcx> = query_if_arena!([$($modifiers)*]
306                    {
307                        use $crate::query::arena_cached::ArenaCached;
308
309                        if mem::needs_drop::<<$V as ArenaCached<'tcx>>::Allocated>() {
310                            <$V as ArenaCached>::alloc_in_arena(
311                                |v| _tcx.query_system.arenas.$name.alloc(v),
312                                provided_value,
313                            )
314                        } else {
315                            <$V as ArenaCached>::alloc_in_arena(
316                                |v| _tcx.arena.dropless.alloc(v),
317                                provided_value,
318                            )
319                        }
320                    }
321                    // Otherwise, the provided value is the value.
322                    (provided_value)
323                );
324                erase::erase_val(value)
325            }
326
327            pub type Storage<'tcx> = <$($K)* as $crate::query::Key>::Cache<Erased<$V>>;
328
329            // Ensure that keys grow no larger than 88 bytes by accident.
330            // Increase this limit if necessary, but do try to keep the size low if possible
331            #[cfg(target_pointer_width = "64")]
332            const _: () = {
333                if size_of::<Key<'static>>() > 88 {
334                    panic!("{}", concat!(
335                        "the query `",
336                        stringify!($name),
337                        "` has a key type `",
338                        stringify!($($K)*),
339                        "` that is too large"
340                    ));
341                }
342            };
343
344            // Ensure that values grow no larger than 64 bytes by accident.
345            // Increase this limit if necessary, but do try to keep the size low if possible
346            #[cfg(target_pointer_width = "64")]
347            #[cfg(not(feature = "rustc_randomized_layouts"))]
348            const _: () = {
349                if size_of::<Value<'static>>() > 64 {
350                    panic!("{}", concat!(
351                        "the query `",
352                        stringify!($name),
353                        "` has a value type `",
354                        stringify!($V),
355                        "` that is too large"
356                    ));
357                }
358            };
359        })*
360
361        /// Holds per-query arenas for queries with the `arena_cache` modifier.
362        #[derive(Default)]
363        pub struct QueryArenas<'tcx> {
364            $(
365                $(#[$attr])*
366                pub $name: query_if_arena!([$($modifiers)*]
367                    // Use the `ArenaCached` helper trait to determine the arena's value type.
368                    (TypedArena<<$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Allocated>)
369                    // No arena for this query, so the field type is `()`.
370                    ()
371                ),
372            )*
373        }
374
375        #[derive(Default)]
376        pub struct QueryCaches<'tcx> {
377            $($(#[$attr])* pub $name: $name::Storage<'tcx>,)*
378        }
379
380        impl<'tcx> $crate::query::TyCtxtEnsureOk<'tcx> {
381            $($(#[$attr])*
382            #[inline(always)]
383            pub fn $name(
384                self,
385                key: query_helper_param_ty!($($K)*),
386            ) -> ensure_ok_result!([$($modifiers)*]) {
387                query_ensure_select!(
388                    [$($modifiers)*]
389                    self.tcx,
390                    self.tcx.query_system.fns.engine.$name,
391                    &self.tcx.query_system.caches.$name,
392                    $crate::query::IntoQueryParam::into_query_param(key),
393                    false,
394                )
395            })*
396        }
397
398        impl<'tcx> $crate::query::TyCtxtEnsureDone<'tcx> {
399            $($(#[$attr])*
400            #[inline(always)]
401            pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
402                crate::query::inner::query_ensure(
403                    self.tcx,
404                    self.tcx.query_system.fns.engine.$name,
405                    &self.tcx.query_system.caches.$name,
406                    $crate::query::IntoQueryParam::into_query_param(key),
407                    true,
408                );
409            })*
410        }
411
412        impl<'tcx> TyCtxt<'tcx> {
413            $($(#[$attr])*
414            #[inline(always)]
415            #[must_use]
416            pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V
417            {
418                self.at(DUMMY_SP).$name(key)
419            })*
420        }
421
422        impl<'tcx> $crate::query::TyCtxtAt<'tcx> {
423            $($(#[$attr])*
424            #[inline(always)]
425            pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V
426            {
427                use $crate::query::{erase, inner};
428
429                erase::restore_val::<$V>(inner::query_get_at(
430                    self.tcx,
431                    self.tcx.query_system.fns.engine.$name,
432                    &self.tcx.query_system.caches.$name,
433                    self.span,
434                    $crate::query::IntoQueryParam::into_query_param(key),
435                ))
436            })*
437        }
438
439        /// Holds a `QueryVTable` for each query.
440        ///
441        /// ("Per" just makes this pluralized name more visually distinct.)
442        pub struct PerQueryVTables<'tcx> {
443            $(
444                pub $name: ::rustc_middle::query::plumbing::QueryVTable<'tcx, $name::Storage<'tcx>>,
445            )*
446        }
447
448        #[derive(Default)]
449        pub struct QueryStates<'tcx> {
450            $(
451                pub $name: $crate::query::QueryState<'tcx, $($K)*>,
452            )*
453        }
454
455        pub struct Providers {
456            $(pub $name: for<'tcx> fn(
457                TyCtxt<'tcx>,
458                $name::LocalKey<'tcx>,
459            ) -> $name::ProvidedValue<'tcx>,)*
460        }
461
462        pub struct ExternProviders {
463            $(pub $name: separate_provide_extern_decl!([$($modifiers)*][$name]),)*
464        }
465
466        impl Default for Providers {
467            fn default() -> Self {
468                Providers {
469                    $($name: |_, key| $crate::query::plumbing::default_query(stringify!($name), &key)),*
470                }
471            }
472        }
473
474        impl Default for ExternProviders {
475            fn default() -> Self {
476                ExternProviders {
477                    $($name: separate_provide_extern_default!([$($modifiers)*][$name]),)*
478                }
479            }
480        }
481
482        impl Copy for Providers {}
483        impl Clone for Providers {
484            fn clone(&self) -> Self { *self }
485        }
486
487        impl Copy for ExternProviders {}
488        impl Clone for ExternProviders {
489            fn clone(&self) -> Self { *self }
490        }
491
492        pub struct QueryEngine {
493            $(pub $name: for<'tcx> fn(
494                TyCtxt<'tcx>,
495                Span,
496                $name::Key<'tcx>,
497                $crate::query::QueryMode,
498            ) -> Option<$crate::query::erase::Erased<$V>>,)*
499        }
500    };
501}
502
503macro_rules! define_feedable {
504    ($($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
505        $(impl<'tcx, K: $crate::query::IntoQueryParam<$($K)*> + Copy> TyCtxtFeed<'tcx, K> {
506            $(#[$attr])*
507            #[inline(always)]
508            pub fn $name(self, value: $name::ProvidedValue<'tcx>) {
509                let key = self.key().into_query_param();
510
511                let tcx = self.tcx;
512                let erased_value = $name::provided_to_erased(tcx, value);
513
514                let dep_kind: dep_graph::DepKind = dep_graph::dep_kinds::$name;
515
516                $crate::query::inner::query_feed(
517                    tcx,
518                    dep_kind,
519                    &tcx.query_system.query_vtables.$name,
520                    &tcx.query_system.caches.$name,
521                    key,
522                    erased_value,
523                );
524            }
525        })*
526    }
527}
528
529// Each of these queries corresponds to a function pointer field in the
530// `Providers` struct for requesting a value of that type, and a method
531// on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
532// which memoizes and does dep-graph tracking, wrapping around the actual
533// `Providers` that the driver creates (using several `rustc_*` crates).
534//
535// The result type of each query must implement `Clone`, and additionally
536// `ty::query::values::Value`, which produces an appropriate placeholder
537// (error) value if the query resulted in a query cycle.
538// Queries marked with `cycle_fatal` do not need the latter implementation,
539// as they will raise an fatal error on query cycles instead.
540
541mod sealed {
542    use rustc_hir::def_id::{LocalModDefId, ModDefId};
543
544    use super::{DefId, LocalDefId, OwnerId};
545
546    /// An analogue of the `Into` trait that's intended only for query parameters.
547    ///
548    /// This exists to allow queries to accept either `DefId` or `LocalDefId` while requiring that the
549    /// user call `to_def_id` to convert between them everywhere else.
550    pub trait IntoQueryParam<P> {
551        fn into_query_param(self) -> P;
552    }
553
554    impl<P> IntoQueryParam<P> for P {
555        #[inline(always)]
556        fn into_query_param(self) -> P {
557            self
558        }
559    }
560
561    impl<'a, P: Copy> IntoQueryParam<P> for &'a P {
562        #[inline(always)]
563        fn into_query_param(self) -> P {
564            *self
565        }
566    }
567
568    impl IntoQueryParam<LocalDefId> for OwnerId {
569        #[inline(always)]
570        fn into_query_param(self) -> LocalDefId {
571            self.def_id
572        }
573    }
574
575    impl IntoQueryParam<DefId> for LocalDefId {
576        #[inline(always)]
577        fn into_query_param(self) -> DefId {
578            self.to_def_id()
579        }
580    }
581
582    impl IntoQueryParam<DefId> for OwnerId {
583        #[inline(always)]
584        fn into_query_param(self) -> DefId {
585            self.to_def_id()
586        }
587    }
588
589    impl IntoQueryParam<DefId> for ModDefId {
590        #[inline(always)]
591        fn into_query_param(self) -> DefId {
592            self.to_def_id()
593        }
594    }
595
596    impl IntoQueryParam<DefId> for LocalModDefId {
597        #[inline(always)]
598        fn into_query_param(self) -> DefId {
599            self.to_def_id()
600        }
601    }
602
603    impl IntoQueryParam<LocalDefId> for LocalModDefId {
604        #[inline(always)]
605        fn into_query_param(self) -> LocalDefId {
606            self.into()
607        }
608    }
609}
610
611#[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_query_system::ich::StableHashingContext<'__ctx>>
            for CyclePlaceholder {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    CyclePlaceholder(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
612pub struct CyclePlaceholder(pub ErrorGuaranteed);
613
614#[cold]
615pub(crate) fn default_query(name: &str, key: &dyn std::fmt::Debug) -> ! {
616    crate::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!(
617        "`tcx.{name}({key:?})` is not supported for this key;\n\
618        hint: Queries can be either made to the local crate, or the external crate. \
619        This error means you tried to use it for one that's not supported.\n\
620        If that's not the case, {name} was likely never assigned to a provider function.\n",
621    )
622}
623
624#[cold]
625pub(crate) fn default_extern_query(name: &str, key: &dyn std::fmt::Debug) -> ! {
626    crate::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!(
627        "`tcx.{name}({key:?})` unsupported by its crate; \
628         perhaps the `{name}` query was never assigned a provider function",
629    )
630}