]> git.lizzy.rs Git - rust.git/blob - src/librustc/ty/query/config.rs
Rollup merge of #59432 - phansch:compiletest_docs, r=alexcrichton
[rust.git] / src / librustc / ty / query / config.rs
1 use crate::dep_graph::SerializedDepNodeIndex;
2 use crate::dep_graph::DepNode;
3 use crate::hir::def_id::{CrateNum, DefId, DefIndex};
4 use crate::mir::interpret::GlobalId;
5 use crate::traits;
6 use crate::traits::query::{
7     CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
8     CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal,
9     CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal,
10 };
11 use crate::ty::{self, ParamEnvAnd, Ty, TyCtxt};
12 use crate::ty::subst::SubstsRef;
13 use crate::ty::query::queries;
14 use crate::ty::query::Query;
15 use crate::ty::query::QueryCache;
16 use crate::ty::query::plumbing::CycleError;
17 use crate::util::profiling::ProfileCategory;
18
19 use std::borrow::Cow;
20 use std::hash::Hash;
21 use std::fmt::Debug;
22 use syntax_pos::symbol::InternedString;
23 use rustc_data_structures::sync::Lock;
24 use rustc_data_structures::fingerprint::Fingerprint;
25 use crate::ich::StableHashingContext;
26
27 // Query configuration and description traits.
28
29 pub trait QueryConfig<'tcx> {
30     const NAME: &'static str;
31     const CATEGORY: ProfileCategory;
32
33     type Key: Eq + Hash + Clone + Debug;
34     type Value: Clone;
35 }
36
37 pub(crate) trait QueryAccessors<'tcx>: QueryConfig<'tcx> {
38     fn query(key: Self::Key) -> Query<'tcx>;
39
40     // Don't use this method to access query results, instead use the methods on TyCtxt
41     fn query_cache<'a>(tcx: TyCtxt<'a, 'tcx, '_>) -> &'a Lock<QueryCache<'tcx, Self>>;
42
43     fn to_dep_node(tcx: TyCtxt<'_, 'tcx, '_>, key: &Self::Key) -> DepNode;
44
45     // Don't use this method to compute query results, instead use the methods on TyCtxt
46     fn compute(tcx: TyCtxt<'_, 'tcx, '_>, key: Self::Key) -> Self::Value;
47
48     fn hash_result(
49         hcx: &mut StableHashingContext<'_>,
50         result: &Self::Value
51     ) -> Option<Fingerprint>;
52
53     fn handle_cycle_error(tcx: TyCtxt<'_, 'tcx, '_>, error: CycleError<'tcx>) -> Self::Value;
54 }
55
56 pub(crate) trait QueryDescription<'tcx>: QueryAccessors<'tcx> {
57     fn describe(tcx: TyCtxt<'_, '_, '_>, key: Self::Key) -> Cow<'static, str>;
58
59     #[inline]
60     fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, _: Self::Key) -> bool {
61         false
62     }
63
64     fn try_load_from_disk(_: TyCtxt<'_, 'tcx, 'tcx>,
65                           _: SerializedDepNodeIndex)
66                           -> Option<Self::Value> {
67         bug!("QueryDescription::load_from_disk() called for an unsupported query.")
68     }
69 }
70
71 impl<'tcx, M: QueryAccessors<'tcx, Key=DefId>> QueryDescription<'tcx> for M {
72     default fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
73         if !tcx.sess.verbose() {
74             format!("processing `{}`", tcx.def_path_str(def_id)).into()
75         } else {
76             let name = unsafe { ::std::intrinsics::type_name::<M>() };
77             format!("processing {:?} with query `{}`", def_id, name).into()
78         }
79     }
80 }
81
82 impl<'tcx> QueryDescription<'tcx> for queries::check_mod_attrs<'tcx> {
83     fn describe(
84         tcx: TyCtxt<'_, '_, '_>,
85         key: DefId,
86     ) -> Cow<'static, str> {
87         format!("checking attributes in {}", key.describe_as_module(tcx)).into()
88     }
89 }
90
91 impl<'tcx> QueryDescription<'tcx> for queries::check_mod_unstable_api_usage<'tcx> {
92     fn describe(
93         tcx: TyCtxt<'_, '_, '_>,
94         key: DefId,
95     ) -> Cow<'static, str> {
96         format!("checking for unstable API usage in {}", key.describe_as_module(tcx)).into()
97     }
98 }
99
100 impl<'tcx> QueryDescription<'tcx> for queries::check_mod_loops<'tcx> {
101     fn describe(
102         tcx: TyCtxt<'_, '_, '_>,
103         key: DefId,
104     ) -> Cow<'static, str> {
105         format!("checking loops in {}", key.describe_as_module(tcx)).into()
106     }
107 }
108
109 impl<'tcx> QueryDescription<'tcx> for queries::check_mod_item_types<'tcx> {
110     fn describe(
111         tcx: TyCtxt<'_, '_, '_>,
112         key: DefId,
113     ) -> Cow<'static, str> {
114         format!("checking item types in {}", key.describe_as_module(tcx)).into()
115     }
116 }
117
118 impl<'tcx> QueryDescription<'tcx> for queries::check_mod_privacy<'tcx> {
119     fn describe(
120         tcx: TyCtxt<'_, '_, '_>,
121         key: DefId,
122     ) -> Cow<'static, str> {
123         format!("checking privacy in {}", key.describe_as_module(tcx)).into()
124     }
125 }
126
127 impl<'tcx> QueryDescription<'tcx> for queries::check_mod_intrinsics<'tcx> {
128     fn describe(
129         tcx: TyCtxt<'_, '_, '_>,
130         key: DefId,
131     ) -> Cow<'static, str> {
132         format!("checking intrinsics in {}", key.describe_as_module(tcx)).into()
133     }
134 }
135
136 impl<'tcx> QueryDescription<'tcx> for queries::check_mod_liveness<'tcx> {
137     fn describe(
138         tcx: TyCtxt<'_, '_, '_>,
139         key: DefId,
140     ) -> Cow<'static, str> {
141         format!("checking liveness of variables in {}", key.describe_as_module(tcx)).into()
142     }
143 }
144
145 impl<'tcx> QueryDescription<'tcx> for queries::check_mod_impl_wf<'tcx> {
146     fn describe(
147         tcx: TyCtxt<'_, '_, '_>,
148         key: DefId,
149     ) -> Cow<'static, str> {
150         format!("checking that impls are well-formed in {}", key.describe_as_module(tcx)).into()
151     }
152 }
153
154 impl<'tcx> QueryDescription<'tcx> for queries::collect_mod_item_types<'tcx> {
155     fn describe(
156         tcx: TyCtxt<'_, '_, '_>,
157         key: DefId,
158     ) -> Cow<'static, str> {
159         format!("collecting item types in {}", key.describe_as_module(tcx)).into()
160     }
161 }
162
163 impl<'tcx> QueryDescription<'tcx> for queries::normalize_projection_ty<'tcx> {
164     fn describe(
165         _tcx: TyCtxt<'_, '_, '_>,
166         goal: CanonicalProjectionGoal<'tcx>,
167     ) -> Cow<'static, str> {
168         format!("normalizing `{:?}`", goal).into()
169     }
170 }
171
172 impl<'tcx> QueryDescription<'tcx> for queries::implied_outlives_bounds<'tcx> {
173     fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTyGoal<'tcx>) -> Cow<'static, str> {
174         format!("computing implied outlives bounds for `{:?}`", goal).into()
175     }
176 }
177
178 impl<'tcx> QueryDescription<'tcx> for queries::dropck_outlives<'tcx> {
179     fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTyGoal<'tcx>) -> Cow<'static, str> {
180         format!("computing dropck types for `{:?}`", goal).into()
181     }
182 }
183
184 impl<'tcx> QueryDescription<'tcx> for queries::normalize_ty_after_erasing_regions<'tcx> {
185     fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: ParamEnvAnd<'tcx, Ty<'tcx>>) -> Cow<'static, str> {
186         format!("normalizing `{:?}`", goal).into()
187     }
188 }
189
190 impl<'tcx> QueryDescription<'tcx> for queries::evaluate_obligation<'tcx> {
191     fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalPredicateGoal<'tcx>) -> Cow<'static, str> {
192         format!("evaluating trait selection obligation `{}`", goal.value.value).into()
193     }
194 }
195
196 impl<'tcx> QueryDescription<'tcx> for queries::evaluate_goal<'tcx> {
197     fn describe(
198         _tcx: TyCtxt<'_, '_, '_>,
199         goal: traits::ChalkCanonicalGoal<'tcx>
200     ) -> Cow<'static, str> {
201         format!("evaluating trait selection obligation `{}`", goal.value.goal).into()
202     }
203 }
204
205 impl<'tcx> QueryDescription<'tcx> for queries::type_op_ascribe_user_type<'tcx> {
206     fn describe(
207         _tcx: TyCtxt<'_, '_, '_>,
208         goal: CanonicalTypeOpAscribeUserTypeGoal<'tcx>,
209     ) -> Cow<'static, str> {
210         format!("evaluating `type_op_ascribe_user_type` `{:?}`", goal).into()
211     }
212 }
213
214 impl<'tcx> QueryDescription<'tcx> for queries::type_op_eq<'tcx> {
215     fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTypeOpEqGoal<'tcx>) -> Cow<'static, str> {
216         format!("evaluating `type_op_eq` `{:?}`", goal).into()
217     }
218 }
219
220 impl<'tcx> QueryDescription<'tcx> for queries::type_op_subtype<'tcx> {
221     fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTypeOpSubtypeGoal<'tcx>)
222                 -> Cow<'static, str> {
223         format!("evaluating `type_op_subtype` `{:?}`", goal).into()
224     }
225 }
226
227 impl<'tcx> QueryDescription<'tcx> for queries::type_op_prove_predicate<'tcx> {
228     fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTypeOpProvePredicateGoal<'tcx>)
229                 -> Cow<'static, str> {
230         format!("evaluating `type_op_prove_predicate` `{:?}`", goal).into()
231     }
232 }
233
234 impl<'tcx> QueryDescription<'tcx> for queries::type_op_normalize_ty<'tcx> {
235     fn describe(_tcx: TyCtxt<'_, '_, '_>,
236                 goal: CanonicalTypeOpNormalizeGoal<'tcx, Ty<'tcx>>) -> Cow<'static, str> {
237         format!("normalizing `{:?}`", goal).into()
238     }
239 }
240
241 impl<'tcx> QueryDescription<'tcx> for queries::type_op_normalize_predicate<'tcx> {
242     fn describe(
243         _tcx: TyCtxt<'_, '_, '_>,
244         goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::Predicate<'tcx>>,
245     ) -> Cow<'static, str> {
246         format!("normalizing `{:?}`", goal).into()
247     }
248 }
249
250 impl<'tcx> QueryDescription<'tcx> for queries::type_op_normalize_poly_fn_sig<'tcx> {
251     fn describe(
252         _tcx: TyCtxt<'_, '_, '_>,
253         goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::PolyFnSig<'tcx>>,
254     ) -> Cow<'static, str> {
255         format!("normalizing `{:?}`", goal).into()
256     }
257 }
258
259 impl<'tcx> QueryDescription<'tcx> for queries::type_op_normalize_fn_sig<'tcx> {
260     fn describe(_tcx: TyCtxt<'_, '_, '_>,
261                 goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::FnSig<'tcx>>) -> Cow<'static, str> {
262         format!("normalizing `{:?}`", goal).into()
263     }
264 }
265
266 impl<'tcx> QueryDescription<'tcx> for queries::is_copy_raw<'tcx> {
267     fn describe(_tcx: TyCtxt<'_, '_, '_>, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
268                 -> Cow<'static, str> {
269         format!("computing whether `{}` is `Copy`", env.value).into()
270     }
271 }
272
273 impl<'tcx> QueryDescription<'tcx> for queries::is_sized_raw<'tcx> {
274     fn describe(_tcx: TyCtxt<'_, '_, '_>, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
275                 -> Cow<'static, str> {
276         format!("computing whether `{}` is `Sized`", env.value).into()
277     }
278 }
279
280 impl<'tcx> QueryDescription<'tcx> for queries::is_freeze_raw<'tcx> {
281     fn describe(_tcx: TyCtxt<'_, '_, '_>, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
282                 -> Cow<'static, str> {
283         format!("computing whether `{}` is freeze", env.value).into()
284     }
285 }
286
287 impl<'tcx> QueryDescription<'tcx> for queries::needs_drop_raw<'tcx> {
288     fn describe(_tcx: TyCtxt<'_, '_, '_>, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
289                 -> Cow<'static, str> {
290         format!("computing whether `{}` needs drop", env.value).into()
291     }
292 }
293
294 impl<'tcx> QueryDescription<'tcx> for queries::layout_raw<'tcx> {
295     fn describe(_tcx: TyCtxt<'_, '_, '_>, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
296                 -> Cow<'static, str> {
297         format!("computing layout of `{}`", env.value).into()
298     }
299 }
300
301 impl<'tcx> QueryDescription<'tcx> for queries::super_predicates_of<'tcx> {
302     fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
303         format!("computing the supertraits of `{}`",
304                 tcx.def_path_str(def_id)).into()
305     }
306 }
307
308 impl<'tcx> QueryDescription<'tcx> for queries::type_param_predicates<'tcx> {
309     fn describe(tcx: TyCtxt<'_, '_, '_>, (_, def_id): (DefId, DefId)) -> Cow<'static, str> {
310         let id = tcx.hir().as_local_hir_id(def_id).unwrap();
311         format!("computing the bounds for type parameter `{}`",
312                 tcx.hir().ty_param_name(id)).into()
313     }
314 }
315
316 impl<'tcx> QueryDescription<'tcx> for queries::coherent_trait<'tcx> {
317     fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
318         format!("coherence checking all impls of trait `{}`",
319                 tcx.def_path_str(def_id)).into()
320     }
321 }
322
323 impl<'tcx> QueryDescription<'tcx> for queries::upstream_monomorphizations<'tcx> {
324     fn describe(_: TyCtxt<'_, '_, '_>, k: CrateNum) -> Cow<'static, str> {
325         format!("collecting available upstream monomorphizations `{:?}`", k).into()
326     }
327 }
328
329 impl<'tcx> QueryDescription<'tcx> for queries::crate_inherent_impls<'tcx> {
330     fn describe(_: TyCtxt<'_, '_, '_>, k: CrateNum) -> Cow<'static, str> {
331         format!("all inherent impls defined in crate `{:?}`", k).into()
332     }
333 }
334
335 impl<'tcx> QueryDescription<'tcx> for queries::crate_inherent_impls_overlap_check<'tcx> {
336     fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
337         "check for overlap between inherent impls defined in this crate".into()
338     }
339 }
340
341 impl<'tcx> QueryDescription<'tcx> for queries::crate_variances<'tcx> {
342     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
343         "computing the variances for items in this crate".into()
344     }
345 }
346
347 impl<'tcx> QueryDescription<'tcx> for queries::inferred_outlives_crate<'tcx> {
348     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
349         "computing the inferred outlives predicates for items in this crate".into()
350     }
351 }
352
353 impl<'tcx> QueryDescription<'tcx> for queries::mir_shims<'tcx> {
354     fn describe(tcx: TyCtxt<'_, '_, '_>, def: ty::InstanceDef<'tcx>) -> Cow<'static, str> {
355         format!("generating MIR shim for `{}`",
356                 tcx.def_path_str(def.def_id())).into()
357     }
358 }
359
360 impl<'tcx> QueryDescription<'tcx> for queries::privacy_access_levels<'tcx> {
361     fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
362         "privacy access levels".into()
363     }
364 }
365
366 impl<'tcx> QueryDescription<'tcx> for queries::check_private_in_public<'tcx> {
367     fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
368         "checking for private elements in public interfaces".into()
369     }
370 }
371
372 impl<'tcx> QueryDescription<'tcx> for queries::typeck_item_bodies<'tcx> {
373     fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
374         "type-checking all item bodies".into()
375     }
376 }
377
378 impl<'tcx> QueryDescription<'tcx> for queries::reachable_set<'tcx> {
379     fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
380         "reachability".into()
381     }
382 }
383
384 impl<'tcx> QueryDescription<'tcx> for queries::const_eval<'tcx> {
385     fn describe(
386         tcx: TyCtxt<'_, '_, '_>,
387         key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
388     ) -> Cow<'static, str> {
389         format!(
390             "const-evaluating + checking `{}`",
391             tcx.def_path_str(key.value.instance.def.def_id()),
392         ).into()
393     }
394
395     #[inline]
396     fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, _key: Self::Key) -> bool {
397         true
398     }
399
400     #[inline]
401     fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
402                               id: SerializedDepNodeIndex)
403                               -> Option<Self::Value> {
404         tcx.queries.on_disk_cache.try_load_query_result(tcx, id).map(Ok)
405     }
406 }
407
408 impl<'tcx> QueryDescription<'tcx> for queries::const_eval_raw<'tcx> {
409     fn describe(tcx: TyCtxt<'_, '_, '_>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
410         -> Cow<'static, str>
411     {
412         format!("const-evaluating `{}`", tcx.def_path_str(key.value.instance.def.def_id())).into()
413     }
414
415     #[inline]
416     fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, _key: Self::Key) -> bool {
417         true
418     }
419
420     #[inline]
421     fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
422                               id: SerializedDepNodeIndex)
423                               -> Option<Self::Value> {
424         tcx.queries.on_disk_cache.try_load_query_result(tcx, id).map(Ok)
425     }
426 }
427
428 impl<'tcx> QueryDescription<'tcx> for queries::symbol_name<'tcx> {
429     fn describe(_tcx: TyCtxt<'_, '_, '_>, instance: ty::Instance<'tcx>) -> Cow<'static, str> {
430         format!("computing the symbol for `{}`", instance).into()
431     }
432
433     #[inline]
434     fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, _: Self::Key) -> bool {
435         true
436     }
437
438     #[inline]
439     fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
440                               id: SerializedDepNodeIndex)
441                               -> Option<Self::Value> {
442         tcx.queries.on_disk_cache.try_load_query_result(tcx, id)
443     }
444 }
445
446 impl<'tcx> QueryDescription<'tcx> for queries::describe_def<'tcx> {
447     fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> {
448         bug!("describe_def")
449     }
450 }
451
452 impl<'tcx> QueryDescription<'tcx> for queries::def_span<'tcx> {
453     fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> {
454         bug!("def_span")
455     }
456 }
457
458
459 impl<'tcx> QueryDescription<'tcx> for queries::lookup_stability<'tcx> {
460     fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> {
461         bug!("stability")
462     }
463 }
464
465 impl<'tcx> QueryDescription<'tcx> for queries::lookup_deprecation_entry<'tcx> {
466     fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> {
467         bug!("deprecation")
468     }
469 }
470
471 impl<'tcx> QueryDescription<'tcx> for queries::item_attrs<'tcx> {
472     fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> {
473         bug!("item_attrs")
474     }
475 }
476
477 impl<'tcx> QueryDescription<'tcx> for queries::is_reachable_non_generic<'tcx> {
478     fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> {
479         bug!("is_reachable_non_generic")
480     }
481 }
482
483 impl<'tcx> QueryDescription<'tcx> for queries::fn_arg_names<'tcx> {
484     fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> {
485         bug!("fn_arg_names")
486     }
487 }
488
489 impl<'tcx> QueryDescription<'tcx> for queries::impl_parent<'tcx> {
490     fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> {
491         bug!("impl_parent")
492     }
493 }
494
495 impl<'tcx> QueryDescription<'tcx> for queries::trait_of_item<'tcx> {
496     fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> {
497         bug!("trait_of_item")
498     }
499 }
500
501 impl<'tcx> QueryDescription<'tcx> for queries::const_is_rvalue_promotable_to_static<'tcx> {
502     fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
503         format!("const checking if rvalue is promotable to static `{}`",
504             tcx.def_path_str(def_id)).into()
505     }
506
507     #[inline]
508     fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, _: Self::Key) -> bool {
509         true
510     }
511
512     #[inline]
513     fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
514                               id: SerializedDepNodeIndex)
515                               -> Option<Self::Value> {
516         tcx.queries.on_disk_cache.try_load_query_result(tcx, id)
517     }
518 }
519
520 impl<'tcx> QueryDescription<'tcx> for queries::rvalue_promotable_map<'tcx> {
521     fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
522         format!("checking which parts of `{}` are promotable to static",
523                 tcx.def_path_str(def_id)).into()
524     }
525 }
526
527 impl<'tcx> QueryDescription<'tcx> for queries::is_mir_available<'tcx> {
528     fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
529         format!("checking if item is mir available: `{}`",
530                 tcx.def_path_str(def_id)).into()
531     }
532 }
533
534 impl<'tcx> QueryDescription<'tcx> for queries::codegen_fulfill_obligation<'tcx> {
535     fn describe(tcx: TyCtxt<'_, '_, '_>,
536                 key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)) -> Cow<'static, str> {
537         format!("checking if `{}` fulfills its obligations", tcx.def_path_str(key.1.def_id()))
538             .into()
539     }
540
541     #[inline]
542     fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, _: Self::Key) -> bool {
543         true
544     }
545
546     #[inline]
547     fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
548                               id: SerializedDepNodeIndex)
549                               -> Option<Self::Value> {
550         tcx.queries.on_disk_cache.try_load_query_result(tcx, id)
551     }
552 }
553
554 impl<'tcx> QueryDescription<'tcx> for queries::trait_impls_of<'tcx> {
555     fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
556         format!("trait impls of `{}`", tcx.def_path_str(def_id)).into()
557     }
558 }
559
560 impl<'tcx> QueryDescription<'tcx> for queries::is_object_safe<'tcx> {
561     fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
562         format!("determine object safety of trait `{}`", tcx.def_path_str(def_id)).into()
563     }
564 }
565
566 impl<'tcx> QueryDescription<'tcx> for queries::is_const_fn_raw<'tcx> {
567     fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
568         format!("checking if item is const fn: `{}`", tcx.def_path_str(def_id)).into()
569     }
570 }
571
572 impl<'tcx> QueryDescription<'tcx> for queries::dylib_dependency_formats<'tcx> {
573     fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
574         "dylib dependency formats of crate".into()
575     }
576 }
577
578 impl<'tcx> QueryDescription<'tcx> for queries::is_compiler_builtins<'tcx> {
579     fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
580         "checking if the crate is_compiler_builtins".into()
581     }
582 }
583
584 impl<'tcx> QueryDescription<'tcx> for queries::has_global_allocator<'tcx> {
585     fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
586         "checking if the crate has_global_allocator".into()
587     }
588 }
589
590 impl<'tcx> QueryDescription<'tcx> for queries::has_panic_handler<'tcx> {
591     fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
592         "checking if the crate has_panic_handler".into()
593     }
594 }
595
596 impl<'tcx> QueryDescription<'tcx> for queries::extern_crate<'tcx> {
597     fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> {
598         "getting crate's ExternCrateData".into()
599     }
600 }
601
602 impl<'tcx> QueryDescription<'tcx> for queries::analysis<'tcx> {
603     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
604         "running analysis passes on this crate".into()
605     }
606 }
607
608 impl<'tcx> QueryDescription<'tcx> for queries::specializes<'tcx> {
609     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: (DefId, DefId)) -> Cow<'static, str> {
610         "computing whether impls specialize one another".into()
611     }
612 }
613
614 impl<'tcx> QueryDescription<'tcx> for queries::in_scope_traits_map<'tcx> {
615     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefIndex) -> Cow<'static, str> {
616         "traits in scope at a block".into()
617     }
618 }
619
620 impl<'tcx> QueryDescription<'tcx> for queries::is_no_builtins<'tcx> {
621     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
622         "test whether a crate has #![no_builtins]".into()
623     }
624 }
625
626 impl<'tcx> QueryDescription<'tcx> for queries::panic_strategy<'tcx> {
627     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
628         "query a crate's configured panic strategy".into()
629     }
630 }
631
632 impl<'tcx> QueryDescription<'tcx> for queries::is_profiler_runtime<'tcx> {
633     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
634         "query a crate is #![profiler_runtime]".into()
635     }
636 }
637
638 impl<'tcx> QueryDescription<'tcx> for queries::is_sanitizer_runtime<'tcx> {
639     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
640         "query a crate is #![sanitizer_runtime]".into()
641     }
642 }
643
644 impl<'tcx> QueryDescription<'tcx> for queries::reachable_non_generics<'tcx> {
645     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
646         "looking up the exported symbols of a crate".into()
647     }
648 }
649
650 impl<'tcx> QueryDescription<'tcx> for queries::foreign_modules<'tcx> {
651     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
652         "looking up the foreign modules of a linked crate".into()
653     }
654 }
655
656 impl<'tcx> QueryDescription<'tcx> for queries::entry_fn<'tcx> {
657     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
658         "looking up the entry function of a crate".into()
659     }
660 }
661
662 impl<'tcx> QueryDescription<'tcx> for queries::plugin_registrar_fn<'tcx> {
663     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
664         "looking up the plugin registrar for a crate".into()
665     }
666 }
667
668 impl<'tcx> QueryDescription<'tcx> for queries::proc_macro_decls_static<'tcx> {
669     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
670         "looking up the derive registrar for a crate".into()
671     }
672 }
673
674 impl<'tcx> QueryDescription<'tcx> for queries::crate_disambiguator<'tcx> {
675     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
676         "looking up the disambiguator a crate".into()
677     }
678 }
679
680 impl<'tcx> QueryDescription<'tcx> for queries::crate_hash<'tcx> {
681     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
682         "looking up the hash a crate".into()
683     }
684 }
685
686 impl<'tcx> QueryDescription<'tcx> for queries::original_crate_name<'tcx> {
687     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
688         "looking up the original name a crate".into()
689     }
690 }
691
692 impl<'tcx> QueryDescription<'tcx> for queries::extra_filename<'tcx> {
693     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
694         "looking up the extra filename for a crate".into()
695     }
696 }
697
698 impl<'tcx> QueryDescription<'tcx> for queries::implementations_of_trait<'tcx> {
699     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: (CrateNum, DefId)) -> Cow<'static, str> {
700         "looking up implementations of a trait in a crate".into()
701     }
702 }
703
704 impl<'tcx> QueryDescription<'tcx> for queries::all_trait_implementations<'tcx> {
705     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
706         "looking up all (?) trait implementations".into()
707     }
708 }
709
710 impl<'tcx> QueryDescription<'tcx> for queries::link_args<'tcx> {
711     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
712         "looking up link arguments for a crate".into()
713     }
714 }
715
716 impl<'tcx> QueryDescription<'tcx> for queries::resolve_lifetimes<'tcx> {
717     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
718         "resolving lifetimes".into()
719     }
720 }
721
722 impl<'tcx> QueryDescription<'tcx> for queries::named_region_map<'tcx> {
723     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefIndex) -> Cow<'static, str> {
724         "looking up a named region".into()
725     }
726 }
727
728 impl<'tcx> QueryDescription<'tcx> for queries::is_late_bound_map<'tcx> {
729     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefIndex) -> Cow<'static, str> {
730         "testing if a region is late bound".into()
731     }
732 }
733
734 impl<'tcx> QueryDescription<'tcx> for queries::object_lifetime_defaults_map<'tcx> {
735     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefIndex) -> Cow<'static, str> {
736         "looking up lifetime defaults for a region".into()
737     }
738 }
739
740 impl<'tcx> QueryDescription<'tcx> for queries::dep_kind<'tcx> {
741     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
742         "fetching what a dependency looks like".into()
743     }
744 }
745
746 impl<'tcx> QueryDescription<'tcx> for queries::crate_name<'tcx> {
747     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
748         "fetching what a crate is named".into()
749     }
750 }
751
752 impl<'tcx> QueryDescription<'tcx> for queries::get_lib_features<'tcx> {
753     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
754         "calculating the lib features map".into()
755     }
756 }
757
758 impl<'tcx> QueryDescription<'tcx> for queries::defined_lib_features<'tcx> {
759     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
760         "calculating the lib features defined in a crate".into()
761     }
762 }
763
764 impl<'tcx> QueryDescription<'tcx> for queries::get_lang_items<'tcx> {
765     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
766         "calculating the lang items map".into()
767     }
768 }
769
770 impl<'tcx> QueryDescription<'tcx> for queries::defined_lang_items<'tcx> {
771     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
772         "calculating the lang items defined in a crate".into()
773     }
774 }
775
776 impl<'tcx> QueryDescription<'tcx> for queries::missing_lang_items<'tcx> {
777     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
778         "calculating the missing lang items in a crate".into()
779     }
780 }
781
782 impl<'tcx> QueryDescription<'tcx> for queries::visible_parent_map<'tcx> {
783     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
784         "calculating the visible parent map".into()
785     }
786 }
787
788 impl<'tcx> QueryDescription<'tcx> for queries::missing_extern_crate_item<'tcx> {
789     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
790         "seeing if we're missing an `extern crate` item for this crate".into()
791     }
792 }
793
794 impl<'tcx> QueryDescription<'tcx> for queries::used_crate_source<'tcx> {
795     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
796         "looking at the source for a crate".into()
797     }
798 }
799
800 impl<'tcx> QueryDescription<'tcx> for queries::postorder_cnums<'tcx> {
801     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
802         "generating a postorder list of CrateNums".into()
803     }
804 }
805
806 impl<'tcx> QueryDescription<'tcx> for queries::maybe_unused_extern_crates<'tcx> {
807     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
808         "looking up all possibly unused extern crates".into()
809     }
810 }
811
812 impl<'tcx> QueryDescription<'tcx> for queries::stability_index<'tcx> {
813     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
814         "calculating the stability index for the local crate".into()
815     }
816 }
817
818 impl<'tcx> QueryDescription<'tcx> for queries::all_traits<'tcx> {
819     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
820         "fetching all foreign and local traits".into()
821     }
822 }
823
824 impl<'tcx> QueryDescription<'tcx> for queries::all_crate_nums<'tcx> {
825     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
826         "fetching all foreign CrateNum instances".into()
827     }
828 }
829
830 impl<'tcx> QueryDescription<'tcx> for queries::exported_symbols<'tcx> {
831     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
832         "exported_symbols".into()
833     }
834 }
835
836 impl<'tcx> QueryDescription<'tcx> for queries::collect_and_partition_mono_items<'tcx> {
837     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
838         "collect_and_partition_mono_items".into()
839     }
840 }
841
842 impl<'tcx> QueryDescription<'tcx> for queries::codegen_unit<'tcx> {
843     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: InternedString) -> Cow<'static, str> {
844         "codegen_unit".into()
845     }
846 }
847
848 impl<'tcx> QueryDescription<'tcx> for queries::output_filenames<'tcx> {
849     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
850         "output_filenames".into()
851     }
852 }
853
854 impl<'tcx> QueryDescription<'tcx> for queries::vtable_methods<'tcx> {
855     fn describe(tcx: TyCtxt<'_, '_, '_>, key: ty::PolyTraitRef<'tcx> ) -> Cow<'static, str> {
856         format!("finding all methods for trait {}", tcx.def_path_str(key.def_id())).into()
857     }
858 }
859
860 impl<'tcx> QueryDescription<'tcx> for queries::features_query<'tcx> {
861     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
862         "looking up enabled feature gates".into()
863     }
864 }
865
866 impl<'tcx> QueryDescription<'tcx> for queries::typeck_tables_of<'tcx> {
867     #[inline]
868     fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, def_id: Self::Key) -> bool {
869         def_id.is_local()
870     }
871
872     fn try_load_from_disk(tcx: TyCtxt<'_, 'tcx, 'tcx>,
873                           id: SerializedDepNodeIndex)
874                           -> Option<Self::Value> {
875         let typeck_tables: Option<ty::TypeckTables<'tcx>> = tcx
876             .queries.on_disk_cache
877             .try_load_query_result(tcx, id);
878
879         typeck_tables.map(|tables| tcx.alloc_tables(tables))
880     }
881 }
882
883 impl<'tcx> QueryDescription<'tcx> for queries::substitute_normalize_and_test_predicates<'tcx> {
884     fn describe(tcx: TyCtxt<'_, '_, '_>, key: (DefId, SubstsRef<'tcx>)) -> Cow<'static, str> {
885         format!("testing substituted normalized predicates:`{}`", tcx.def_path_str(key.0)).into()
886     }
887 }
888
889 impl<'tcx> QueryDescription<'tcx> for queries::method_autoderef_steps<'tcx> {
890     fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTyGoal<'tcx>) -> Cow<'static, str> {
891         format!("computing autoderef types for `{:?}`", goal).into()
892     }
893 }
894
895 impl<'tcx> QueryDescription<'tcx> for queries::target_features_whitelist<'tcx> {
896     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
897         "looking up the whitelist of target features".into()
898     }
899 }
900
901 impl<'tcx> QueryDescription<'tcx> for queries::instance_def_size_estimate<'tcx> {
902     fn describe(tcx: TyCtxt<'_, '_, '_>, def: ty::InstanceDef<'tcx>) -> Cow<'static, str> {
903         format!("estimating size for `{}`", tcx.def_path_str(def.def_id())).into()
904     }
905 }
906
907 impl<'tcx> QueryDescription<'tcx> for queries::dllimport_foreign_items<'tcx> {
908     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
909         "dllimport_foreign_items".into()
910     }
911 }
912
913 impl<'tcx> QueryDescription<'tcx> for queries::backend_optimization_level<'tcx> {
914     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
915         "optimization level used by backend".into()
916     }
917 }
918
919 macro_rules! impl_disk_cacheable_query(
920     ($query_name:ident, |$tcx:tt, $key:tt| $cond:expr) => {
921         impl<'tcx> QueryDescription<'tcx> for queries::$query_name<'tcx> {
922             #[inline]
923             fn cache_on_disk($tcx: TyCtxt<'_, 'tcx, 'tcx>, $key: Self::Key) -> bool {
924                 $cond
925             }
926
927             #[inline]
928             fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
929                                       id: SerializedDepNodeIndex)
930                                       -> Option<Self::Value> {
931                 tcx.queries.on_disk_cache.try_load_query_result(tcx, id)
932             }
933         }
934     }
935 );
936
937 impl_disk_cacheable_query!(mir_borrowck, |tcx, def_id| {
938     def_id.is_local() && tcx.is_closure(def_id)
939 });
940
941 impl_disk_cacheable_query!(unsafety_check_result, |_, def_id| def_id.is_local());
942 impl_disk_cacheable_query!(borrowck, |_, def_id| def_id.is_local());
943 impl_disk_cacheable_query!(check_match, |_, def_id| def_id.is_local());
944 impl_disk_cacheable_query!(def_symbol_name, |_, _| true);
945 impl_disk_cacheable_query!(predicates_of, |_, def_id| def_id.is_local());
946 impl_disk_cacheable_query!(used_trait_imports, |_, def_id| def_id.is_local());
947 impl_disk_cacheable_query!(codegen_fn_attrs, |_, _| true);
948 impl_disk_cacheable_query!(specialization_graph_of, |_, _| true);