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.
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.
11 use dep_graph::SerializedDepNodeIndex;
12 use hir::def_id::{CrateNum, DefId, DefIndex};
13 use ty::{self, Ty, TyCtxt};
14 use ty::maps::queries;
15 use ty::subst::Substs;
18 use syntax_pos::symbol::InternedString;
20 /// Query configuration and description traits.
22 pub trait QueryConfig {
23 type Key: Eq + Hash + Clone;
27 pub(super) trait QueryDescription<'tcx>: QueryConfig {
28 fn describe(tcx: TyCtxt, key: Self::Key) -> String;
31 fn cache_on_disk(_: Self::Key) -> bool {
35 fn try_load_from_disk(_: TyCtxt<'_, 'tcx, 'tcx>,
36 _: SerializedDepNodeIndex)
37 -> Option<Self::Value> {
38 bug!("QueryDescription::load_from_disk() called for an unsupported query.")
42 impl<'tcx, M: QueryConfig<Key=DefId>> QueryDescription<'tcx> for M {
43 default fn describe(tcx: TyCtxt, def_id: DefId) -> String {
44 if !tcx.sess.verbose() {
45 format!("processing `{}`", tcx.item_path_str(def_id))
47 let name = unsafe { ::std::intrinsics::type_name::<M>() };
48 format!("processing `{}` applied to `{:?}`", name, def_id)
53 impl<'tcx> QueryDescription<'tcx> for queries::is_copy_raw<'tcx> {
54 fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
55 format!("computing whether `{}` is `Copy`", env.value)
59 impl<'tcx> QueryDescription<'tcx> for queries::is_sized_raw<'tcx> {
60 fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
61 format!("computing whether `{}` is `Sized`", env.value)
65 impl<'tcx> QueryDescription<'tcx> for queries::is_freeze_raw<'tcx> {
66 fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
67 format!("computing whether `{}` is freeze", env.value)
71 impl<'tcx> QueryDescription<'tcx> for queries::needs_drop_raw<'tcx> {
72 fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
73 format!("computing whether `{}` needs drop", env.value)
77 impl<'tcx> QueryDescription<'tcx> for queries::layout_raw<'tcx> {
78 fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
79 format!("computing layout of `{}`", env.value)
83 impl<'tcx> QueryDescription<'tcx> for queries::super_predicates_of<'tcx> {
84 fn describe(tcx: TyCtxt, def_id: DefId) -> String {
85 format!("computing the supertraits of `{}`",
86 tcx.item_path_str(def_id))
90 impl<'tcx> QueryDescription<'tcx> for queries::erase_regions_ty<'tcx> {
91 fn describe(_tcx: TyCtxt, ty: Ty<'tcx>) -> String {
92 format!("erasing regions from `{:?}`", ty)
96 impl<'tcx> QueryDescription<'tcx> for queries::type_param_predicates<'tcx> {
97 fn describe(tcx: TyCtxt, (_, def_id): (DefId, DefId)) -> String {
98 let id = tcx.hir.as_local_node_id(def_id).unwrap();
99 format!("computing the bounds for type parameter `{}`",
100 tcx.hir.ty_param_name(id))
104 impl<'tcx> QueryDescription<'tcx> for queries::coherent_trait<'tcx> {
105 fn describe(tcx: TyCtxt, def_id: DefId) -> String {
106 format!("coherence checking all impls of trait `{}`",
107 tcx.item_path_str(def_id))
111 impl<'tcx> QueryDescription<'tcx> for queries::crate_inherent_impls<'tcx> {
112 fn describe(_: TyCtxt, k: CrateNum) -> String {
113 format!("all inherent impls defined in crate `{:?}`", k)
117 impl<'tcx> QueryDescription<'tcx> for queries::crate_inherent_impls_overlap_check<'tcx> {
118 fn describe(_: TyCtxt, _: CrateNum) -> String {
119 format!("check for overlap between inherent impls defined in this crate")
123 impl<'tcx> QueryDescription<'tcx> for queries::crate_variances<'tcx> {
124 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
125 format!("computing the variances for items in this crate")
129 impl<'tcx> QueryDescription<'tcx> for queries::mir_shims<'tcx> {
130 fn describe(tcx: TyCtxt, def: ty::InstanceDef<'tcx>) -> String {
131 format!("generating MIR shim for `{}`",
132 tcx.item_path_str(def.def_id()))
136 impl<'tcx> QueryDescription<'tcx> for queries::privacy_access_levels<'tcx> {
137 fn describe(_: TyCtxt, _: CrateNum) -> String {
138 format!("privacy access levels")
142 impl<'tcx> QueryDescription<'tcx> for queries::typeck_item_bodies<'tcx> {
143 fn describe(_: TyCtxt, _: CrateNum) -> String {
144 format!("type-checking all item bodies")
148 impl<'tcx> QueryDescription<'tcx> for queries::reachable_set<'tcx> {
149 fn describe(_: TyCtxt, _: CrateNum) -> String {
150 format!("reachability")
154 impl<'tcx> QueryDescription<'tcx> for queries::const_eval<'tcx> {
155 fn describe(tcx: TyCtxt, key: ty::ParamEnvAnd<'tcx, (DefId, &'tcx Substs<'tcx>)>) -> String {
156 format!("const-evaluating `{}`", tcx.item_path_str(key.value.0))
160 impl<'tcx> QueryDescription<'tcx> for queries::mir_keys<'tcx> {
161 fn describe(_: TyCtxt, _: CrateNum) -> String {
162 format!("getting a list of all mir_keys")
166 impl<'tcx> QueryDescription<'tcx> for queries::symbol_name<'tcx> {
167 fn describe(_tcx: TyCtxt, instance: ty::Instance<'tcx>) -> String {
168 format!("computing the symbol for `{}`", instance)
172 fn cache_on_disk(_: Self::Key) -> bool {
177 fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
178 id: SerializedDepNodeIndex)
179 -> Option<Self::Value> {
180 tcx.on_disk_query_result_cache.try_load_query_result(tcx, id)
184 impl<'tcx> QueryDescription<'tcx> for queries::describe_def<'tcx> {
185 fn describe(_: TyCtxt, _: DefId) -> String {
190 impl<'tcx> QueryDescription<'tcx> for queries::def_span<'tcx> {
191 fn describe(_: TyCtxt, _: DefId) -> String {
197 impl<'tcx> QueryDescription<'tcx> for queries::lookup_stability<'tcx> {
198 fn describe(_: TyCtxt, _: DefId) -> String {
203 impl<'tcx> QueryDescription<'tcx> for queries::lookup_deprecation_entry<'tcx> {
204 fn describe(_: TyCtxt, _: DefId) -> String {
209 impl<'tcx> QueryDescription<'tcx> for queries::item_attrs<'tcx> {
210 fn describe(_: TyCtxt, _: DefId) -> String {
215 impl<'tcx> QueryDescription<'tcx> for queries::is_exported_symbol<'tcx> {
216 fn describe(_: TyCtxt, _: DefId) -> String {
217 bug!("is_exported_symbol")
221 impl<'tcx> QueryDescription<'tcx> for queries::fn_arg_names<'tcx> {
222 fn describe(_: TyCtxt, _: DefId) -> String {
227 impl<'tcx> QueryDescription<'tcx> for queries::impl_parent<'tcx> {
228 fn describe(_: TyCtxt, _: DefId) -> String {
233 impl<'tcx> QueryDescription<'tcx> for queries::trait_of_item<'tcx> {
234 fn describe(_: TyCtxt, _: DefId) -> String {
235 bug!("trait_of_item")
239 impl<'tcx> QueryDescription<'tcx> for queries::item_body_nested_bodies<'tcx> {
240 fn describe(tcx: TyCtxt, def_id: DefId) -> String {
241 format!("nested item bodies of `{}`", tcx.item_path_str(def_id))
245 impl<'tcx> QueryDescription<'tcx> for queries::const_is_rvalue_promotable_to_static<'tcx> {
246 fn describe(tcx: TyCtxt, def_id: DefId) -> String {
247 format!("const checking if rvalue is promotable to static `{}`",
248 tcx.item_path_str(def_id))
252 fn cache_on_disk(_: Self::Key) -> bool {
257 fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
258 id: SerializedDepNodeIndex)
259 -> Option<Self::Value> {
260 tcx.on_disk_query_result_cache.try_load_query_result(tcx, id)
264 impl<'tcx> QueryDescription<'tcx> for queries::rvalue_promotable_map<'tcx> {
265 fn describe(tcx: TyCtxt, def_id: DefId) -> String {
266 format!("checking which parts of `{}` are promotable to static",
267 tcx.item_path_str(def_id))
271 impl<'tcx> QueryDescription<'tcx> for queries::is_mir_available<'tcx> {
272 fn describe(tcx: TyCtxt, def_id: DefId) -> String {
273 format!("checking if item is mir available: `{}`",
274 tcx.item_path_str(def_id))
278 impl<'tcx> QueryDescription<'tcx> for queries::trans_fulfill_obligation<'tcx> {
279 fn describe(tcx: TyCtxt, key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)) -> String {
280 format!("checking if `{}` fulfills its obligations", tcx.item_path_str(key.1.def_id()))
284 fn cache_on_disk(_: Self::Key) -> bool {
289 fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
290 id: SerializedDepNodeIndex)
291 -> Option<Self::Value> {
292 tcx.on_disk_query_result_cache.try_load_query_result(tcx, id)
296 impl<'tcx> QueryDescription<'tcx> for queries::trait_impls_of<'tcx> {
297 fn describe(tcx: TyCtxt, def_id: DefId) -> String {
298 format!("trait impls of `{}`", tcx.item_path_str(def_id))
302 impl<'tcx> QueryDescription<'tcx> for queries::is_object_safe<'tcx> {
303 fn describe(tcx: TyCtxt, def_id: DefId) -> String {
304 format!("determine object safety of trait `{}`", tcx.item_path_str(def_id))
308 impl<'tcx> QueryDescription<'tcx> for queries::is_const_fn<'tcx> {
309 fn describe(tcx: TyCtxt, def_id: DefId) -> String {
310 format!("checking if item is const fn: `{}`", tcx.item_path_str(def_id))
314 impl<'tcx> QueryDescription<'tcx> for queries::dylib_dependency_formats<'tcx> {
315 fn describe(_: TyCtxt, _: CrateNum) -> String {
316 "dylib dependency formats of crate".to_string()
320 impl<'tcx> QueryDescription<'tcx> for queries::is_panic_runtime<'tcx> {
321 fn describe(_: TyCtxt, _: CrateNum) -> String {
322 "checking if the crate is_panic_runtime".to_string()
326 impl<'tcx> QueryDescription<'tcx> for queries::is_compiler_builtins<'tcx> {
327 fn describe(_: TyCtxt, _: CrateNum) -> String {
328 "checking if the crate is_compiler_builtins".to_string()
332 impl<'tcx> QueryDescription<'tcx> for queries::has_global_allocator<'tcx> {
333 fn describe(_: TyCtxt, _: CrateNum) -> String {
334 "checking if the crate has_global_allocator".to_string()
338 impl<'tcx> QueryDescription<'tcx> for queries::extern_crate<'tcx> {
339 fn describe(_: TyCtxt, _: DefId) -> String {
340 "getting crate's ExternCrateData".to_string()
344 impl<'tcx> QueryDescription<'tcx> for queries::lint_levels<'tcx> {
345 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
346 format!("computing the lint levels for items in this crate")
350 impl<'tcx> QueryDescription<'tcx> for queries::specializes<'tcx> {
351 fn describe(_tcx: TyCtxt, _: (DefId, DefId)) -> String {
352 format!("computing whether impls specialize one another")
356 impl<'tcx> QueryDescription<'tcx> for queries::in_scope_traits_map<'tcx> {
357 fn describe(_tcx: TyCtxt, _: DefIndex) -> String {
358 format!("traits in scope at a block")
362 impl<'tcx> QueryDescription<'tcx> for queries::is_no_builtins<'tcx> {
363 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
364 format!("test whether a crate has #![no_builtins]")
368 impl<'tcx> QueryDescription<'tcx> for queries::panic_strategy<'tcx> {
369 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
370 format!("query a crate's configured panic strategy")
374 impl<'tcx> QueryDescription<'tcx> for queries::is_profiler_runtime<'tcx> {
375 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
376 format!("query a crate is #![profiler_runtime]")
380 impl<'tcx> QueryDescription<'tcx> for queries::is_sanitizer_runtime<'tcx> {
381 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
382 format!("query a crate is #![sanitizer_runtime]")
386 impl<'tcx> QueryDescription<'tcx> for queries::exported_symbol_ids<'tcx> {
387 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
388 format!("looking up the exported symbols of a crate")
392 impl<'tcx> QueryDescription<'tcx> for queries::native_libraries<'tcx> {
393 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
394 format!("looking up the native libraries of a linked crate")
398 impl<'tcx> QueryDescription<'tcx> for queries::plugin_registrar_fn<'tcx> {
399 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
400 format!("looking up the plugin registrar for a crate")
404 impl<'tcx> QueryDescription<'tcx> for queries::derive_registrar_fn<'tcx> {
405 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
406 format!("looking up the derive registrar for a crate")
410 impl<'tcx> QueryDescription<'tcx> for queries::crate_disambiguator<'tcx> {
411 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
412 format!("looking up the disambiguator a crate")
416 impl<'tcx> QueryDescription<'tcx> for queries::crate_hash<'tcx> {
417 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
418 format!("looking up the hash a crate")
422 impl<'tcx> QueryDescription<'tcx> for queries::original_crate_name<'tcx> {
423 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
424 format!("looking up the original name a crate")
428 impl<'tcx> QueryDescription<'tcx> for queries::implementations_of_trait<'tcx> {
429 fn describe(_tcx: TyCtxt, _: (CrateNum, DefId)) -> String {
430 format!("looking up implementations of a trait in a crate")
434 impl<'tcx> QueryDescription<'tcx> for queries::all_trait_implementations<'tcx> {
435 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
436 format!("looking up all (?) trait implementations")
440 impl<'tcx> QueryDescription<'tcx> for queries::link_args<'tcx> {
441 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
442 format!("looking up link arguments for a crate")
446 impl<'tcx> QueryDescription<'tcx> for queries::resolve_lifetimes<'tcx> {
447 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
448 format!("resolving lifetimes")
452 impl<'tcx> QueryDescription<'tcx> for queries::named_region_map<'tcx> {
453 fn describe(_tcx: TyCtxt, _: DefIndex) -> String {
454 format!("looking up a named region")
458 impl<'tcx> QueryDescription<'tcx> for queries::is_late_bound_map<'tcx> {
459 fn describe(_tcx: TyCtxt, _: DefIndex) -> String {
460 format!("testing if a region is late boudn")
464 impl<'tcx> QueryDescription<'tcx> for queries::object_lifetime_defaults_map<'tcx> {
465 fn describe(_tcx: TyCtxt, _: DefIndex) -> String {
466 format!("looking up lifetime defaults for a region")
470 impl<'tcx> QueryDescription<'tcx> for queries::dep_kind<'tcx> {
471 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
472 format!("fetching what a dependency looks like")
476 impl<'tcx> QueryDescription<'tcx> for queries::crate_name<'tcx> {
477 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
478 format!("fetching what a crate is named")
482 impl<'tcx> QueryDescription<'tcx> for queries::get_lang_items<'tcx> {
483 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
484 format!("calculating the lang items map")
488 impl<'tcx> QueryDescription<'tcx> for queries::defined_lang_items<'tcx> {
489 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
490 format!("calculating the lang items defined in a crate")
494 impl<'tcx> QueryDescription<'tcx> for queries::missing_lang_items<'tcx> {
495 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
496 format!("calculating the missing lang items in a crate")
500 impl<'tcx> QueryDescription<'tcx> for queries::visible_parent_map<'tcx> {
501 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
502 format!("calculating the visible parent map")
506 impl<'tcx> QueryDescription<'tcx> for queries::missing_extern_crate_item<'tcx> {
507 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
508 format!("seeing if we're missing an `extern crate` item for this crate")
512 impl<'tcx> QueryDescription<'tcx> for queries::used_crate_source<'tcx> {
513 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
514 format!("looking at the source for a crate")
518 impl<'tcx> QueryDescription<'tcx> for queries::postorder_cnums<'tcx> {
519 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
520 format!("generating a postorder list of CrateNums")
524 impl<'tcx> QueryDescription<'tcx> for queries::maybe_unused_extern_crates<'tcx> {
525 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
526 format!("looking up all possibly unused extern crates")
530 impl<'tcx> QueryDescription<'tcx> for queries::stability_index<'tcx> {
531 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
532 format!("calculating the stability index for the local crate")
536 impl<'tcx> QueryDescription<'tcx> for queries::all_crate_nums<'tcx> {
537 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
538 format!("fetching all foreign CrateNum instances")
542 impl<'tcx> QueryDescription<'tcx> for queries::exported_symbols<'tcx> {
543 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
544 format!("exported_symbols")
548 impl<'tcx> QueryDescription<'tcx> for queries::collect_and_partition_translation_items<'tcx> {
549 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
550 format!("collect_and_partition_translation_items")
554 impl<'tcx> QueryDescription<'tcx> for queries::codegen_unit<'tcx> {
555 fn describe(_tcx: TyCtxt, _: InternedString) -> String {
556 format!("codegen_unit")
560 impl<'tcx> QueryDescription<'tcx> for queries::compile_codegen_unit<'tcx> {
561 fn describe(_tcx: TyCtxt, _: InternedString) -> String {
562 format!("compile_codegen_unit")
566 impl<'tcx> QueryDescription<'tcx> for queries::output_filenames<'tcx> {
567 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
568 format!("output_filenames")
572 impl<'tcx> QueryDescription<'tcx> for queries::has_clone_closures<'tcx> {
573 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
574 format!("seeing if the crate has enabled `Clone` closures")
578 impl<'tcx> QueryDescription<'tcx> for queries::vtable_methods<'tcx> {
579 fn describe(tcx: TyCtxt, key: ty::PolyTraitRef<'tcx> ) -> String {
580 format!("finding all methods for trait {}", tcx.item_path_str(key.def_id()))
584 impl<'tcx> QueryDescription<'tcx> for queries::has_copy_closures<'tcx> {
585 fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
586 format!("seeing if the crate has enabled `Copy` closures")
590 impl<'tcx> QueryDescription<'tcx> for queries::fully_normalize_monormophic_ty<'tcx> {
591 fn describe(_tcx: TyCtxt, _: Ty) -> String {
592 format!("normalizing types")
596 impl<'tcx> QueryDescription<'tcx> for queries::typeck_tables_of<'tcx> {
598 fn cache_on_disk(def_id: Self::Key) -> bool {
602 fn try_load_from_disk(tcx: TyCtxt<'_, 'tcx, 'tcx>,
603 id: SerializedDepNodeIndex)
604 -> Option<Self::Value> {
605 let typeck_tables: Option<ty::TypeckTables<'tcx>> = tcx
606 .on_disk_query_result_cache
607 .try_load_query_result(tcx, id);
609 typeck_tables.map(|tables| tcx.alloc_tables(tables))
613 impl<'tcx> QueryDescription<'tcx> for queries::optimized_mir<'tcx> {
615 fn cache_on_disk(def_id: Self::Key) -> bool {
619 fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
620 id: SerializedDepNodeIndex)
621 -> Option<Self::Value> {
622 let mir: Option<::mir::Mir<'tcx>> = tcx.on_disk_query_result_cache
623 .try_load_query_result(tcx, id);
624 mir.map(|x| tcx.alloc_mir(x))
628 impl<'tcx> QueryDescription<'tcx> for queries::substitute_normalize_and_test_predicates<'tcx> {
629 fn describe(tcx: TyCtxt, key: (DefId, &'tcx Substs<'tcx>)) -> String {
630 format!("testing substituted normalized predicates:`{}`", tcx.item_path_str(key.0))
634 macro_rules! impl_disk_cacheable_query(
635 ($query_name:ident, |$key:tt| $cond:expr) => {
636 impl<'tcx> QueryDescription<'tcx> for queries::$query_name<'tcx> {
638 fn cache_on_disk($key: Self::Key) -> bool {
643 fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
644 id: SerializedDepNodeIndex)
645 -> Option<Self::Value> {
646 tcx.on_disk_query_result_cache.try_load_query_result(tcx, id)
652 impl_disk_cacheable_query!(unsafety_check_result, |def_id| def_id.is_local());
653 impl_disk_cacheable_query!(borrowck, |def_id| def_id.is_local());
654 impl_disk_cacheable_query!(mir_borrowck, |def_id| def_id.is_local());
655 impl_disk_cacheable_query!(mir_const_qualif, |def_id| def_id.is_local());
656 impl_disk_cacheable_query!(check_match, |def_id| def_id.is_local());
657 impl_disk_cacheable_query!(contains_extern_indicator, |_| true);
658 impl_disk_cacheable_query!(def_symbol_name, |_| true);