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