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