1use std::ops::Deref;
23use 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::HandleCycleError;
8use rustc_query_system::dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
9pub(crate) use rustc_query_system::query::QueryJobId;
10use rustc_query_system::query::*;
11use rustc_span::{ErrorGuaranteed, Span};
12pub use sealed::IntoQueryParam;
1314use crate::dep_graph;
15use crate::dep_graph::DepKind;
16use crate::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex, OnDiskCache};
17use crate::query::{
18DynamicQueries, ExternProviders, Providers, QueryArenas, QueryCaches, QueryEngine, QueryStates,
19};
20use crate::ty::TyCtxt;
2122pub struct DynamicQuery<'tcx, C: QueryCache> {
23pub name: &'static str,
24pub eval_always: bool,
25pub dep_kind: DepKind,
26pub handle_cycle_error: HandleCycleError,
27// Offset of this query's state field in the QueryStates struct
28pub query_state: usize,
29// Offset of this query's cache field in the QueryCaches struct
30pub query_cache: usize,
31pub cache_on_disk: fn(tcx: TyCtxt<'tcx>, key: &C::Key) -> bool,
32pub execute_query: fn(tcx: TyCtxt<'tcx>, k: C::Key) -> C::Value,
33pub compute: fn(tcx: TyCtxt<'tcx>, key: C::Key) -> C::Value,
34pub can_load_from_disk: bool,
35pub try_load_from_disk: fn(
36 tcx: TyCtxt<'tcx>,
37 key: &C::Key,
38 prev_index: SerializedDepNodeIndex,
39 index: DepNodeIndex,
40 ) -> Option<C::Value>,
41pub loadable_from_disk:
42fn(tcx: TyCtxt<'tcx>, key: &C::Key, index: SerializedDepNodeIndex) -> bool,
43pub hash_result: HashResult<C::Value>,
44pub value_from_cycle_error:
45fn(tcx: TyCtxt<'tcx>, cycle_error: &CycleError, guar: ErrorGuaranteed) -> C::Value,
46pub format_value: fn(&C::Value) -> String,
47}
4849pub struct QuerySystemFns {
50pub engine: QueryEngine,
51pub local_providers: Providers,
52pub extern_providers: ExternProviders,
53pub encode_query_results: for<'tcx> fn(
54 tcx: TyCtxt<'tcx>,
55 encoder: &mut CacheEncoder<'_, 'tcx>,
56 query_result_index: &mut EncodedDepNodeIndex,
57 ),
58pub try_mark_green: for<'tcx> fn(tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool,
59}
6061pub struct QuerySystem<'tcx> {
62pub states: QueryStates<'tcx>,
63pub arenas: WorkerLocal<QueryArenas<'tcx>>,
64pub caches: QueryCaches<'tcx>,
65pub dynamic_queries: DynamicQueries<'tcx>,
6667/// This provides access to the incremental compilation on-disk cache for query results.
68 /// Do not access this directly. It is only meant to be used by
69 /// `DepGraph::try_mark_green()` and the query infrastructure.
70 /// This is `None` if we are not incremental compilation mode
71pub on_disk_cache: Option<OnDiskCache>,
7273pub fns: QuerySystemFns,
7475pub jobs: AtomicU64,
76}
7778#[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)]
79pub struct TyCtxtAt<'tcx> {
80pub tcx: TyCtxt<'tcx>,
81pub span: Span,
82}
8384impl<'tcx> Dereffor TyCtxtAt<'tcx> {
85type Target = TyCtxt<'tcx>;
86#[inline(always)]
87fn deref(&self) -> &Self::Target {
88&self.tcx
89 }
90}
9192#[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)]
93#[must_use]
94pub struct TyCtxtEnsureOk<'tcx> {
95pub tcx: TyCtxt<'tcx>,
96}
9798#[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)]
99#[must_use]
100pub struct TyCtxtEnsureDone<'tcx> {
101pub tcx: TyCtxt<'tcx>,
102}
103104impl<'tcx> TyCtxt<'tcx> {
105/// Wrapper that calls queries in a special "ensure OK" mode, for callers
106 /// that don't need the return value and just want to invoke a query for
107 /// its potential side-effect of emitting fatal errors.
108 ///
109 /// This can be more efficient than a normal query call, because if the
110 /// query's inputs are all green, the call can return immediately without
111 /// needing to obtain a value (by decoding one from disk or by executing
112 /// the query).
113 ///
114 /// (As with all query calls, execution is also skipped if the query result
115 /// is already cached in memory.)
116 ///
117 /// ## WARNING
118 /// A subsequent normal call to the same query might still cause it to be
119 /// executed! This can occur when the inputs are all green, but the query's
120 /// result is not cached on disk, so the query must be executed to obtain a
121 /// return value.
122 ///
123 /// Therefore, this call mode is not appropriate for callers that want to
124 /// ensure that the query is _never_ executed in the future.
125 ///
126 /// ## `return_result_from_ensure_ok`
127 /// If a query has the `return_result_from_ensure_ok` modifier, calls via
128 /// `ensure_ok` will instead return `Result<(), ErrorGuaranteed>`. If the
129 /// query needs to be executed, and execution returns an error, that error
130 /// is returned to the caller.
131#[inline(always)]
132pub fn ensure_ok(self) -> TyCtxtEnsureOk<'tcx> {
133TyCtxtEnsureOk { tcx: self }
134 }
135136/// Wrapper that calls queries in a special "ensure done" mode, for callers
137 /// that don't need the return value and just want to guarantee that the
138 /// query won't be executed in the future, by executing it now if necessary.
139 ///
140 /// This is useful for queries that read from a [`Steal`] value, to ensure
141 /// that they are executed before the query that will steal the value.
142 ///
143 /// Unlike [`Self::ensure_ok`], a query with all-green inputs will only be
144 /// skipped if its return value is stored in the disk-cache. This is still
145 /// more efficient than a regular query, because in that situation the
146 /// return value doesn't necessarily need to be decoded.
147 ///
148 /// (As with all query calls, execution is also skipped if the query result
149 /// is already cached in memory.)
150 ///
151 /// [`Steal`]: rustc_data_structures::steal::Steal
152#[inline(always)]
153pub fn ensure_done(self) -> TyCtxtEnsureDone<'tcx> {
154TyCtxtEnsureDone { tcx: self }
155 }
156157/// Returns a transparent wrapper for `TyCtxt` which uses
158 /// `span` as the location of queries performed through it.
159#[inline(always)]
160pub fn at(self, span: Span) -> TyCtxtAt<'tcx> {
161TyCtxtAt { tcx: self, span }
162 }
163164pub fn try_mark_green(self, dep_node: &dep_graph::DepNode) -> bool {
165 (self.query_system.fns.try_mark_green)(self, dep_node)
166 }
167}
168169/// Calls either `query_ensure` or `query_ensure_error_guaranteed`, depending
170/// on whether the list of modifiers contains `return_result_from_ensure_ok`.
171macro_rules!query_ensure_select {
172 ([]$($args:tt)*) => {
173crate::query::inner::query_ensure($($args)*)
174 };
175 ([(return_result_from_ensure_ok) $($rest:tt)*]$($args:tt)*) => {
176crate::query::inner::query_ensure_error_guaranteed($($args)*)
177 };
178 ([$other:tt $($modifiers:tt)*]$($args:tt)*) => {
179query_ensure_select!([$($modifiers)*]$($args)*)
180 };
181}
182183macro_rules!query_helper_param_ty {
184 (DefId) => { impl IntoQueryParam<DefId> };
185 (LocalDefId) => { impl IntoQueryParam<LocalDefId> };
186 ($K:ty) => { $K };
187}
188189macro_rules!query_if_arena {
190 ([] $arena:tt $no_arena:tt) => {
191$no_arena
192};
193 ([(arena_cache) $($rest:tt)*] $arena:tt $no_arena:tt) => {
194$arena
195};
196 ([$other:tt $($modifiers:tt)*]$($args:tt)*) => {
197query_if_arena!([$($modifiers)*]$($args)*)
198 };
199}
200201/// If `separate_provide_extern`, then the key can be projected to its
202/// local key via `<$K as AsLocalKey>::LocalKey`.
203macro_rules!local_key_if_separate_extern {
204 ([] $($K:tt)*) => {
205 $($K)*
206 };
207 ([(separate_provide_extern) $($rest:tt)*] $($K:tt)*) => {
208 <$($K)* as AsLocalKey>::LocalKey209 };
210 ([$other:tt $($modifiers:tt)*] $($K:tt)*) => {
211local_key_if_separate_extern!([$($modifiers)*] $($K)*)
212 };
213}
214215macro_rules!separate_provide_extern_decl {
216 ([][$name:ident]) => {
217 ()
218 };
219 ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
220for<'tcx> fn(
221TyCtxt<'tcx>,
222 queries::$name::Key<'tcx>,
223 ) -> queries::$name::ProvidedValue<'tcx>
224 };
225 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
226separate_provide_extern_decl!([$($modifiers)*][$($args)*])
227 };
228}
229230macro_rules!ensure_ok_result {
231 ( [] ) => {
232 ()
233 };
234 ( [(return_result_from_ensure_ok) $($rest:tt)*] ) => {
235Result<(), ErrorGuaranteed>
236 };
237 ( [$other:tt $($modifiers:tt)*] ) => {
238ensure_ok_result!( [$($modifiers)*] )
239 };
240}
241242macro_rules!separate_provide_extern_default {
243 ([][$name:ident]) => {
244 ()
245 };
246 ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
247 |_, key| $crate::query::plumbing::default_extern_query(stringify!($name), &key)
248 };
249 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
250separate_provide_extern_default!([$($modifiers)*][$($args)*])
251 };
252}
253254macro_rules!define_callbacks {
255 (
256 $(
257 $(#[$attr:meta])*
258 [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,
259 )*
260 ) => {
261262#[allow(unused_lifetimes)]
263pub mod queries {
264 $(pub mod $name {
265use super::super::*;
266267pub type Key<'tcx> = $($K)*;
268pub type Value<'tcx> = $V;
269270pub type LocalKey<'tcx> = local_key_if_separate_extern!([$($modifiers)*] $($K)*);
271272/// This type alias specifies the type returned from query providers and the type
273 /// used for decoding. For regular queries this is the declared returned type `V`,
274 /// but `arena_cache` will use `<V as ArenaCached>::Provided` instead.
275pub type ProvidedValue<'tcx> = query_if_arena!(
276 [$($modifiers)*]
277 (<$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Provided)
278 ($V)
279 );
280281/// This function takes `ProvidedValue` and converts it to an erased `Value` by
282 /// allocating it on an arena if the query has the `arena_cache` modifier. The
283 /// value is then erased and returned. This will happen when computing the query
284 /// using a provider or decoding a stored result.
285#[inline(always)]
286pub fn provided_to_erased<'tcx>(
287 _tcx: TyCtxt<'tcx>,
288 value: ProvidedValue<'tcx>,
289 ) -> Erase<Value<'tcx>> {
290 erase(query_if_arena!([$($modifiers)*]
291 {
292use $crate::query::arena_cached::ArenaCached;
293294if mem::needs_drop::<<$V as ArenaCached<'tcx>>::Allocated>() {
295 <$V as ArenaCached>::alloc_in_arena(
296 |v| _tcx.query_system.arenas.$name.alloc(v),
297 value,
298 )
299 } else {
300 <$V as ArenaCached>::alloc_in_arena(
301 |v| _tcx.arena.dropless.alloc(v),
302 value,
303 )
304 }
305 }
306 (value)
307 ))
308 }
309310pub type Storage<'tcx> = <$($K)* as keys::Key>::Cache<Erase<$V>>;
311312// Ensure that keys grow no larger than 88 bytes by accident.
313 // Increase this limit if necessary, but do try to keep the size low if possible
314#[cfg(target_pointer_width = "64")]
315const _: () = {
316if size_of::<Key<'static>>() > 88 {
317panic!("{}", concat!(
318"the query `",
319stringify!($name),
320"` has a key type `",
321stringify!($($K)*),
322"` that is too large"
323));
324 }
325 };
326327// Ensure that values grow no larger than 64 bytes by accident.
328 // Increase this limit if necessary, but do try to keep the size low if possible
329#[cfg(target_pointer_width = "64")]
330 #[cfg(not(feature = "rustc_randomized_layouts"))]
331const _: () = {
332if size_of::<Value<'static>>() > 64 {
333panic!("{}", concat!(
334"the query `",
335stringify!($name),
336"` has a value type `",
337stringify!($V),
338"` that is too large"
339));
340 }
341 };
342 })*
343 }
344345pub struct QueryArenas<'tcx> {
346 $($(#[$attr])* pub $name: query_if_arena!([$($modifiers)*]
347 (TypedArena<<$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Allocated>)
348 ()
349 ),)*
350 }
351352impl Default for QueryArenas<'_> {
353fn default() -> Self {
354Self {
355 $($name: query_if_arena!([$($modifiers)*]
356 (Default::default())
357 ()
358 ),)*
359 }
360 }
361 }
362363#[derive(Default)]
364pub struct QueryCaches<'tcx> {
365 $($(#[$attr])* pub $name: queries::$name::Storage<'tcx>,)*
366 }
367368impl<'tcx> TyCtxtEnsureOk<'tcx> {
369 $($(#[$attr])*
370#[inline(always)]
371pub fn $name(
372self,
373 key: query_helper_param_ty!($($K)*),
374 ) -> ensure_ok_result!([$($modifiers)*]) {
375query_ensure_select!(
376 [$($modifiers)*]
377self.tcx,
378self.tcx.query_system.fns.engine.$name,
379&self.tcx.query_system.caches.$name,
380 key.into_query_param(),
381false,
382 )
383 })*
384 }
385386impl<'tcx> TyCtxtEnsureDone<'tcx> {
387 $($(#[$attr])*
388#[inline(always)]
389pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
390crate::query::inner::query_ensure(
391self.tcx,
392self.tcx.query_system.fns.engine.$name,
393&self.tcx.query_system.caches.$name,
394 key.into_query_param(),
395true,
396 );
397 })*
398 }
399400impl<'tcx> TyCtxt<'tcx> {
401 $($(#[$attr])*
402#[inline(always)]
403 #[must_use]
404pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V
405{
406self.at(DUMMY_SP).$name(key)
407 })*
408 }
409410impl<'tcx> TyCtxtAt<'tcx> {
411 $($(#[$attr])*
412#[inline(always)]
413pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V
414{
415 restore::<$V>(crate::query::inner::query_get_at(
416self.tcx,
417self.tcx.query_system.fns.engine.$name,
418&self.tcx.query_system.caches.$name,
419self.span,
420 key.into_query_param(),
421 ))
422 })*
423 }
424425pub struct DynamicQueries<'tcx> {
426 $(
427pub $name: DynamicQuery<'tcx, queries::$name::Storage<'tcx>>,
428 )*
429 }
430431#[derive(Default)]
432pub struct QueryStates<'tcx> {
433 $(
434pub $name: QueryState<$($K)*>,
435 )*
436 }
437438pub struct Providers {
439 $(pub $name: for<'tcx> fn(
440TyCtxt<'tcx>,
441 queries::$name::LocalKey<'tcx>,
442 ) -> queries::$name::ProvidedValue<'tcx>,)*
443 }
444445pub struct ExternProviders {
446 $(pub $name: separate_provide_extern_decl!([$($modifiers)*][$name]),)*
447 }
448449impl Default for Providers {
450fn default() -> Self {
451 Providers {
452 $($name: |_, key| $crate::query::plumbing::default_query(stringify!($name), &key)),*
453 }
454 }
455 }
456457impl Default for ExternProviders {
458fn default() -> Self {
459 ExternProviders {
460 $($name: separate_provide_extern_default!([$($modifiers)*][$name]),)*
461 }
462 }
463 }
464465impl Copy for Providers {}
466impl Clone for Providers {
467fn clone(&self) -> Self { *self }
468 }
469470impl Copy for ExternProviders {}
471impl Clone for ExternProviders {
472fn clone(&self) -> Self { *self }
473 }
474475pub struct QueryEngine {
476 $(pub $name: for<'tcx> fn(
477TyCtxt<'tcx>,
478Span,
479 queries::$name::Key<'tcx>,
480QueryMode,
481 ) -> Option<Erase<$V>>,)*
482 }
483 };
484}
485486macro_rules!hash_result {
487 ([]) => {{
488Some(dep_graph::hash_result)
489 }};
490 ([(no_hash) $($rest:tt)*]) => {{
491None
492}};
493 ([$other:tt $($modifiers:tt)*]) => {
494hash_result!([$($modifiers)*])
495 };
496}
497498macro_rules!define_feedable {
499 ($($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
500 $(impl<'tcx, K: IntoQueryParam<$($K)*> + Copy> TyCtxtFeed<'tcx, K> {
501 $(#[$attr])*
502#[inline(always)]
503pub fn $name(self, value: queries::$name::ProvidedValue<'tcx>) {
504let key = self.key().into_query_param();
505506let tcx = self.tcx;
507let erased = queries::$name::provided_to_erased(tcx, value);
508let cache = &tcx.query_system.caches.$name;
509510let dep_kind: dep_graph::DepKind = dep_graph::dep_kinds::$name;
511let hasher: Option<fn(&mut StableHashingContext<'_>, &_) -> _> = hash_result!([$($modifiers)*]);
512513$crate::query::inner::query_feed(
514 tcx,
515 dep_kind,
516 hasher,
517 cache,
518 key,
519 erased,
520 );
521 }
522 })*
523 }
524}
525526// Each of these queries corresponds to a function pointer field in the
527// `Providers` struct for requesting a value of that type, and a method
528// on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
529// which memoizes and does dep-graph tracking, wrapping around the actual
530// `Providers` that the driver creates (using several `rustc_*` crates).
531//
532// The result type of each query must implement `Clone`, and additionally
533// `ty::query::values::Value`, which produces an appropriate placeholder
534// (error) value if the query resulted in a query cycle.
535// Queries marked with `cycle_fatal` do not need the latter implementation,
536// as they will raise an fatal error on query cycles instead.
537538mod sealed {
539use rustc_hir::def_id::{LocalModDefId, ModDefId};
540541use super::{DefId, LocalDefId, OwnerId};
542543/// An analogue of the `Into` trait that's intended only for query parameters.
544 ///
545 /// This exists to allow queries to accept either `DefId` or `LocalDefId` while requiring that the
546 /// user call `to_def_id` to convert between them everywhere else.
547pub trait IntoQueryParam<P> {
548fn into_query_param(self) -> P;
549 }
550551impl<P> IntoQueryParam<P> for P {
552#[inline(always)]
553fn into_query_param(self) -> P {
554self555 }
556 }
557558impl<'a, P: Copy> IntoQueryParam<P> for &'a P {
559#[inline(always)]
560fn into_query_param(self) -> P {
561*self562 }
563 }
564565impl IntoQueryParam<LocalDefId> for OwnerId {
566#[inline(always)]
567fn into_query_param(self) -> LocalDefId {
568self.def_id
569 }
570 }
571572impl IntoQueryParam<DefId> for LocalDefId {
573#[inline(always)]
574fn into_query_param(self) -> DefId {
575self.to_def_id()
576 }
577 }
578579impl IntoQueryParam<DefId> for OwnerId {
580#[inline(always)]
581fn into_query_param(self) -> DefId {
582self.to_def_id()
583 }
584 }
585586impl IntoQueryParam<DefId> for ModDefId {
587#[inline(always)]
588fn into_query_param(self) -> DefId {
589self.to_def_id()
590 }
591 }
592593impl IntoQueryParam<DefId> for LocalModDefId {
594#[inline(always)]
595fn into_query_param(self) -> DefId {
596self.to_def_id()
597 }
598 }
599600impl IntoQueryParam<LocalDefId> for LocalModDefId {
601#[inline(always)]
602fn into_query_param(self) -> LocalDefId {
603self.into()
604 }
605 }
606}
607608#[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)]
609pub struct CyclePlaceholder(pub ErrorGuaranteed);
610611#[cold]
612pub(crate) fn default_query(name: &str, key: &dyn std::fmt::Debug) -> ! {
613crate::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!(
614"`tcx.{name}({key:?})` is not supported for this key;\n\
615 hint: Queries can be either made to the local crate, or the external crate. \
616 This error means you tried to use it for one that's not supported.\n\
617 If that's not the case, {name} was likely never assigned to a provider function.\n",
618 )619}
620621#[cold]
622pub(crate) fn default_extern_query(name: &str, key: &dyn std::fmt::Debug) -> ! {
623crate::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!(
624"`tcx.{name}({key:?})` unsupported by its crate; \
625 perhaps the `{name}` query was never assigned a provider function",
626 )627}