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