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