]> git.lizzy.rs Git - rust.git/commitdiff
rustc: rename ty::maps to ty::query.
authorEduard-Mihai Burtescu <edy.burt@gmail.com>
Wed, 13 Jun 2018 13:44:43 +0000 (16:44 +0300)
committerEduard-Mihai Burtescu <edy.burt@gmail.com>
Thu, 14 Jun 2018 15:05:12 +0000 (18:05 +0300)
65 files changed:
src/README.md
src/librustc/dep_graph/graph.rs
src/librustc/hir/mod.rs
src/librustc/lint/mod.rs
src/librustc/middle/const_val.rs
src/librustc/middle/reachable.rs
src/librustc/middle/region.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc/traits/mod.rs
src/librustc/ty/context.rs
src/librustc/ty/erase_regions.rs
src/librustc/ty/layout.rs
src/librustc/ty/maps/README.md [deleted file]
src/librustc/ty/maps/config.rs [deleted file]
src/librustc/ty/maps/job.rs [deleted file]
src/librustc/ty/maps/keys.rs [deleted file]
src/librustc/ty/maps/mod.rs [deleted file]
src/librustc/ty/maps/on_disk_cache.rs [deleted file]
src/librustc/ty/maps/plumbing.rs [deleted file]
src/librustc/ty/maps/values.rs [deleted file]
src/librustc/ty/mod.rs
src/librustc/ty/query/README.md [new file with mode: 0644]
src/librustc/ty/query/config.rs [new file with mode: 0644]
src/librustc/ty/query/job.rs [new file with mode: 0644]
src/librustc/ty/query/keys.rs [new file with mode: 0644]
src/librustc/ty/query/mod.rs [new file with mode: 0644]
src/librustc/ty/query/on_disk_cache.rs [new file with mode: 0644]
src/librustc/ty/query/plumbing.rs [new file with mode: 0644]
src/librustc/ty/query/values.rs [new file with mode: 0644]
src/librustc/ty/util.rs
src/librustc_borrowck/borrowck/mod.rs
src/librustc_codegen_llvm/attributes.rs
src/librustc_codegen_llvm/back/symbol_export.rs
src/librustc_codegen_llvm/base.rs
src/librustc_codegen_llvm/lib.rs
src/librustc_codegen_utils/codegen_backend.rs
src/librustc_codegen_utils/symbol_names.rs
src/librustc_driver/driver.rs
src/librustc_driver/test.rs
src/librustc_incremental/persist/dirty_clean.rs
src/librustc_incremental/persist/load.rs
src/librustc_metadata/cstore_impl.rs
src/librustc_mir/borrow_check/mod.rs
src/librustc_mir/interpret/eval_context.rs
src/librustc_mir/interpret/memory.rs
src/librustc_mir/lib.rs
src/librustc_mir/shim.rs
src/librustc_mir/transform/check_unsafety.rs
src/librustc_mir/transform/inline.rs
src/librustc_mir/transform/mod.rs
src/librustc_mir/transform/qualify_consts.rs
src/librustc_passes/lib.rs
src/librustc_passes/rvalue_promotion.rs
src/librustc_privacy/lib.rs
src/librustc_traits/lib.rs
src/librustc_typeck/check/method/mod.rs
src/librustc_typeck/check/method/suggest.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/wfcheck.rs
src/librustc_typeck/coherence/mod.rs
src/librustc_typeck/collect.rs
src/librustc_typeck/lib.rs
src/librustc_typeck/outlives/mod.rs
src/librustc_typeck/variance/mod.rs
src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs

index 690ab674c64ebd96bf1700994b0097f506c58955..6da4944c392db58bde3aec9f189323da38cfac24 100644 (file)
@@ -6,7 +6,7 @@ This directory contains the source code of the rust project, including:
 For more information on how various parts of the compiler work, see the [rustc guide].
 
 Their is also useful content in the following READMEs, which are gradually being moved over to the guide:
-- https://github.com/rust-lang/rust/tree/master/src/librustc/ty/maps
+- https://github.com/rust-lang/rust/tree/master/src/librustc/ty/query
 - https://github.com/rust-lang/rust/tree/master/src/librustc/dep_graph
 - https://github.com/rust-lang/rust/blob/master/src/librustc/infer/region_constraints
 - https://github.com/rust-lang/rust/tree/master/src/librustc/infer/higher_ranked
index 26470ddc82af5c322ae46da1bd211bb88bec31be..2390d7eccce765ad275d5dbc64d31ee5bfead42c 100644 (file)
@@ -656,7 +656,7 @@ pub fn try_mark_green<'tcx>(&self,
                     // We failed to mark it green, so we try to force the query.
                     debug!("try_mark_green({:?}) --- trying to force \
                             dependency {:?}", dep_node, dep_dep_node);
-                    if ::ty::maps::force_from_dep_node(tcx, dep_dep_node) {
+                    if ::ty::query::force_from_dep_node(tcx, dep_dep_node) {
                         let dep_dep_node_color = data.colors.borrow().get(dep_dep_node_index);
 
                         match dep_dep_node_color {
@@ -742,14 +742,14 @@ pub fn try_mark_green<'tcx>(&self,
             // and emit other diagnostics before these diagnostics are emitted.
             // Such diagnostics should be emitted after these.
             // See https://github.com/rust-lang/rust/issues/48685
-            let diagnostics = tcx.on_disk_query_result_cache
+            let diagnostics = tcx.queries.on_disk_cache
                                  .load_diagnostics(tcx, prev_dep_node_index);
 
             if diagnostics.len() > 0 {
                 let handle = tcx.sess.diagnostic();
 
                 // Promote the previous diagnostics to the current session.
-                tcx.on_disk_query_result_cache
+                tcx.queries.on_disk_cache
                    .store_diagnostics(dep_node_index, diagnostics.clone());
 
                 for diagnostic in diagnostics {
index b7c66398f8500e3119d129f3aa30c358dc59612d..a0952720945e870ae2cffcf4b95c61ba3ca92ffb 100644 (file)
@@ -45,7 +45,7 @@
 use syntax::util::ThinVec;
 use syntax::util::parser::ExprPrecedence;
 use ty::AdtKind;
-use ty::maps::Providers;
+use ty::query::Providers;
 
 use rustc_data_structures::indexed_vec;
 use rustc_data_structures::sync::{ParallelIterator, par_iter, Send, Sync, scope};
index 56b7da4c5da8c534e3565d54f703652a608ad04e..9338e235c534df2f9fd7afd9a9a5d72e47023606 100644 (file)
@@ -47,7 +47,7 @@
 use syntax::visit as ast_visit;
 use syntax_pos::Span;
 use ty::TyCtxt;
-use ty::maps::Providers;
+use ty::query::Providers;
 use util::nodemap::NodeMap;
 
 pub use lint::context::{LateContext, EarlyContext, LintContext, LintStore,
index 88275b3c18cc1172f83fd736a02c362d129e52f3..2fa77be644e312bf898427dd7435e239d81946be 100644 (file)
@@ -11,7 +11,7 @@
 use hir::def_id::DefId;
 use ty;
 use ty::subst::Substs;
-use ty::maps::TyCtxtAt;
+use ty::query::TyCtxtAt;
 use mir::interpret::ConstValue;
 use errors::DiagnosticBuilder;
 
index 249651ef65da0eadd645695d0a5366b8d11c041e..6b47a90079a6e711518ae378bb97174d8ac67156 100644 (file)
@@ -21,7 +21,7 @@
 use hir::def_id::{DefId, CrateNum};
 use rustc_data_structures::sync::Lrc;
 use ty::{self, TyCtxt};
-use ty::maps::Providers;
+use ty::query::Providers;
 use middle::privacy;
 use session::config;
 use util::nodemap::{NodeSet, FxHashSet};
index 0ba204dc20606aab5345ffe885af9e07c0131d70..e478f493647728e9cb50886c7bbba443d54fcc6f 100644 (file)
@@ -27,7 +27,7 @@
 use syntax::ast;
 use syntax_pos::{Span, DUMMY_SP};
 use ty::TyCtxt;
-use ty::maps::Providers;
+use ty::query::Providers;
 
 use hir;
 use hir::def_id::DefId;
index 14c1993e28e152ed1023394ffc99f7054b8aa49c..781d48e2123938d2e57608242cf2f94c8d523135 100644 (file)
@@ -349,8 +349,8 @@ struct ElisionFailureInfo {
 
 const ROOT_SCOPE: ScopeRef<'static> = &Scope::Root;
 
-pub fn provide(providers: &mut ty::maps::Providers) {
-    *providers = ty::maps::Providers {
+pub fn provide(providers: &mut ty::query::Providers) {
+    *providers = ty::query::Providers {
         resolve_lifetimes,
 
         named_region_map: |tcx, id| {
index e284b3fc75a6418475c3f7934f63dc8dae14fdbf..761de0014384265933c40d77a94430659c83d95b 100644 (file)
@@ -991,8 +991,8 @@ fn self_ty(&self) -> ty::Binder<Ty<'tcx>> {
     }
 }
 
-pub fn provide(providers: &mut ty::maps::Providers) {
-    *providers = ty::maps::Providers {
+pub fn provide(providers: &mut ty::query::Providers) {
+    *providers = ty::query::Providers {
         is_object_safe: object_safety::is_object_safe_provider,
         specialization_graph_of: specialize::specialization_graph_provider,
         specializes: specialize::specializes,
index e66ad24231094967b43876bf1fa448ae996d8c30..4433394d2719f89cd99d9a5fb11c304a70463c9d 100644 (file)
@@ -46,7 +46,7 @@
 use ty::TypeVariants::*;
 use ty::GenericParamDefKind;
 use ty::layout::{LayoutDetails, TargetDataLayout};
-use ty::maps;
+use ty::query;
 use ty::steal::Steal;
 use ty::BindingMode;
 use ty::CanonicalTy;
@@ -863,11 +863,6 @@ pub struct GlobalCtxt<'tcx> {
 
     pub dep_graph: DepGraph,
 
-    /// This provides access to the incr. comp. on-disk cache for query results.
-    /// Do not access this directly. It is only meant to be used by
-    /// `DepGraph::try_mark_green()` and the query infrastructure in `ty::maps`.
-    pub(crate) on_disk_query_result_cache: maps::OnDiskCache<'tcx>,
-
     /// Common types, pre-interned for your convenience.
     pub types: CommonTypes<'tcx>,
 
@@ -886,7 +881,7 @@ pub struct GlobalCtxt<'tcx> {
     /// as well as all upstream crates. Only populated in incremental mode.
     pub def_path_hash_to_def_id: Option<FxHashMap<DefPathHash, DefId>>,
 
-    pub maps: maps::Maps<'tcx>,
+    pub(crate) queries: query::Queries<'tcx>,
 
     // Records the free variables refrenced by every closure
     // expression. Do not track deps for this, just recompute it from
@@ -1074,12 +1069,12 @@ fn is_global(self) -> bool {
     /// reference to the context, to allow formatting values that need it.
     pub fn create_and_enter<F, R>(s: &'tcx Session,
                                   cstore: &'tcx CrateStoreDyn,
-                                  local_providers: ty::maps::Providers<'tcx>,
-                                  extern_providers: ty::maps::Providers<'tcx>,
+                                  local_providers: ty::query::Providers<'tcx>,
+                                  extern_providers: ty::query::Providers<'tcx>,
                                   arenas: &'tcx AllArenas<'tcx>,
                                   resolutions: ty::Resolutions,
                                   hir: hir_map::Map<'tcx>,
-                                  on_disk_query_result_cache: maps::OnDiskCache<'tcx>,
+                                  on_disk_query_result_cache: query::OnDiskCache<'tcx>,
                                   crate_name: &str,
                                   tx: mpsc::Sender<Box<dyn Any + Send>>,
                                   output_filenames: &OutputFilenames,
@@ -1144,7 +1139,6 @@ pub fn create_and_enter<F, R>(s: &'tcx Session,
             global_arenas: &arenas.global,
             global_interners: interners,
             dep_graph: dep_graph.clone(),
-            on_disk_query_result_cache,
             types: common_types,
             trait_map,
             export_map: resolutions.export_map.into_iter().map(|(k, v)| {
@@ -1165,7 +1159,7 @@ pub fn create_and_enter<F, R>(s: &'tcx Session,
                     .collect(),
             hir,
             def_path_hash_to_def_id,
-            maps: maps::Maps::new(providers),
+            queries: query::Queries::new(providers, on_disk_query_result_cache),
             rcache: Lock::new(FxHashMap()),
             selection_cache: traits::SelectionCache::new(),
             evaluation_cache: traits::EvaluationCache::new(),
@@ -1343,7 +1337,7 @@ pub fn serialize_query_result_cache<E>(self,
                                            -> Result<(), E::Error>
         where E: ty::codec::TyEncoder
     {
-        self.on_disk_query_result_cache.serialize(self.global_tcx(), encoder)
+        self.queries.on_disk_cache.serialize(self.global_tcx(), encoder)
     }
 
     /// If true, we should use a naive AST walk to determine if match
@@ -1702,7 +1696,7 @@ pub mod tls {
     use std::fmt;
     use std::mem;
     use syntax_pos;
-    use ty::maps;
+    use ty::query;
     use errors::{Diagnostic, TRACK_DIAGNOSTICS};
     use rustc_data_structures::OnDrop;
     use rustc_data_structures::sync::{self, Lrc, Lock};
@@ -1726,8 +1720,8 @@ pub struct ImplicitCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
         pub tcx: TyCtxt<'a, 'gcx, 'tcx>,
 
         /// The current query job, if any. This is updated by start_job in
-        /// ty::maps::plumbing when executing a query
-        pub query: Option<Lrc<maps::QueryJob<'gcx>>>,
+        /// ty::query::plumbing when executing a query
+        pub query: Option<Lrc<query::QueryJob<'gcx>>>,
 
         /// Used to prevent layout from recursing too deeply.
         pub layout_depth: usize,
@@ -2792,7 +2786,7 @@ fn intern_with<I: Iterator<Item=Self>, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> S
     }
 }
 
-pub fn provide(providers: &mut ty::maps::Providers) {
+pub fn provide(providers: &mut ty::query::Providers) {
     // FIXME(#44234) - almost all of these queries have no sub-queries and
     // therefore no actual inputs, they're just reading tables calculated in
     // resolve! Does this work? Unsure! That's what the issue is about
index f483b4c174ac3881ce1705d6c09fadba04d4122a..2fb2154ce6ba0f5a3ca0ce277db399af4941cf04 100644 (file)
@@ -11,8 +11,8 @@
 use ty::{self, Ty, TyCtxt};
 use ty::fold::{TypeFolder, TypeFoldable};
 
-pub(super) fn provide(providers: &mut ty::maps::Providers) {
-    *providers = ty::maps::Providers {
+pub(super) fn provide(providers: &mut ty::query::Providers) {
+    *providers = ty::query::Providers {
         erase_regions_ty,
         ..*providers
     };
index 499398abcf99622cd3ad02987ff8936510b71a8d..f5c2a0c3f9f05f504c09026d9ec714749b7e8fff 100644 (file)
@@ -194,8 +194,8 @@ fn layout_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     })
 }
 
-pub fn provide(providers: &mut ty::maps::Providers) {
-    *providers = ty::maps::Providers {
+pub fn provide(providers: &mut ty::query::Providers) {
+    *providers = ty::query::Providers {
         layout_raw,
         ..*providers
     };
@@ -1481,7 +1481,7 @@ fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
     }
 }
 
-impl<'a, 'tcx> LayoutOf for LayoutCx<'tcx, ty::maps::TyCtxtAt<'a, 'tcx, 'tcx>> {
+impl<'a, 'tcx> LayoutOf for LayoutCx<'tcx, ty::query::TyCtxtAt<'a, 'tcx, 'tcx>> {
     type Ty = Ty<'tcx>;
     type TyLayout = Result<TyLayout<'tcx>, LayoutError<'tcx>>;
 
@@ -1527,7 +1527,7 @@ pub fn layout_of(self, param_env_and_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
     }
 }
 
-impl ty::maps::TyCtxtAt<'a, 'tcx, '_> {
+impl ty::query::TyCtxtAt<'a, 'tcx, '_> {
     /// Computes the layout of a type. Note that this implicitly
     /// executes in "reveal all" mode.
     #[inline]
diff --git a/src/librustc/ty/maps/README.md b/src/librustc/ty/maps/README.md
deleted file mode 100644 (file)
index 8207c18..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-# The Rust Compiler Query System
-
-The Compiler Query System is the key to our new demand-driven
-organization.  The idea is pretty simple. You have various queries
-that compute things about the input -- for example, there is a query
-called `type_of(def_id)` that, given the def-id of some item, will
-compute the type of that item and return it to you.
-
-Query execution is **memoized** -- so the first time you invoke a
-query, it will go do the computation, but the next time, the result is
-returned from a hashtable. Moreover, query execution fits nicely into
-**incremental computation**; the idea is roughly that, when you do a
-query, the result **may** be returned to you by loading stored data
-from disk (but that's a separate topic we won't discuss further here).
-
-The overall vision is that, eventually, the entire compiler
-control-flow will be query driven. There will effectively be one
-top-level query ("compile") that will run compilation on a crate; this
-will in turn demand information about that crate, starting from the
-*end*.  For example:
-
-- This "compile" query might demand to get a list of codegen-units
-  (i.e., modules that need to be compiled by LLVM).
-- But computing the list of codegen-units would invoke some subquery
-  that returns the list of all modules defined in the Rust source.
-- That query in turn would invoke something asking for the HIR.
-- This keeps going further and further back until we wind up doing the
-  actual parsing.
-
-However, that vision is not fully realized. Still, big chunks of the
-compiler (for example, generating MIR) work exactly like this.
-
-### Invoking queries
-
-To invoke a query is simple. The tcx ("type context") offers a method
-for each defined query. So, for example, to invoke the `type_of`
-query, you would just do this:
-
-```rust
-let ty = tcx.type_of(some_def_id);
-```
-
-### Cycles between queries
-
-Currently, cycles during query execution should always result in a
-compilation error. Typically, they arise because of illegal programs
-that contain cyclic references they shouldn't (though sometimes they
-arise because of compiler bugs, in which case we need to factor our
-queries in a more fine-grained fashion to avoid them).
-
-However, it is nonetheless often useful to *recover* from a cycle
-(after reporting an error, say) and try to soldier on, so as to give a
-better user experience. In order to recover from a cycle, you don't
-get to use the nice method-call-style syntax. Instead, you invoke
-using the `try_get` method, which looks roughly like this:
-
-```rust
-use ty::maps::queries;
-...
-match queries::type_of::try_get(tcx, DUMMY_SP, self.did) {
-  Ok(result) => {
-    // no cycle occurred! You can use `result`
-  }
-  Err(err) => {
-    // A cycle occurred! The error value `err` is a `DiagnosticBuilder`,
-    // meaning essentially an "in-progress", not-yet-reported error message.
-    // See below for more details on what to do here.
-  }
-}
-```
-
-So, if you get back an `Err` from `try_get`, then a cycle *did* occur. This means that
-you must ensure that a compiler error message is reported. You can do that in two ways:
-
-The simplest is to invoke `err.emit()`. This will emit the cycle error to the user.
-
-However, often cycles happen because of an illegal program, and you
-know at that point that an error either already has been reported or
-will be reported due to this cycle by some other bit of code. In that
-case, you can invoke `err.cancel()` to not emit any error. It is
-traditional to then invoke:
-
-```
-tcx.sess.delay_span_bug(some_span, "some message")
-```
-
-`delay_span_bug()` is a helper that says: we expect a compilation
-error to have happened or to happen in the future; so, if compilation
-ultimately succeeds, make an ICE with the message `"some
-message"`. This is basically just a precaution in case you are wrong.
-
-### How the compiler executes a query
-
-So you may be wondering what happens when you invoke a query
-method. The answer is that, for each query, the compiler maintains a
-cache -- if your query has already been executed, then, the answer is
-simple: we clone the return value out of the cache and return it
-(therefore, you should try to ensure that the return types of queries
-are cheaply cloneable; insert a `Rc` if necessary).
-
-#### Providers
-
-If, however, the query is *not* in the cache, then the compiler will
-try to find a suitable **provider**. A provider is a function that has
-been defined and linked into the compiler somewhere that contains the
-code to compute the result of the query.
-
-**Providers are defined per-crate.** The compiler maintains,
-internally, a table of providers for every crate, at least
-conceptually. Right now, there are really two sets: the providers for
-queries about the **local crate** (that is, the one being compiled)
-and providers for queries about **external crates** (that is,
-dependencies of the local crate). Note that what determines the crate
-that a query is targeting is not the *kind* of query, but the *key*.
-For example, when you invoke `tcx.type_of(def_id)`, that could be a
-local query or an external query, depending on what crate the `def_id`
-is referring to (see the `self::keys::Key` trait for more information
-on how that works).
-
-Providers always have the same signature:
-
-```rust
-fn provider<'cx, 'tcx>(tcx: TyCtxt<'cx, 'tcx, 'tcx>,
-                       key: QUERY_KEY)
-                       -> QUERY_RESULT
-{
-    ...
-}
-```
-
-Providers take two arguments: the `tcx` and the query key. Note also
-that they take the *global* tcx (i.e., they use the `'tcx` lifetime
-twice), rather than taking a tcx with some active inference context.
-They return the result of the query.
-
-####  How providers are setup
-
-When the tcx is created, it is given the providers by its creator using
-the `Providers` struct. This struct is generate by the macros here, but it
-is basically a big list of function pointers:
-
-```rust
-struct Providers {
-    type_of: for<'cx, 'tcx> fn(TyCtxt<'cx, 'tcx, 'tcx>, DefId) -> Ty<'tcx>,
-    ...
-}
-```
-
-At present, we have one copy of the struct for local crates, and one
-for external crates, though the plan is that we may eventually have
-one per crate.
-
-These `Provider` structs are ultimately created and populated by
-`librustc_driver`, but it does this by distributing the work
-throughout the other `rustc_*` crates. This is done by invoking
-various `provide` functions. These functions tend to look something
-like this:
-
-```rust
-pub fn provide(providers: &mut Providers) {
-    *providers = Providers {
-        type_of,
-        ..*providers
-    };
-}
-```
-
-That is, they take an `&mut Providers` and mutate it in place. Usually
-we use the formulation above just because it looks nice, but you could
-as well do `providers.type_of = type_of`, which would be equivalent.
-(Here, `type_of` would be a top-level function, defined as we saw
-before.) So, if we want to add a provider for some other query,
-let's call it `fubar`, into the crate above, we might modify the `provide()`
-function like so:
-
-```rust
-pub fn provide(providers: &mut Providers) {
-    *providers = Providers {
-        type_of,
-        fubar,
-        ..*providers
-    };
-}
-
-fn fubar<'cx, 'tcx>(tcx: TyCtxt<'cx, 'tcx>, key: DefId) -> Fubar<'tcx> { .. }
-```
-
-NB. Most of the `rustc_*` crates only provide **local
-providers**. Almost all **extern providers** wind up going through the
-`rustc_metadata` crate, which loads the information from the crate
-metadata.  But in some cases there are crates that provide queries for
-*both* local and external crates, in which case they define both a
-`provide` and a `provide_extern` function that `rustc_driver` can
-invoke.
-
-### Adding a new kind of query
-
-So suppose you want to add a new kind of query, how do you do so?
-Well, defining a query takes place in two steps:
-
-1. first, you have to specify the query name and arguments; and then,
-2. you have to supply query providers where needed.
-
-To specify the query name and arguments, you simply add an entry
-to the big macro invocation in `mod.rs`. This will probably have changed
-by the time you read this README, but at present it looks something
-like:
-
-```
-define_maps! { <'tcx>
-    /// Records the type of every item.
-    [] fn type_of: TypeOfItem(DefId) -> Ty<'tcx>,
-
-    ...
-}
-```
-
-Each line of the macro defines one query. The name is broken up like this:
-
-```
-[] fn type_of: TypeOfItem(DefId) -> Ty<'tcx>,
-^^    ^^^^^^^  ^^^^^^^^^^ ^^^^^     ^^^^^^^^
-|     |        |          |         |
-|     |        |          |         result type of query
-|     |        |          query key type
-|     |        dep-node constructor
-|     name of query
-query flags
-```
-
-Let's go over them one by one:
-
-- **Query flags:** these are largely unused right now, but the intention
-  is that we'll be able to customize various aspects of how the query is
-  processed.
-- **Name of query:** the name of the query method
-  (`tcx.type_of(..)`). Also used as the name of a struct
-  (`ty::maps::queries::type_of`) that will be generated to represent
-  this query.
-- **Dep-node constructor:** indicates the constructor function that
-  connects this query to incremental compilation. Typically, this is a
-  `DepNode` variant, which can be added by modifying the
-  `define_dep_nodes!` macro invocation in
-  `librustc/dep_graph/dep_node.rs`.
-  - However, sometimes we use a custom function, in which case the
-    name will be in snake case and the function will be defined at the
-    bottom of the file. This is typically used when the query key is
-    not a def-id, or just not the type that the dep-node expects.
-- **Query key type:** the type of the argument to this query.
-  This type must implement the `ty::maps::keys::Key` trait, which
-  defines (for example) how to map it to a crate, and so forth.
-- **Result type of query:** the type produced by this query. This type
-  should (a) not use `RefCell` or other interior mutability and (b) be
-  cheaply cloneable. Interning or using `Rc` or `Arc` is recommended for
-  non-trivial data types.
-  - The one exception to those rules is the `ty::steal::Steal` type,
-    which is used to cheaply modify MIR in place. See the definition
-    of `Steal` for more details. New uses of `Steal` should **not** be
-    added without alerting `@rust-lang/compiler`.
-
-So, to add a query:
-
-- Add an entry to `define_maps!` using the format above.
-- Possibly add a corresponding entry to the dep-node macro.
-- Link the provider by modifying the appropriate `provide` method;
-  or add a new one if needed and ensure that `rustc_driver` is invoking it.
-
-#### Query structs and descriptions
-
-For each kind, the `define_maps` macro will generate a "query struct"
-named after the query. This struct is a kind of a place-holder
-describing the query. Each such struct implements the
-`self::config::QueryConfig` trait, which has associated types for the
-key/value of that particular query. Basically the code generated looks something
-like this:
-
-```rust
-// Dummy struct representing a particular kind of query:
-pub struct type_of<'tcx> { phantom: PhantomData<&'tcx ()> }
-
-impl<'tcx> QueryConfig for type_of<'tcx> {
-  type Key = DefId;
-  type Value = Ty<'tcx>;
-}
-```
-
-There is an additional trait that you may wish to implement called
-`self::config::QueryDescription`. This trait is used during cycle
-errors to give a "human readable" name for the query, so that we can
-summarize what was happening when the cycle occurred. Implementing
-this trait is optional if the query key is `DefId`, but if you *don't*
-implement it, you get a pretty generic error ("processing `foo`...").
-You can put new impls into the `config` module. They look something like this:
-
-```rust
-impl<'tcx> QueryDescription for queries::type_of<'tcx> {
-    fn describe(tcx: TyCtxt, key: DefId) -> String {
-        format!("computing the type of `{}`", tcx.item_path_str(key))
-    }
-}
-```
-
diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs
deleted file mode 100644 (file)
index 19c97a9..0000000
+++ /dev/null
@@ -1,799 +0,0 @@
-// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use dep_graph::SerializedDepNodeIndex;
-use dep_graph::DepNode;
-use hir::def_id::{CrateNum, DefId, DefIndex};
-use mir::interpret::{GlobalId, ConstValue};
-use traits::query::{CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal};
-use ty::{self, ParamEnvAnd, Ty, TyCtxt};
-use ty::subst::Substs;
-use ty::maps::queries;
-use ty::maps::Query;
-use ty::maps::QueryMap;
-
-use std::hash::Hash;
-use std::fmt::Debug;
-use syntax_pos::symbol::InternedString;
-use rustc_data_structures::sync::Lock;
-use rustc_data_structures::stable_hasher::HashStable;
-use ich::StableHashingContext;
-
-/// Query configuration and description traits.
-
-pub trait QueryConfig<'tcx> {
-    const NAME: &'static str;
-
-    type Key: Eq + Hash + Clone + Debug;
-    type Value: Clone + for<'a> HashStable<StableHashingContext<'a>>;
-
-    fn query(key: Self::Key) -> Query<'tcx>;
-
-    // Don't use this method to access query results, instead use the methods on TyCtxt
-    fn query_map<'a>(tcx: TyCtxt<'a, 'tcx, '_>) -> &'a Lock<QueryMap<'tcx, Self>>;
-
-    fn to_dep_node(tcx: TyCtxt<'_, 'tcx, '_>, key: &Self::Key) -> DepNode;
-
-    // Don't use this method to compute query results, instead use the methods on TyCtxt
-    fn compute(tcx: TyCtxt<'_, 'tcx, '_>, key: Self::Key) -> Self::Value;
-
-    fn handle_cycle_error(tcx: TyCtxt<'_, 'tcx, '_>) -> Self::Value;
-}
-
-pub trait QueryDescription<'tcx>: QueryConfig<'tcx> {
-    fn describe(tcx: TyCtxt, key: Self::Key) -> String;
-
-    #[inline]
-    fn cache_on_disk(_: Self::Key) -> bool {
-        false
-    }
-
-    fn try_load_from_disk(_: TyCtxt<'_, 'tcx, 'tcx>,
-                          _: SerializedDepNodeIndex)
-                          -> Option<Self::Value> {
-        bug!("QueryDescription::load_from_disk() called for an unsupported query.")
-    }
-}
-
-impl<'tcx, M: QueryConfig<'tcx, Key=DefId>> QueryDescription<'tcx> for M {
-    default fn describe(tcx: TyCtxt, def_id: DefId) -> String {
-        if !tcx.sess.verbose() {
-            format!("processing `{}`", tcx.item_path_str(def_id))
-        } else {
-            let name = unsafe { ::std::intrinsics::type_name::<M>() };
-            format!("processing `{}` applied to `{:?}`", name, def_id)
-        }
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::normalize_projection_ty<'tcx> {
-    fn describe(
-        _tcx: TyCtxt,
-        goal: CanonicalProjectionGoal<'tcx>,
-    ) -> String {
-        format!("normalizing `{:?}`", goal)
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::dropck_outlives<'tcx> {
-    fn describe(_tcx: TyCtxt, goal: CanonicalTyGoal<'tcx>) -> String {
-        format!("computing dropck types for `{:?}`", goal)
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::normalize_ty_after_erasing_regions<'tcx> {
-    fn describe(_tcx: TyCtxt, goal: ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
-        format!("normalizing `{:?}`", goal)
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::evaluate_obligation<'tcx> {
-    fn describe(_tcx: TyCtxt, goal: CanonicalPredicateGoal<'tcx>) -> String {
-        format!("evaluating trait selection obligation `{}`", goal.value.value)
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::is_copy_raw<'tcx> {
-    fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
-        format!("computing whether `{}` is `Copy`", env.value)
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::is_sized_raw<'tcx> {
-    fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
-        format!("computing whether `{}` is `Sized`", env.value)
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::is_freeze_raw<'tcx> {
-    fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
-        format!("computing whether `{}` is freeze", env.value)
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::needs_drop_raw<'tcx> {
-    fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
-        format!("computing whether `{}` needs drop", env.value)
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::layout_raw<'tcx> {
-    fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
-        format!("computing layout of `{}`", env.value)
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::super_predicates_of<'tcx> {
-    fn describe(tcx: TyCtxt, def_id: DefId) -> String {
-        format!("computing the supertraits of `{}`",
-                tcx.item_path_str(def_id))
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::const_value_to_allocation<'tcx> {
-    fn describe(_tcx: TyCtxt, (val, ty): (ConstValue<'tcx>, Ty<'tcx>)) -> String {
-        format!("converting value `{:?}` ({}) to an allocation", val, ty)
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::erase_regions_ty<'tcx> {
-    fn describe(_tcx: TyCtxt, ty: Ty<'tcx>) -> String {
-        format!("erasing regions from `{:?}`", ty)
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::type_param_predicates<'tcx> {
-    fn describe(tcx: TyCtxt, (_, def_id): (DefId, DefId)) -> String {
-        let id = tcx.hir.as_local_node_id(def_id).unwrap();
-        format!("computing the bounds for type parameter `{}`",
-                tcx.hir.ty_param_name(id))
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::coherent_trait<'tcx> {
-    fn describe(tcx: TyCtxt, def_id: DefId) -> String {
-        format!("coherence checking all impls of trait `{}`",
-                tcx.item_path_str(def_id))
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::upstream_monomorphizations<'tcx> {
-    fn describe(_: TyCtxt, k: CrateNum) -> String {
-        format!("collecting available upstream monomorphizations `{:?}`", k)
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::crate_inherent_impls<'tcx> {
-    fn describe(_: TyCtxt, k: CrateNum) -> String {
-        format!("all inherent impls defined in crate `{:?}`", k)
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::crate_inherent_impls_overlap_check<'tcx> {
-    fn describe(_: TyCtxt, _: CrateNum) -> String {
-        format!("check for overlap between inherent impls defined in this crate")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::crate_variances<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("computing the variances for items in this crate")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::inferred_outlives_crate<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("computing the inferred outlives predicates for items in this crate")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::mir_shims<'tcx> {
-    fn describe(tcx: TyCtxt, def: ty::InstanceDef<'tcx>) -> String {
-        format!("generating MIR shim for `{}`",
-                tcx.item_path_str(def.def_id()))
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::privacy_access_levels<'tcx> {
-    fn describe(_: TyCtxt, _: CrateNum) -> String {
-        format!("privacy access levels")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::typeck_item_bodies<'tcx> {
-    fn describe(_: TyCtxt, _: CrateNum) -> String {
-        format!("type-checking all item bodies")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::reachable_set<'tcx> {
-    fn describe(_: TyCtxt, _: CrateNum) -> String {
-        format!("reachability")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::const_eval<'tcx> {
-    fn describe(tcx: TyCtxt, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) -> String {
-        format!("const-evaluating `{}`", tcx.item_path_str(key.value.instance.def.def_id()))
-    }
-
-    #[inline]
-    fn cache_on_disk(_key: Self::Key) -> bool {
-        true
-    }
-
-    #[inline]
-    fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                              id: SerializedDepNodeIndex)
-                              -> Option<Self::Value> {
-        tcx.on_disk_query_result_cache.try_load_query_result(tcx, id).map(Ok)
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::mir_keys<'tcx> {
-    fn describe(_: TyCtxt, _: CrateNum) -> String {
-        format!("getting a list of all mir_keys")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::symbol_name<'tcx> {
-    fn describe(_tcx: TyCtxt, instance: ty::Instance<'tcx>) -> String {
-        format!("computing the symbol for `{}`", instance)
-    }
-
-    #[inline]
-    fn cache_on_disk(_: Self::Key) -> bool {
-        true
-    }
-
-    #[inline]
-    fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                              id: SerializedDepNodeIndex)
-                              -> Option<Self::Value> {
-        tcx.on_disk_query_result_cache.try_load_query_result(tcx, id)
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::describe_def<'tcx> {
-    fn describe(_: TyCtxt, _: DefId) -> String {
-        bug!("describe_def")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::def_span<'tcx> {
-    fn describe(_: TyCtxt, _: DefId) -> String {
-        bug!("def_span")
-    }
-}
-
-
-impl<'tcx> QueryDescription<'tcx> for queries::lookup_stability<'tcx> {
-    fn describe(_: TyCtxt, _: DefId) -> String {
-        bug!("stability")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::lookup_deprecation_entry<'tcx> {
-    fn describe(_: TyCtxt, _: DefId) -> String {
-        bug!("deprecation")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::item_attrs<'tcx> {
-    fn describe(_: TyCtxt, _: DefId) -> String {
-        bug!("item_attrs")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::is_reachable_non_generic<'tcx> {
-    fn describe(_: TyCtxt, _: DefId) -> String {
-        bug!("is_reachable_non_generic")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::fn_arg_names<'tcx> {
-    fn describe(_: TyCtxt, _: DefId) -> String {
-        bug!("fn_arg_names")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::impl_parent<'tcx> {
-    fn describe(_: TyCtxt, _: DefId) -> String {
-        bug!("impl_parent")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::trait_of_item<'tcx> {
-    fn describe(_: TyCtxt, _: DefId) -> String {
-        bug!("trait_of_item")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::const_is_rvalue_promotable_to_static<'tcx> {
-    fn describe(tcx: TyCtxt, def_id: DefId) -> String {
-        format!("const checking if rvalue is promotable to static `{}`",
-            tcx.item_path_str(def_id))
-    }
-
-    #[inline]
-    fn cache_on_disk(_: Self::Key) -> bool {
-        true
-    }
-
-    #[inline]
-    fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                          id: SerializedDepNodeIndex)
-                          -> Option<Self::Value> {
-        tcx.on_disk_query_result_cache.try_load_query_result(tcx, id)
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::rvalue_promotable_map<'tcx> {
-    fn describe(tcx: TyCtxt, def_id: DefId) -> String {
-        format!("checking which parts of `{}` are promotable to static",
-                tcx.item_path_str(def_id))
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::is_mir_available<'tcx> {
-    fn describe(tcx: TyCtxt, def_id: DefId) -> String {
-        format!("checking if item is mir available: `{}`",
-            tcx.item_path_str(def_id))
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::codegen_fulfill_obligation<'tcx> {
-    fn describe(tcx: TyCtxt, key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)) -> String {
-        format!("checking if `{}` fulfills its obligations", tcx.item_path_str(key.1.def_id()))
-    }
-
-    #[inline]
-    fn cache_on_disk(_: Self::Key) -> bool {
-        true
-    }
-
-    #[inline]
-    fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                              id: SerializedDepNodeIndex)
-                              -> Option<Self::Value> {
-        tcx.on_disk_query_result_cache.try_load_query_result(tcx, id)
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::trait_impls_of<'tcx> {
-    fn describe(tcx: TyCtxt, def_id: DefId) -> String {
-        format!("trait impls of `{}`", tcx.item_path_str(def_id))
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::is_object_safe<'tcx> {
-    fn describe(tcx: TyCtxt, def_id: DefId) -> String {
-        format!("determine object safety of trait `{}`", tcx.item_path_str(def_id))
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::is_const_fn<'tcx> {
-    fn describe(tcx: TyCtxt, def_id: DefId) -> String {
-        format!("checking if item is const fn: `{}`", tcx.item_path_str(def_id))
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::dylib_dependency_formats<'tcx> {
-    fn describe(_: TyCtxt, _: CrateNum) -> String {
-        "dylib dependency formats of crate".to_string()
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::is_panic_runtime<'tcx> {
-    fn describe(_: TyCtxt, _: CrateNum) -> String {
-        "checking if the crate is_panic_runtime".to_string()
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::is_compiler_builtins<'tcx> {
-    fn describe(_: TyCtxt, _: CrateNum) -> String {
-        "checking if the crate is_compiler_builtins".to_string()
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::has_global_allocator<'tcx> {
-    fn describe(_: TyCtxt, _: CrateNum) -> String {
-        "checking if the crate has_global_allocator".to_string()
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::extern_crate<'tcx> {
-    fn describe(_: TyCtxt, _: DefId) -> String {
-        "getting crate's ExternCrateData".to_string()
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::lint_levels<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("computing the lint levels for items in this crate")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::specializes<'tcx> {
-    fn describe(_tcx: TyCtxt, _: (DefId, DefId)) -> String {
-        format!("computing whether impls specialize one another")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::in_scope_traits_map<'tcx> {
-    fn describe(_tcx: TyCtxt, _: DefIndex) -> String {
-        format!("traits in scope at a block")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::is_no_builtins<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("test whether a crate has #![no_builtins]")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::panic_strategy<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("query a crate's configured panic strategy")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::is_profiler_runtime<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("query a crate is #![profiler_runtime]")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::is_sanitizer_runtime<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("query a crate is #![sanitizer_runtime]")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::reachable_non_generics<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("looking up the exported symbols of a crate")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::native_libraries<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("looking up the native libraries of a linked crate")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::foreign_modules<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("looking up the foreign modules of a linked crate")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::plugin_registrar_fn<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("looking up the plugin registrar for a crate")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::derive_registrar_fn<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("looking up the derive registrar for a crate")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::crate_disambiguator<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("looking up the disambiguator a crate")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::crate_hash<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("looking up the hash a crate")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::original_crate_name<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("looking up the original name a crate")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::extra_filename<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("looking up the extra filename for a crate")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::implementations_of_trait<'tcx> {
-    fn describe(_tcx: TyCtxt, _: (CrateNum, DefId)) -> String {
-        format!("looking up implementations of a trait in a crate")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::all_trait_implementations<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("looking up all (?) trait implementations")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::link_args<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("looking up link arguments for a crate")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::resolve_lifetimes<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("resolving lifetimes")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::named_region_map<'tcx> {
-    fn describe(_tcx: TyCtxt, _: DefIndex) -> String {
-        format!("looking up a named region")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::is_late_bound_map<'tcx> {
-    fn describe(_tcx: TyCtxt, _: DefIndex) -> String {
-        format!("testing if a region is late bound")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::object_lifetime_defaults_map<'tcx> {
-    fn describe(_tcx: TyCtxt, _: DefIndex) -> String {
-        format!("looking up lifetime defaults for a region")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::dep_kind<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("fetching what a dependency looks like")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::crate_name<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("fetching what a crate is named")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::get_lang_items<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("calculating the lang items map")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::defined_lang_items<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("calculating the lang items defined in a crate")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::missing_lang_items<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("calculating the missing lang items in a crate")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::visible_parent_map<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("calculating the visible parent map")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::missing_extern_crate_item<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("seeing if we're missing an `extern crate` item for this crate")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::used_crate_source<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("looking at the source for a crate")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::postorder_cnums<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("generating a postorder list of CrateNums")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::maybe_unused_extern_crates<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("looking up all possibly unused extern crates")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::stability_index<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("calculating the stability index for the local crate")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::all_traits<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("fetching all foreign and local traits")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::all_crate_nums<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("fetching all foreign CrateNum instances")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::exported_symbols<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("exported_symbols")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::collect_and_partition_mono_items<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("collect_and_partition_mono_items")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::codegen_unit<'tcx> {
-    fn describe(_tcx: TyCtxt, _: InternedString) -> String {
-        format!("codegen_unit")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::compile_codegen_unit<'tcx> {
-    fn describe(_tcx: TyCtxt, _: InternedString) -> String {
-        format!("compile_codegen_unit")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::output_filenames<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("output_filenames")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::vtable_methods<'tcx> {
-    fn describe(tcx: TyCtxt, key: ty::PolyTraitRef<'tcx> ) -> String {
-        format!("finding all methods for trait {}", tcx.item_path_str(key.def_id()))
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::features_query<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("looking up enabled feature gates")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::typeck_tables_of<'tcx> {
-    #[inline]
-    fn cache_on_disk(def_id: Self::Key) -> bool {
-        def_id.is_local()
-    }
-
-    fn try_load_from_disk(tcx: TyCtxt<'_, 'tcx, 'tcx>,
-                          id: SerializedDepNodeIndex)
-                          -> Option<Self::Value> {
-        let typeck_tables: Option<ty::TypeckTables<'tcx>> = tcx
-            .on_disk_query_result_cache
-            .try_load_query_result(tcx, id);
-
-        typeck_tables.map(|tables| tcx.alloc_tables(tables))
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::optimized_mir<'tcx> {
-    #[inline]
-    fn cache_on_disk(def_id: Self::Key) -> bool {
-        def_id.is_local()
-    }
-
-    fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                              id: SerializedDepNodeIndex)
-                              -> Option<Self::Value> {
-        let mir: Option<::mir::Mir<'tcx>> = tcx.on_disk_query_result_cache
-                                               .try_load_query_result(tcx, id);
-        mir.map(|x| tcx.alloc_mir(x))
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::substitute_normalize_and_test_predicates<'tcx> {
-    fn describe(tcx: TyCtxt, key: (DefId, &'tcx Substs<'tcx>)) -> String {
-        format!("testing substituted normalized predicates:`{}`", tcx.item_path_str(key.0))
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::target_features_whitelist<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("looking up the whitelist of target features")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::instance_def_size_estimate<'tcx> {
-    fn describe(tcx: TyCtxt, def: ty::InstanceDef<'tcx>) -> String {
-        format!("estimating size for `{}`", tcx.item_path_str(def.def_id()))
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::wasm_custom_sections<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("custom wasm sections for a crate")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::generics_of<'tcx> {
-    #[inline]
-    fn cache_on_disk(def_id: Self::Key) -> bool {
-        def_id.is_local()
-    }
-
-    fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                              id: SerializedDepNodeIndex)
-                              -> Option<Self::Value> {
-        let generics: Option<ty::Generics> = tcx.on_disk_query_result_cache
-                                                .try_load_query_result(tcx, id);
-        generics.map(|x| tcx.alloc_generics(x))
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::program_clauses_for<'tcx> {
-    fn describe(_tcx: TyCtxt, _: DefId) -> String {
-        format!("generating chalk-style clauses")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::program_clauses_for_env<'tcx> {
-    fn describe(_tcx: TyCtxt, _: ty::ParamEnv<'tcx>) -> String {
-        format!("generating chalk-style clauses for param env")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::wasm_import_module_map<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("wasm import module map")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::dllimport_foreign_items<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("wasm import module map")
-    }
-}
-
-macro_rules! impl_disk_cacheable_query(
-    ($query_name:ident, |$key:tt| $cond:expr) => {
-        impl<'tcx> QueryDescription<'tcx> for queries::$query_name<'tcx> {
-            #[inline]
-            fn cache_on_disk($key: Self::Key) -> bool {
-                $cond
-            }
-
-            #[inline]
-            fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                      id: SerializedDepNodeIndex)
-                                      -> Option<Self::Value> {
-                tcx.on_disk_query_result_cache.try_load_query_result(tcx, id)
-            }
-        }
-    }
-);
-
-impl_disk_cacheable_query!(unsafety_check_result, |def_id| def_id.is_local());
-impl_disk_cacheable_query!(borrowck, |def_id| def_id.is_local());
-impl_disk_cacheable_query!(mir_borrowck, |def_id| def_id.is_local());
-impl_disk_cacheable_query!(mir_const_qualif, |def_id| def_id.is_local());
-impl_disk_cacheable_query!(check_match, |def_id| def_id.is_local());
-impl_disk_cacheable_query!(def_symbol_name, |_| true);
-impl_disk_cacheable_query!(type_of, |def_id| def_id.is_local());
-impl_disk_cacheable_query!(predicates_of, |def_id| def_id.is_local());
-impl_disk_cacheable_query!(used_trait_imports, |def_id| def_id.is_local());
-impl_disk_cacheable_query!(codegen_fn_attrs, |_| true);
-impl_disk_cacheable_query!(specialization_graph_of, |_| true);
diff --git a/src/librustc/ty/maps/job.rs b/src/librustc/ty/maps/job.rs
deleted file mode 100644 (file)
index 3da73d4..0000000
+++ /dev/null
@@ -1,525 +0,0 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![allow(warnings)]
-
-use std::mem;
-use rustc_data_structures::sync::{Lock, LockGuard, Lrc, Weak};
-use rustc_data_structures::OnDrop;
-use syntax_pos::Span;
-use ty::tls;
-use ty::maps::Query;
-use ty::maps::plumbing::CycleError;
-use ty::context::TyCtxt;
-use errors::Diagnostic;
-use std::process;
-use std::fmt;
-use std::collections::HashSet;
-#[cfg(parallel_queries)]
-use {
-    rayon_core,
-    parking_lot::{Mutex, Condvar},
-    std::sync::atomic::Ordering,
-    std::thread,
-    std::iter,
-    std::iter::FromIterator,
-    syntax_pos::DUMMY_SP,
-    rustc_data_structures::stable_hasher::{StableHasherResult, StableHasher, HashStable},
-};
-
-/// Indicates the state of a query for a given key in a query map
-pub(super) enum QueryResult<'tcx> {
-    /// An already executing query. The query job can be used to await for its completion
-    Started(Lrc<QueryJob<'tcx>>),
-
-    /// The query panicked. Queries trying to wait on this will raise a fatal error / silently panic
-    Poisoned,
-}
-
-/// A span and a query key
-#[derive(Clone, Debug)]
-pub struct QueryInfo<'tcx> {
-    /// The span for a reason this query was required
-    pub span: Span,
-    pub query: Query<'tcx>,
-}
-
-/// A object representing an active query job.
-pub struct QueryJob<'tcx> {
-    pub info: QueryInfo<'tcx>,
-
-    /// The parent query job which created this job and is implicitly waiting on it.
-    pub parent: Option<Lrc<QueryJob<'tcx>>>,
-
-    /// Diagnostic messages which are emitted while the query executes
-    pub diagnostics: Lock<Vec<Diagnostic>>,
-
-    /// The latch which is used to wait on this job
-    #[cfg(parallel_queries)]
-    latch: QueryLatch<'tcx>,
-}
-
-impl<'tcx> QueryJob<'tcx> {
-    /// Creates a new query job
-    pub fn new(info: QueryInfo<'tcx>, parent: Option<Lrc<QueryJob<'tcx>>>) -> Self {
-        QueryJob {
-            diagnostics: Lock::new(Vec::new()),
-            info,
-            parent,
-            #[cfg(parallel_queries)]
-            latch: QueryLatch::new(),
-        }
-    }
-
-    /// Awaits for the query job to complete.
-    ///
-    /// For single threaded rustc there's no concurrent jobs running, so if we are waiting for any
-    /// query that means that there is a query cycle, thus this always running a cycle error.
-    pub(super) fn await<'lcx>(
-        &self,
-        tcx: TyCtxt<'_, 'tcx, 'lcx>,
-        span: Span,
-    ) -> Result<(), CycleError<'tcx>> {
-        #[cfg(not(parallel_queries))]
-        {
-            self.find_cycle_in_stack(tcx, span)
-        }
-
-        #[cfg(parallel_queries)]
-        {
-            tls::with_related_context(tcx, move |icx| {
-                let mut waiter = Lrc::new(QueryWaiter {
-                    query: icx.query.clone(),
-                    span,
-                    cycle: Lock::new(None),
-                    condvar: Condvar::new(),
-                });
-                self.latch.await(&waiter);
-
-                match Lrc::get_mut(&mut waiter).unwrap().cycle.get_mut().take() {
-                    None => Ok(()),
-                    Some(cycle) => Err(cycle)
-                }
-            })
-        }
-    }
-
-    #[cfg(not(parallel_queries))]
-    fn find_cycle_in_stack<'lcx>(
-        &self,
-        tcx: TyCtxt<'_, 'tcx, 'lcx>,
-        span: Span,
-    ) -> Result<(), CycleError<'tcx>> {
-        // Get the current executing query (waiter) and find the waitee amongst its parents
-        let mut current_job = tls::with_related_context(tcx, |icx| icx.query.clone());
-        let mut cycle = Vec::new();
-
-        while let Some(job) = current_job {
-            cycle.insert(0, job.info.clone());
-
-            if &*job as *const _ == self as *const _ {
-                // This is the end of the cycle
-                // The span entry we included was for the usage
-                // of the cycle itself, and not part of the cycle
-                // Replace it with the span which caused the cycle to form
-                cycle[0].span = span;
-                // Find out why the cycle itself was used
-                let usage = job.parent.as_ref().map(|parent| {
-                    (job.info.span, parent.info.query.clone())
-                });
-                return Err(CycleError { usage, cycle });
-            }
-
-            current_job = job.parent.clone();
-        }
-
-        panic!("did not find a cycle")
-    }
-
-    /// Signals to waiters that the query is complete.
-    ///
-    /// This does nothing for single threaded rustc,
-    /// as there are no concurrent jobs which could be waiting on us
-    pub fn signal_complete(&self) {
-        #[cfg(parallel_queries)]
-        self.latch.set();
-    }
-
-    fn as_ptr(&self) -> *const QueryJob<'tcx> {
-        self as *const _
-    }
-}
-
-#[cfg(parallel_queries)]
-struct QueryWaiter<'tcx> {
-    query: Option<Lrc<QueryJob<'tcx>>>,
-    condvar: Condvar,
-    span: Span,
-    cycle: Lock<Option<CycleError<'tcx>>>,
-}
-
-#[cfg(parallel_queries)]
-impl<'tcx> QueryWaiter<'tcx> {
-    fn notify(&self, registry: &rayon_core::Registry) {
-        rayon_core::mark_unblocked(registry);
-        self.condvar.notify_one();
-    }
-}
-
-#[cfg(parallel_queries)]
-struct QueryLatchInfo<'tcx> {
-    complete: bool,
-    waiters: Vec<Lrc<QueryWaiter<'tcx>>>,
-}
-
-#[cfg(parallel_queries)]
-struct QueryLatch<'tcx> {
-    info: Mutex<QueryLatchInfo<'tcx>>,
-}
-
-#[cfg(parallel_queries)]
-impl<'tcx> QueryLatch<'tcx> {
-    fn new() -> Self {
-        QueryLatch {
-            info: Mutex::new(QueryLatchInfo {
-                complete: false,
-                waiters: Vec::new(),
-            }),
-        }
-    }
-
-    /// Awaits the caller on this latch by blocking the current thread.
-    fn await(&self, waiter: &Lrc<QueryWaiter<'tcx>>) {
-        let mut info = self.info.lock();
-        if !info.complete {
-            // We push the waiter on to the `waiters` list. It can be accessed inside
-            // the `wait` call below, by 1) the `set` method or 2) by deadlock detection.
-            // Both of these will remove it from the `waiters` list before resuming
-            // this thread.
-            info.waiters.push(waiter.clone());
-
-            // If this detects a deadlock and the deadlock handler wants to resume this thread
-            // we have to be in the `wait` call. This is ensured by the deadlock handler
-            // getting the self.info lock.
-            rayon_core::mark_blocked();
-            waiter.condvar.wait(&mut info);
-        }
-    }
-
-    /// Sets the latch and resumes all waiters on it
-    fn set(&self) {
-        let mut info = self.info.lock();
-        debug_assert!(!info.complete);
-        info.complete = true;
-        let registry = rayon_core::Registry::current();
-        for waiter in info.waiters.drain(..) {
-            waiter.notify(&registry);
-        }
-    }
-
-    /// Remove a single waiter from the list of waiters.
-    /// This is used to break query cycles.
-    fn extract_waiter(
-        &self,
-        waiter: usize,
-    ) -> Lrc<QueryWaiter<'tcx>> {
-        let mut info = self.info.lock();
-        debug_assert!(!info.complete);
-        // Remove the waiter from the list of waiters
-        info.waiters.remove(waiter)
-    }
-}
-
-/// A resumable waiter of a query. The usize is the index into waiters in the query's latch
-#[cfg(parallel_queries)]
-type Waiter<'tcx> = (Lrc<QueryJob<'tcx>>, usize);
-
-/// Visits all the non-resumable and resumable waiters of a query.
-/// Only waiters in a query are visited.
-/// `visit` is called for every waiter and is passed a query waiting on `query_ref`
-/// and a span indicating the reason the query waited on `query_ref`.
-/// If `visit` returns Some, this function returns.
-/// For visits of non-resumable waiters it returns the return value of `visit`.
-/// For visits of resumable waiters it returns Some(Some(Waiter)) which has the
-/// required information to resume the waiter.
-/// If all `visit` calls returns None, this function also returns None.
-#[cfg(parallel_queries)]
-fn visit_waiters<'tcx, F>(query: Lrc<QueryJob<'tcx>>, mut visit: F) -> Option<Option<Waiter<'tcx>>>
-where
-    F: FnMut(Span, Lrc<QueryJob<'tcx>>) -> Option<Option<Waiter<'tcx>>>
-{
-    // Visit the parent query which is a non-resumable waiter since it's on the same stack
-    if let Some(ref parent) = query.parent {
-        if let Some(cycle) = visit(query.info.span, parent.clone()) {
-            return Some(cycle);
-        }
-    }
-
-    // Visit the explict waiters which use condvars and are resumable
-    for (i, waiter) in query.latch.info.lock().waiters.iter().enumerate() {
-        if let Some(ref waiter_query) = waiter.query {
-            if visit(waiter.span, waiter_query.clone()).is_some() {
-                // Return a value which indicates that this waiter can be resumed
-                return Some(Some((query.clone(), i)));
-            }
-        }
-    }
-    None
-}
-
-/// Look for query cycles by doing a depth first search starting at `query`.
-/// `span` is the reason for the `query` to execute. This is initially DUMMY_SP.
-/// If a cycle is detected, this initial value is replaced with the span causing
-/// the cycle.
-#[cfg(parallel_queries)]
-fn cycle_check<'tcx>(query: Lrc<QueryJob<'tcx>>,
-                     span: Span,
-                     stack: &mut Vec<(Span, Lrc<QueryJob<'tcx>>)>,
-                     visited: &mut HashSet<*const QueryJob<'tcx>>
-) -> Option<Option<Waiter<'tcx>>> {
-    if visited.contains(&query.as_ptr()) {
-        return if let Some(p) = stack.iter().position(|q| q.1.as_ptr() == query.as_ptr()) {
-            // We detected a query cycle, fix up the initial span and return Some
-
-            // Remove previous stack entries
-            stack.splice(0..p, iter::empty());
-            // Replace the span for the first query with the cycle cause
-            stack[0].0 = span;
-            Some(None)
-        } else {
-            None
-        }
-    }
-
-    // Mark this query is visited and add it to the stack
-    visited.insert(query.as_ptr());
-    stack.push((span, query.clone()));
-
-    // Visit all the waiters
-    let r = visit_waiters(query, |span, successor| {
-        cycle_check(successor, span, stack, visited)
-    });
-
-    // Remove the entry in our stack if we didn't find a cycle
-    if r.is_none() {
-        stack.pop();
-    }
-
-    r
-}
-
-/// Finds out if there's a path to the compiler root (aka. code which isn't in a query)
-/// from `query` without going through any of the queries in `visited`.
-/// This is achieved with a depth first search.
-#[cfg(parallel_queries)]
-fn connected_to_root<'tcx>(
-    query: Lrc<QueryJob<'tcx>>,
-    visited: &mut HashSet<*const QueryJob<'tcx>>
-) -> bool {
-    // We already visited this or we're deliberately ignoring it
-    if visited.contains(&query.as_ptr()) {
-        return false;
-    }
-
-    // This query is connected to the root (it has no query parent), return true
-    if query.parent.is_none() {
-        return true;
-    }
-
-    visited.insert(query.as_ptr());
-
-    let mut connected = false;
-
-    visit_waiters(query, |_, successor| {
-        if connected_to_root(successor, visited) {
-            Some(None)
-        } else {
-            None
-        }
-    }).is_some()
-}
-
-/// Looks for query cycles starting from the last query in `jobs`.
-/// If a cycle is found, all queries in the cycle is removed from `jobs` and
-/// the function return true.
-/// If a cycle was not found, the starting query is removed from `jobs` and
-/// the function returns false.
-#[cfg(parallel_queries)]
-fn remove_cycle<'tcx>(
-    jobs: &mut Vec<Lrc<QueryJob<'tcx>>>,
-    wakelist: &mut Vec<Lrc<QueryWaiter<'tcx>>>,
-    tcx: TyCtxt<'_, 'tcx, '_>
-) -> bool {
-    let mut visited = HashSet::new();
-    let mut stack = Vec::new();
-    // Look for a cycle starting with the last query in `jobs`
-    if let Some(waiter) = cycle_check(jobs.pop().unwrap(),
-                                      DUMMY_SP,
-                                      &mut stack,
-                                      &mut visited) {
-        // Reverse the stack so earlier entries require later entries
-        stack.reverse();
-
-        // Extract the spans and queries into separate arrays
-        let mut spans: Vec<_> = stack.iter().map(|e| e.0).collect();
-        let queries = stack.into_iter().map(|e| e.1);
-
-        // Shift the spans so that queries are matched with the span for their waitee
-        let last = spans.pop().unwrap();
-        spans.insert(0, last);
-
-        // Zip them back together
-        let mut stack: Vec<_> = spans.into_iter().zip(queries).collect();
-
-        // Remove the queries in our cycle from the list of jobs to look at
-        for r in &stack {
-            if let Some(pos) = jobs.iter().position(|j| j.as_ptr() == r.1.as_ptr()) {
-                jobs.remove(pos);
-            }
-        }
-
-        // Find the queries in the cycle which are
-        // connected to queries outside the cycle
-        let entry_points: Vec<Lrc<QueryJob<'tcx>>> = stack.iter().filter_map(|query| {
-            // Mark all the other queries in the cycle as already visited
-            let mut visited = HashSet::from_iter(stack.iter().filter_map(|q| {
-                if q.1.as_ptr() != query.1.as_ptr() {
-                    Some(q.1.as_ptr())
-                } else {
-                    None
-                }
-            }));
-
-            if connected_to_root(query.1.clone(), &mut visited) {
-                Some(query.1.clone())
-            } else {
-                None
-            }
-        }).collect();
-
-        // Deterministically pick an entry point
-        // FIXME: Sort this instead
-        let mut hcx = tcx.create_stable_hashing_context();
-        let entry_point = entry_points.iter().min_by_key(|q| {
-            let mut stable_hasher = StableHasher::<u64>::new();
-            q.info.query.hash_stable(&mut hcx, &mut stable_hasher);
-            stable_hasher.finish()
-        }).unwrap().as_ptr();
-
-        // Shift the stack until our entry point is first
-        while stack[0].1.as_ptr() != entry_point {
-            let last = stack.pop().unwrap();
-            stack.insert(0, last);
-        }
-
-        // Create the cycle error
-        let mut error = CycleError {
-            usage: None,
-            cycle: stack.iter().map(|&(s, ref q)| QueryInfo {
-                span: s,
-                query: q.info.query.clone(),
-            } ).collect(),
-        };
-
-        // We unwrap `waiter` here since there must always be one
-        // edge which is resumeable / waited using a query latch
-        let (waitee_query, waiter_idx) = waiter.unwrap();
-
-        // Extract the waiter we want to resume
-        let waiter = waitee_query.latch.extract_waiter(waiter_idx);
-
-        // Set the cycle error so it will be picked up when resumed
-        *waiter.cycle.lock() = Some(error);
-
-        // Put the waiter on the list of things to resume
-        wakelist.push(waiter);
-
-        true
-    } else {
-        false
-    }
-}
-
-/// Creates a new thread and forwards information in thread locals to it.
-/// The new thread runs the deadlock handler.
-/// Must only be called when a deadlock is about to happen.
-#[cfg(parallel_queries)]
-pub unsafe fn handle_deadlock() {
-    use syntax;
-    use syntax_pos;
-
-    let registry = rayon_core::Registry::current();
-
-    let gcx_ptr = tls::GCX_PTR.with(|gcx_ptr| {
-        gcx_ptr as *const _
-    });
-    let gcx_ptr = &*gcx_ptr;
-
-    let syntax_globals = syntax::GLOBALS.with(|syntax_globals| {
-        syntax_globals as *const _
-    });
-    let syntax_globals = &*syntax_globals;
-
-    let syntax_pos_globals = syntax_pos::GLOBALS.with(|syntax_pos_globals| {
-        syntax_pos_globals as *const _
-    });
-    let syntax_pos_globals = &*syntax_pos_globals;
-    thread::spawn(move || {
-        tls::GCX_PTR.set(gcx_ptr, || {
-            syntax_pos::GLOBALS.set(syntax_pos_globals, || {
-                syntax_pos::GLOBALS.set(syntax_pos_globals, || {
-                    tls::with_thread_locals(|| {
-                        tls::with_global(|tcx| deadlock(tcx, &registry))
-                    })
-                })
-            })
-        })
-    });
-}
-
-/// Detects query cycles by using depth first search over all active query jobs.
-/// If a query cycle is found it will break the cycle by finding an edge which
-/// uses a query latch and then resuming that waiter.
-/// There may be multiple cycles involved in a deadlock, so this searches
-/// all active queries for cycles before finally resuming all the waiters at once.
-#[cfg(parallel_queries)]
-fn deadlock(tcx: TyCtxt<'_, '_, '_>, registry: &rayon_core::Registry) {
-    let on_panic = OnDrop(|| {
-        eprintln!("deadlock handler panicked, aborting process");
-        process::abort();
-    });
-
-    let mut wakelist = Vec::new();
-    let mut jobs: Vec<_> = tcx.maps.collect_active_jobs();
-
-    let mut found_cycle = false;
-
-    while jobs.len() > 0 {
-        if remove_cycle(&mut jobs, &mut wakelist, tcx) {
-            found_cycle = true;
-        }
-    }
-
-    // Check that a cycle was found. It is possible for a deadlock to occur without
-    // a query cycle if a query which can be waited on uses Rayon to do multithreading
-    // internally. Such a query (X) may be executing on 2 threads (A and B) and A may
-    // wait using Rayon on B. Rayon may then switch to executing another query (Y)
-    // which in turn will wait on X causing a deadlock. We have a false dependency from
-    // X to Y due to Rayon waiting and a true dependency from Y to X. The algorithm here
-    // only considers the true dependency and won't detect a cycle.
-    assert!(found_cycle);
-
-    // FIXME: Ensure this won't cause a deadlock before we return
-    for waiter in wakelist.into_iter() {
-        waiter.notify(registry);
-    }
-
-    on_panic.disable();
-}
diff --git a/src/librustc/ty/maps/keys.rs b/src/librustc/ty/maps/keys.rs
deleted file mode 100644 (file)
index 3510a1b..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Defines the set of legal keys that can be used in queries.
-
-use hir::def_id::{CrateNum, DefId, LOCAL_CRATE, DefIndex};
-use traits::query::{CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal};
-use ty::{self, Ty, TyCtxt};
-use ty::subst::Substs;
-use ty::fast_reject::SimplifiedType;
-use mir;
-
-use std::fmt::Debug;
-use std::hash::Hash;
-use syntax_pos::{Span, DUMMY_SP};
-use syntax_pos::symbol::InternedString;
-
-/// The `Key` trait controls what types can legally be used as the key
-/// for a query.
-pub trait Key: Clone + Hash + Eq + Debug {
-    /// Given an instance of this key, what crate is it referring to?
-    /// This is used to find the provider.
-    fn map_crate(&self) -> CrateNum;
-
-    /// In the event that a cycle occurs, if no explicit span has been
-    /// given for a query with key `self`, what span should we use?
-    fn default_span(&self, tcx: TyCtxt) -> Span;
-}
-
-impl<'tcx> Key for ty::InstanceDef<'tcx> {
-    fn map_crate(&self) -> CrateNum {
-        LOCAL_CRATE
-    }
-
-    fn default_span(&self, tcx: TyCtxt) -> Span {
-        tcx.def_span(self.def_id())
-    }
-}
-
-impl<'tcx> Key for ty::Instance<'tcx> {
-    fn map_crate(&self) -> CrateNum {
-        LOCAL_CRATE
-    }
-
-    fn default_span(&self, tcx: TyCtxt) -> Span {
-        tcx.def_span(self.def_id())
-    }
-}
-
-impl<'tcx> Key for mir::interpret::GlobalId<'tcx> {
-    fn map_crate(&self) -> CrateNum {
-        self.instance.map_crate()
-    }
-
-    fn default_span(&self, tcx: TyCtxt) -> Span {
-        self.instance.default_span(tcx)
-    }
-}
-
-impl Key for CrateNum {
-    fn map_crate(&self) -> CrateNum {
-        *self
-    }
-    fn default_span(&self, _: TyCtxt) -> Span {
-        DUMMY_SP
-    }
-}
-
-impl Key for DefIndex {
-    fn map_crate(&self) -> CrateNum {
-        LOCAL_CRATE
-    }
-    fn default_span(&self, _tcx: TyCtxt) -> Span {
-        DUMMY_SP
-    }
-}
-
-impl Key for DefId {
-    fn map_crate(&self) -> CrateNum {
-        self.krate
-    }
-    fn default_span(&self, tcx: TyCtxt) -> Span {
-        tcx.def_span(*self)
-    }
-}
-
-impl Key for (DefId, DefId) {
-    fn map_crate(&self) -> CrateNum {
-        self.0.krate
-    }
-    fn default_span(&self, tcx: TyCtxt) -> Span {
-        self.1.default_span(tcx)
-    }
-}
-
-impl Key for (CrateNum, DefId) {
-    fn map_crate(&self) -> CrateNum {
-        self.0
-    }
-    fn default_span(&self, tcx: TyCtxt) -> Span {
-        self.1.default_span(tcx)
-    }
-}
-
-impl Key for (DefId, SimplifiedType) {
-    fn map_crate(&self) -> CrateNum {
-        self.0.krate
-    }
-    fn default_span(&self, tcx: TyCtxt) -> Span {
-        self.0.default_span(tcx)
-    }
-}
-
-impl<'tcx> Key for (DefId, &'tcx Substs<'tcx>) {
-    fn map_crate(&self) -> CrateNum {
-        self.0.krate
-    }
-    fn default_span(&self, tcx: TyCtxt) -> Span {
-        self.0.default_span(tcx)
-    }
-}
-
-impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) {
-    fn map_crate(&self) -> CrateNum {
-        self.1.def_id().krate
-    }
-    fn default_span(&self, tcx: TyCtxt) -> Span {
-        tcx.def_span(self.1.def_id())
-    }
-}
-
-impl<'tcx> Key for ty::PolyTraitRef<'tcx>{
-    fn map_crate(&self) -> CrateNum {
-        self.def_id().krate
-    }
-    fn default_span(&self, tcx: TyCtxt) -> Span {
-        tcx.def_span(self.def_id())
-    }
-}
-
-impl<'tcx> Key for (mir::interpret::ConstValue<'tcx>, Ty<'tcx>) {
-    fn map_crate(&self) -> CrateNum {
-        LOCAL_CRATE
-    }
-    fn default_span(&self, _: TyCtxt) -> Span {
-        DUMMY_SP
-    }
-}
-
-impl<'tcx> Key for Ty<'tcx> {
-    fn map_crate(&self) -> CrateNum {
-        LOCAL_CRATE
-    }
-    fn default_span(&self, _: TyCtxt) -> Span {
-        DUMMY_SP
-    }
-}
-
-impl<'tcx> Key for ty::ParamEnv<'tcx> {
-    fn map_crate(&self) -> CrateNum {
-        LOCAL_CRATE
-    }
-    fn default_span(&self, _: TyCtxt) -> Span {
-        DUMMY_SP
-    }
-}
-
-impl<'tcx, T: Key> Key for ty::ParamEnvAnd<'tcx, T> {
-    fn map_crate(&self) -> CrateNum {
-        self.value.map_crate()
-    }
-    fn default_span(&self, tcx: TyCtxt) -> Span {
-        self.value.default_span(tcx)
-    }
-}
-
-impl Key for InternedString {
-    fn map_crate(&self) -> CrateNum {
-        LOCAL_CRATE
-    }
-    fn default_span(&self, _tcx: TyCtxt) -> Span {
-        DUMMY_SP
-    }
-}
-
-impl<'tcx> Key for CanonicalProjectionGoal<'tcx> {
-    fn map_crate(&self) -> CrateNum {
-        LOCAL_CRATE
-    }
-
-    fn default_span(&self, _tcx: TyCtxt) -> Span {
-        DUMMY_SP
-    }
-}
-
-impl<'tcx> Key for CanonicalTyGoal<'tcx> {
-    fn map_crate(&self) -> CrateNum {
-        LOCAL_CRATE
-    }
-
-    fn default_span(&self, _tcx: TyCtxt) -> Span {
-        DUMMY_SP
-    }
-}
-
-impl<'tcx> Key for CanonicalPredicateGoal<'tcx> {
-    fn map_crate(&self) -> CrateNum {
-        LOCAL_CRATE
-    }
-
-    fn default_span(&self, _tcx: TyCtxt) -> Span {
-        DUMMY_SP
-    }
-}
diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs
deleted file mode 100644 (file)
index 4aead31..0000000
+++ /dev/null
@@ -1,640 +0,0 @@
-// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use dep_graph::{DepConstructor, DepNode};
-use hir::def_id::{CrateNum, DefId, DefIndex};
-use hir::def::{Def, Export};
-use hir::{self, TraitCandidate, ItemLocalId, CodegenFnAttrs};
-use hir::svh::Svh;
-use infer::canonical::{self, Canonical};
-use lint;
-use middle::borrowck::BorrowCheckResult;
-use middle::cstore::{ExternCrate, LinkagePreference, NativeLibrary, ForeignModule};
-use middle::cstore::{NativeLibraryKind, DepKind, CrateSource};
-use middle::privacy::AccessLevels;
-use middle::reachable::ReachableSet;
-use middle::region;
-use middle::resolve_lifetime::{ResolveLifetimes, Region, ObjectLifetimeDefault};
-use middle::stability::{self, DeprecationEntry};
-use middle::lang_items::{LanguageItems, LangItem};
-use middle::exported_symbols::{SymbolExportLevel, ExportedSymbol};
-use middle::const_val::EvalResult;
-use mir::mono::{CodegenUnit, Stats};
-use mir;
-use mir::interpret::{GlobalId, Allocation, ConstValue};
-use session::{CompileResult, CrateDisambiguator};
-use session::config::OutputFilenames;
-use traits::{self, Vtable};
-use traits::query::{CanonicalPredicateGoal, CanonicalProjectionGoal,
-                    CanonicalTyGoal, NoSolution};
-use traits::query::dropck_outlives::{DtorckConstraint, DropckOutlivesResult};
-use traits::query::normalize::NormalizationResult;
-use traits::specialization_graph;
-use traits::Clauses;
-use ty::{self, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt};
-use ty::steal::Steal;
-use ty::subst::Substs;
-use util::nodemap::{DefIdSet, DefIdMap, ItemLocalSet};
-use util::common::{ErrorReported};
-
-use rustc_data_structures::indexed_set::IdxSetBuf;
-use rustc_target::spec::PanicStrategy;
-use rustc_data_structures::indexed_vec::IndexVec;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_data_structures::stable_hasher::StableVec;
-
-use std::ops::Deref;
-use rustc_data_structures::sync::Lrc;
-use std::sync::Arc;
-use syntax_pos::{Span, DUMMY_SP};
-use syntax_pos::symbol::InternedString;
-use syntax::attr;
-use syntax::ast;
-use syntax::feature_gate;
-use syntax::symbol::Symbol;
-
-#[macro_use]
-mod plumbing;
-use self::plumbing::*;
-pub use self::plumbing::{force_from_dep_node, CycleError};
-
-mod job;
-pub use self::job::{QueryJob, QueryInfo};
-#[cfg(parallel_queries)]
-pub use self::job::handle_deadlock;
-
-mod keys;
-pub use self::keys::Key;
-
-mod values;
-use self::values::Value;
-
-mod config;
-pub use self::config::QueryConfig;
-use self::config::QueryDescription;
-
-mod on_disk_cache;
-pub use self::on_disk_cache::OnDiskCache;
-
-// Each of these maps also corresponds to a method on a
-// `Provider` trait for requesting a value of that type,
-// and a method on `Maps` itself for doing that in a
-// a way that memoizes and does dep-graph tracking,
-// wrapping around the actual chain of providers that
-// the driver creates (using several `rustc_*` crates).
-//
-// The result of query must implement Clone. They must also implement ty::maps::values::Value
-// which produces an appropriate error value if the query resulted in a query cycle.
-// Queries marked with `fatal_cycle` do not need that implementation
-// as they will raise an fatal error on query cycles instead.
-define_maps! { <'tcx>
-    /// Records the type of every item.
-    [] fn type_of: TypeOfItem(DefId) -> Ty<'tcx>,
-
-    /// Maps from the def-id of an item (trait/struct/enum/fn) to its
-    /// associated generics and predicates.
-    [] fn generics_of: GenericsOfItem(DefId) -> &'tcx ty::Generics,
-    [] fn predicates_of: PredicatesOfItem(DefId) -> ty::GenericPredicates<'tcx>,
-    [] fn explicit_predicates_of: ExplicitPredicatesOfItem(DefId) -> ty::GenericPredicates<'tcx>,
-
-    /// Maps from the def-id of a trait to the list of
-    /// super-predicates. This is a subset of the full list of
-    /// predicates. We store these in a separate map because we must
-    /// evaluate them even during type conversion, often before the
-    /// full predicates are available (note that supertraits have
-    /// additional acyclicity requirements).
-    [] fn super_predicates_of: SuperPredicatesOfItem(DefId) -> ty::GenericPredicates<'tcx>,
-
-    /// To avoid cycles within the predicates of a single item we compute
-    /// per-type-parameter predicates for resolving `T::AssocTy`.
-    [] fn type_param_predicates: type_param_predicates((DefId, DefId))
-        -> ty::GenericPredicates<'tcx>,
-
-    [] fn trait_def: TraitDefOfItem(DefId) -> &'tcx ty::TraitDef,
-    [] fn adt_def: AdtDefOfItem(DefId) -> &'tcx ty::AdtDef,
-    [] fn adt_destructor: AdtDestructor(DefId) -> Option<ty::Destructor>,
-    [] fn adt_sized_constraint: SizedConstraint(DefId) -> &'tcx [Ty<'tcx>],
-    [] fn adt_dtorck_constraint: DtorckConstraint(
-        DefId
-    ) -> Result<DtorckConstraint<'tcx>, NoSolution>,
-
-    /// True if this is a const fn
-    [] fn is_const_fn: IsConstFn(DefId) -> bool,
-
-    /// True if this is a foreign item (i.e., linked via `extern { ... }`).
-    [] fn is_foreign_item: IsForeignItem(DefId) -> bool,
-
-    /// Get a map with the variance of every item; use `item_variance`
-    /// instead.
-    [] fn crate_variances: crate_variances(CrateNum) -> Lrc<ty::CrateVariancesMap>,
-
-    /// Maps from def-id of a type or region parameter to its
-    /// (inferred) variance.
-    [] fn variances_of: ItemVariances(DefId) -> Lrc<Vec<ty::Variance>>,
-
-    /// Maps from def-id of a type to its (inferred) outlives.
-    [] fn inferred_outlives_of: InferredOutlivesOf(DefId) -> Lrc<Vec<ty::Predicate<'tcx>>>,
-
-    /// Maps from def-id of a type to its (inferred) outlives.
-    [] fn inferred_outlives_crate: InferredOutlivesCrate(CrateNum)
-        -> Lrc<ty::CratePredicatesMap<'tcx>>,
-
-    /// Maps from an impl/trait def-id to a list of the def-ids of its items
-    [] fn associated_item_def_ids: AssociatedItemDefIds(DefId) -> Lrc<Vec<DefId>>,
-
-    /// Maps from a trait item to the trait item "descriptor"
-    [] fn associated_item: AssociatedItems(DefId) -> ty::AssociatedItem,
-
-    [] fn impl_trait_ref: ImplTraitRef(DefId) -> Option<ty::TraitRef<'tcx>>,
-    [] fn impl_polarity: ImplPolarity(DefId) -> hir::ImplPolarity,
-
-    /// Maps a DefId of a type to a list of its inherent impls.
-    /// Contains implementations of methods that are inherent to a type.
-    /// Methods in these implementations don't need to be exported.
-    [] fn inherent_impls: InherentImpls(DefId) -> Lrc<Vec<DefId>>,
-
-    /// Set of all the def-ids in this crate that have MIR associated with
-    /// them. This includes all the body owners, but also things like struct
-    /// constructors.
-    [] fn mir_keys: mir_keys(CrateNum) -> Lrc<DefIdSet>,
-
-    /// Maps DefId's that have an associated Mir to the result
-    /// of the MIR qualify_consts pass. The actual meaning of
-    /// the value isn't known except to the pass itself.
-    [] fn mir_const_qualif: MirConstQualif(DefId) -> (u8, Lrc<IdxSetBuf<mir::Local>>),
-
-    /// Fetch the MIR for a given def-id right after it's built - this includes
-    /// unreachable code.
-    [] fn mir_built: MirBuilt(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
-
-    /// Fetch the MIR for a given def-id up till the point where it is
-    /// ready for const evaluation.
-    ///
-    /// See the README for the `mir` module for details.
-    [] fn mir_const: MirConst(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
-
-    [] fn mir_validated: MirValidated(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
-
-    /// MIR after our optimization passes have run. This is MIR that is ready
-    /// for codegen. This is also the only query that can fetch non-local MIR, at present.
-    [] fn optimized_mir: MirOptimized(DefId) -> &'tcx mir::Mir<'tcx>,
-
-    /// The result of unsafety-checking this def-id.
-    [] fn unsafety_check_result: UnsafetyCheckResult(DefId) -> mir::UnsafetyCheckResult,
-
-    /// HACK: when evaluated, this reports a "unsafe derive on repr(packed)" error
-    [] fn unsafe_derive_on_repr_packed: UnsafeDeriveOnReprPacked(DefId) -> (),
-
-    /// The signature of functions and closures.
-    [] fn fn_sig: FnSignature(DefId) -> ty::PolyFnSig<'tcx>,
-
-    /// Caches CoerceUnsized kinds for impls on custom types.
-    [] fn coerce_unsized_info: CoerceUnsizedInfo(DefId)
-        -> ty::adjustment::CoerceUnsizedInfo,
-
-    [] fn typeck_item_bodies: typeck_item_bodies_dep_node(CrateNum) -> CompileResult,
-
-    [] fn typeck_tables_of: TypeckTables(DefId) -> &'tcx ty::TypeckTables<'tcx>,
-
-    [] fn used_trait_imports: UsedTraitImports(DefId) -> Lrc<DefIdSet>,
-
-    [] fn has_typeck_tables: HasTypeckTables(DefId) -> bool,
-
-    [] fn coherent_trait: CoherenceCheckTrait(DefId) -> (),
-
-    [] fn borrowck: BorrowCheck(DefId) -> Lrc<BorrowCheckResult>,
-
-    /// Borrow checks the function body. If this is a closure, returns
-    /// additional requirements that the closure's creator must verify.
-    [] fn mir_borrowck: MirBorrowCheck(DefId) -> mir::BorrowCheckResult<'tcx>,
-
-    /// Gets a complete map from all types to their inherent impls.
-    /// Not meant to be used directly outside of coherence.
-    /// (Defined only for LOCAL_CRATE)
-    [] fn crate_inherent_impls: crate_inherent_impls_dep_node(CrateNum) -> CrateInherentImpls,
-
-    /// Checks all types in the krate for overlap in their inherent impls. Reports errors.
-    /// Not meant to be used directly outside of coherence.
-    /// (Defined only for LOCAL_CRATE)
-    [] fn crate_inherent_impls_overlap_check: inherent_impls_overlap_check_dep_node(CrateNum) -> (),
-
-    /// Results of evaluating const items or constants embedded in
-    /// other items (such as enum variant explicit discriminants).
-    [] fn const_eval: const_eval_dep_node(ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
-        -> EvalResult<'tcx>,
-
-    /// Converts a constant value to an constant allocation
-    [] fn const_value_to_allocation: const_value_to_allocation(
-        (ConstValue<'tcx>, Ty<'tcx>)
-    ) -> &'tcx Allocation,
-
-    [] fn check_match: CheckMatch(DefId)
-        -> Result<(), ErrorReported>,
-
-    /// Performs the privacy check and computes "access levels".
-    [] fn privacy_access_levels: PrivacyAccessLevels(CrateNum) -> Lrc<AccessLevels>,
-
-    [] fn reachable_set: reachability_dep_node(CrateNum) -> ReachableSet,
-
-    /// Per-body `region::ScopeTree`. The `DefId` should be the owner-def-id for the body;
-    /// in the case of closures, this will be redirected to the enclosing function.
-    [] fn region_scope_tree: RegionScopeTree(DefId) -> Lrc<region::ScopeTree>,
-
-    [] fn mir_shims: mir_shim_dep_node(ty::InstanceDef<'tcx>) -> &'tcx mir::Mir<'tcx>,
-
-    [] fn def_symbol_name: SymbolName(DefId) -> ty::SymbolName,
-    [] fn symbol_name: symbol_name_dep_node(ty::Instance<'tcx>) -> ty::SymbolName,
-
-    [] fn describe_def: DescribeDef(DefId) -> Option<Def>,
-    [] fn def_span: DefSpan(DefId) -> Span,
-    [] fn lookup_stability: LookupStability(DefId) -> Option<&'tcx attr::Stability>,
-    [] fn lookup_deprecation_entry: LookupDeprecationEntry(DefId) -> Option<DeprecationEntry>,
-    [] fn item_attrs: ItemAttrs(DefId) -> Lrc<[ast::Attribute]>,
-    [] fn codegen_fn_attrs: codegen_fn_attrs(DefId) -> CodegenFnAttrs,
-    [] fn fn_arg_names: FnArgNames(DefId) -> Vec<ast::Name>,
-    /// Gets the rendered value of the specified constant or associated constant.
-    /// Used by rustdoc.
-    [] fn rendered_const: RenderedConst(DefId) -> String,
-    [] fn impl_parent: ImplParent(DefId) -> Option<DefId>,
-    [] fn trait_of_item: TraitOfItem(DefId) -> Option<DefId>,
-    [] fn const_is_rvalue_promotable_to_static: ConstIsRvaluePromotableToStatic(DefId) -> bool,
-    [] fn rvalue_promotable_map: RvaluePromotableMap(DefId) -> Lrc<ItemLocalSet>,
-    [] fn is_mir_available: IsMirAvailable(DefId) -> bool,
-    [] fn vtable_methods: vtable_methods_node(ty::PolyTraitRef<'tcx>)
-                          -> Lrc<Vec<Option<(DefId, &'tcx Substs<'tcx>)>>>,
-
-    [] fn codegen_fulfill_obligation: fulfill_obligation_dep_node(
-        (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)) -> Vtable<'tcx, ()>,
-    [] fn trait_impls_of: TraitImpls(DefId) -> Lrc<ty::trait_def::TraitImpls>,
-    [] fn specialization_graph_of: SpecializationGraph(DefId) -> Lrc<specialization_graph::Graph>,
-    [] fn is_object_safe: ObjectSafety(DefId) -> bool,
-
-    // Get the ParameterEnvironment for a given item; this environment
-    // will be in "user-facing" mode, meaning that it is suitabe for
-    // type-checking etc, and it does not normalize specializable
-    // associated types. This is almost always what you want,
-    // unless you are doing MIR optimizations, in which case you
-    // might want to use `reveal_all()` method to change modes.
-    [] fn param_env: ParamEnv(DefId) -> ty::ParamEnv<'tcx>,
-
-    // Trait selection queries. These are best used by invoking `ty.moves_by_default()`,
-    // `ty.is_copy()`, etc, since that will prune the environment where possible.
-    [] fn is_copy_raw: is_copy_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool,
-    [] fn is_sized_raw: is_sized_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool,
-    [] fn is_freeze_raw: is_freeze_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool,
-    [] fn needs_drop_raw: needs_drop_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool,
-    [] fn layout_raw: layout_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
-                                  -> Result<&'tcx ty::layout::LayoutDetails,
-                                            ty::layout::LayoutError<'tcx>>,
-
-    [] fn dylib_dependency_formats: DylibDepFormats(CrateNum)
-                                    -> Lrc<Vec<(CrateNum, LinkagePreference)>>,
-
-    [fatal_cycle] fn is_panic_runtime: IsPanicRuntime(CrateNum) -> bool,
-    [fatal_cycle] fn is_compiler_builtins: IsCompilerBuiltins(CrateNum) -> bool,
-    [fatal_cycle] fn has_global_allocator: HasGlobalAllocator(CrateNum) -> bool,
-    [fatal_cycle] fn is_sanitizer_runtime: IsSanitizerRuntime(CrateNum) -> bool,
-    [fatal_cycle] fn is_profiler_runtime: IsProfilerRuntime(CrateNum) -> bool,
-    [fatal_cycle] fn panic_strategy: GetPanicStrategy(CrateNum) -> PanicStrategy,
-    [fatal_cycle] fn is_no_builtins: IsNoBuiltins(CrateNum) -> bool,
-
-    [] fn extern_crate: ExternCrate(DefId) -> Lrc<Option<ExternCrate>>,
-
-    [] fn specializes: specializes_node((DefId, DefId)) -> bool,
-    [] fn in_scope_traits_map: InScopeTraits(DefIndex)
-        -> Option<Lrc<FxHashMap<ItemLocalId, Lrc<StableVec<TraitCandidate>>>>>,
-    [] fn module_exports: ModuleExports(DefId) -> Option<Lrc<Vec<Export>>>,
-    [] fn lint_levels: lint_levels_node(CrateNum) -> Lrc<lint::LintLevelMap>,
-
-    [] fn impl_defaultness: ImplDefaultness(DefId) -> hir::Defaultness,
-
-    [] fn check_item_well_formed: CheckItemWellFormed(DefId) -> (),
-    [] fn check_trait_item_well_formed: CheckTraitItemWellFormed(DefId) -> (),
-    [] fn check_impl_item_well_formed: CheckImplItemWellFormed(DefId) -> (),
-
-    // The DefIds of all non-generic functions and statics in the given crate
-    // that can be reached from outside the crate.
-    //
-    // We expect this items to be available for being linked to.
-    //
-    // This query can also be called for LOCAL_CRATE. In this case it will
-    // compute which items will be reachable to other crates, taking into account
-    // the kind of crate that is currently compiled. Crates with only a
-    // C interface have fewer reachable things.
-    //
-    // Does not include external symbols that don't have a corresponding DefId,
-    // like the compiler-generated `main` function and so on.
-    [] fn reachable_non_generics: ReachableNonGenerics(CrateNum)
-        -> Lrc<DefIdMap<SymbolExportLevel>>,
-    [] fn is_reachable_non_generic: IsReachableNonGeneric(DefId) -> bool,
-    [] fn is_unreachable_local_definition: IsUnreachableLocalDefinition(DefId) -> bool,
-
-    [] fn upstream_monomorphizations: UpstreamMonomorphizations(CrateNum)
-        -> Lrc<DefIdMap<Lrc<FxHashMap<&'tcx Substs<'tcx>, CrateNum>>>>,
-    [] fn upstream_monomorphizations_for: UpstreamMonomorphizationsFor(DefId)
-        -> Option<Lrc<FxHashMap<&'tcx Substs<'tcx>, CrateNum>>>,
-
-    [] fn native_libraries: NativeLibraries(CrateNum) -> Lrc<Vec<NativeLibrary>>,
-
-    [] fn foreign_modules: ForeignModules(CrateNum) -> Lrc<Vec<ForeignModule>>,
-
-    [] fn plugin_registrar_fn: PluginRegistrarFn(CrateNum) -> Option<DefId>,
-    [] fn derive_registrar_fn: DeriveRegistrarFn(CrateNum) -> Option<DefId>,
-    [] fn crate_disambiguator: CrateDisambiguator(CrateNum) -> CrateDisambiguator,
-    [] fn crate_hash: CrateHash(CrateNum) -> Svh,
-    [] fn original_crate_name: OriginalCrateName(CrateNum) -> Symbol,
-    [] fn extra_filename: ExtraFileName(CrateNum) -> String,
-
-    [] fn implementations_of_trait: implementations_of_trait_node((CrateNum, DefId))
-        -> Lrc<Vec<DefId>>,
-    [] fn all_trait_implementations: AllTraitImplementations(CrateNum)
-        -> Lrc<Vec<DefId>>,
-
-    [] fn dllimport_foreign_items: DllimportForeignItems(CrateNum)
-        -> Lrc<FxHashSet<DefId>>,
-    [] fn is_dllimport_foreign_item: IsDllimportForeignItem(DefId) -> bool,
-    [] fn is_statically_included_foreign_item: IsStaticallyIncludedForeignItem(DefId) -> bool,
-    [] fn native_library_kind: NativeLibraryKind(DefId)
-        -> Option<NativeLibraryKind>,
-    [] fn link_args: link_args_node(CrateNum) -> Lrc<Vec<String>>,
-
-    // Lifetime resolution. See `middle::resolve_lifetimes`.
-    [] fn resolve_lifetimes: ResolveLifetimes(CrateNum) -> Lrc<ResolveLifetimes>,
-    [] fn named_region_map: NamedRegion(DefIndex) ->
-        Option<Lrc<FxHashMap<ItemLocalId, Region>>>,
-    [] fn is_late_bound_map: IsLateBound(DefIndex) ->
-        Option<Lrc<FxHashSet<ItemLocalId>>>,
-    [] fn object_lifetime_defaults_map: ObjectLifetimeDefaults(DefIndex)
-        -> Option<Lrc<FxHashMap<ItemLocalId, Lrc<Vec<ObjectLifetimeDefault>>>>>,
-
-    [] fn visibility: Visibility(DefId) -> ty::Visibility,
-    [] fn dep_kind: DepKind(CrateNum) -> DepKind,
-    [] fn crate_name: CrateName(CrateNum) -> Symbol,
-    [] fn item_children: ItemChildren(DefId) -> Lrc<Vec<Export>>,
-    [] fn extern_mod_stmt_cnum: ExternModStmtCnum(DefId) -> Option<CrateNum>,
-
-    [] fn get_lang_items: get_lang_items_node(CrateNum) -> Lrc<LanguageItems>,
-    [] fn defined_lang_items: DefinedLangItems(CrateNum) -> Lrc<Vec<(DefId, usize)>>,
-    [] fn missing_lang_items: MissingLangItems(CrateNum) -> Lrc<Vec<LangItem>>,
-    [] fn visible_parent_map: visible_parent_map_node(CrateNum)
-        -> Lrc<DefIdMap<DefId>>,
-    [] fn missing_extern_crate_item: MissingExternCrateItem(CrateNum) -> bool,
-    [] fn used_crate_source: UsedCrateSource(CrateNum) -> Lrc<CrateSource>,
-    [] fn postorder_cnums: postorder_cnums_node(CrateNum) -> Lrc<Vec<CrateNum>>,
-
-    [] fn freevars: Freevars(DefId) -> Option<Lrc<Vec<hir::Freevar>>>,
-    [] fn maybe_unused_trait_import: MaybeUnusedTraitImport(DefId) -> bool,
-    [] fn maybe_unused_extern_crates: maybe_unused_extern_crates_node(CrateNum)
-        -> Lrc<Vec<(DefId, Span)>>,
-
-    [] fn stability_index: stability_index_node(CrateNum) -> Lrc<stability::Index<'tcx>>,
-    [] fn all_crate_nums: all_crate_nums_node(CrateNum) -> Lrc<Vec<CrateNum>>,
-
-    /// A vector of every trait accessible in the whole crate
-    /// (i.e. including those from subcrates). This is used only for
-    /// error reporting.
-    [] fn all_traits: all_traits_node(CrateNum) -> Lrc<Vec<DefId>>,
-
-    [] fn exported_symbols: ExportedSymbols(CrateNum)
-        -> Arc<Vec<(ExportedSymbol<'tcx>, SymbolExportLevel)>>,
-    [] fn collect_and_partition_mono_items:
-        collect_and_partition_mono_items_node(CrateNum)
-        -> (Arc<DefIdSet>, Arc<Vec<Arc<CodegenUnit<'tcx>>>>),
-    [] fn is_codegened_item: IsCodegenedItem(DefId) -> bool,
-    [] fn codegen_unit: CodegenUnit(InternedString) -> Arc<CodegenUnit<'tcx>>,
-    [] fn compile_codegen_unit: CompileCodegenUnit(InternedString) -> Stats,
-    [] fn output_filenames: output_filenames_node(CrateNum)
-        -> Arc<OutputFilenames>,
-
-    // Erases regions from `ty` to yield a new type.
-    // Normally you would just use `tcx.erase_regions(&value)`,
-    // however, which uses this query as a kind of cache.
-    [] fn erase_regions_ty: erase_regions_ty(Ty<'tcx>) -> Ty<'tcx>,
-
-    /// Do not call this query directly: invoke `normalize` instead.
-    [] fn normalize_projection_ty: NormalizeProjectionTy(
-        CanonicalProjectionGoal<'tcx>
-    ) -> Result<
-        Lrc<Canonical<'tcx, canonical::QueryResult<'tcx, NormalizationResult<'tcx>>>>,
-        NoSolution,
-    >,
-
-    /// Do not call this query directly: invoke `normalize_erasing_regions` instead.
-    [] fn normalize_ty_after_erasing_regions: NormalizeTyAfterErasingRegions(
-        ParamEnvAnd<'tcx, Ty<'tcx>>
-    ) -> Ty<'tcx>,
-
-    /// Do not call this query directly: invoke `infcx.at().dropck_outlives()` instead.
-    [] fn dropck_outlives: DropckOutlives(
-        CanonicalTyGoal<'tcx>
-    ) -> Result<
-        Lrc<Canonical<'tcx, canonical::QueryResult<'tcx, DropckOutlivesResult<'tcx>>>>,
-        NoSolution,
-    >,
-
-    /// Do not call this query directly: invoke `infcx.predicate_may_hold()` or
-    /// `infcx.predicate_must_hold()` instead.
-    [] fn evaluate_obligation: EvaluateObligation(
-        CanonicalPredicateGoal<'tcx>
-    ) -> Result<traits::EvaluationResult, traits::OverflowError>,
-
-    [] fn substitute_normalize_and_test_predicates:
-        substitute_normalize_and_test_predicates_node((DefId, &'tcx Substs<'tcx>)) -> bool,
-
-    [] fn target_features_whitelist:
-        target_features_whitelist_node(CrateNum) -> Lrc<FxHashMap<String, Option<String>>>,
-
-    // Get an estimate of the size of an InstanceDef based on its MIR for CGU partitioning.
-    [] fn instance_def_size_estimate: instance_def_size_estimate_dep_node(ty::InstanceDef<'tcx>)
-        -> usize,
-
-    [] fn features_query: features_node(CrateNum) -> Lrc<feature_gate::Features>,
-
-    [] fn program_clauses_for: ProgramClausesFor(DefId) -> Clauses<'tcx>,
-
-    [] fn program_clauses_for_env: ProgramClausesForEnv(
-        ty::ParamEnv<'tcx>
-    ) -> Clauses<'tcx>,
-
-    [] fn wasm_custom_sections: WasmCustomSections(CrateNum) -> Lrc<Vec<DefId>>,
-    [] fn wasm_import_module_map: WasmImportModuleMap(CrateNum)
-        -> Lrc<FxHashMap<DefId, String>>,
-}
-
-//////////////////////////////////////////////////////////////////////
-// These functions are little shims used to find the dep-node for a
-// given query when there is not a *direct* mapping:
-
-
-fn features_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
-    DepConstructor::Features
-}
-
-fn codegen_fn_attrs<'tcx>(id: DefId) -> DepConstructor<'tcx> {
-    DepConstructor::CodegenFnAttrs { 0: id }
-}
-
-fn erase_regions_ty<'tcx>(ty: Ty<'tcx>) -> DepConstructor<'tcx> {
-    DepConstructor::EraseRegionsTy { ty }
-}
-
-fn const_value_to_allocation<'tcx>(
-    (val, ty): (ConstValue<'tcx>, Ty<'tcx>)
-) -> DepConstructor<'tcx> {
-    DepConstructor::ConstValueToAllocation { val, ty }
-}
-
-fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> {
-    DepConstructor::TypeParamPredicates {
-        item_id,
-        param_id
-    }
-}
-
-fn fulfill_obligation_dep_node<'tcx>((param_env, trait_ref):
-    (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)) -> DepConstructor<'tcx> {
-    DepConstructor::FulfillObligation {
-        param_env,
-        trait_ref
-    }
-}
-
-fn crate_inherent_impls_dep_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
-    DepConstructor::Coherence
-}
-
-fn inherent_impls_overlap_check_dep_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
-    DepConstructor::CoherenceInherentImplOverlapCheck
-}
-
-fn reachability_dep_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
-    DepConstructor::Reachability
-}
-
-fn mir_shim_dep_node<'tcx>(instance_def: ty::InstanceDef<'tcx>) -> DepConstructor<'tcx> {
-    DepConstructor::MirShim {
-        instance_def
-    }
-}
-
-fn symbol_name_dep_node<'tcx>(instance: ty::Instance<'tcx>) -> DepConstructor<'tcx> {
-    DepConstructor::InstanceSymbolName { instance }
-}
-
-fn typeck_item_bodies_dep_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
-    DepConstructor::TypeckBodiesKrate
-}
-
-fn const_eval_dep_node<'tcx>(param_env: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
-                             -> DepConstructor<'tcx> {
-    DepConstructor::ConstEval { param_env }
-}
-
-fn mir_keys<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
-    DepConstructor::MirKeys
-}
-
-fn crate_variances<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
-    DepConstructor::CrateVariances
-}
-
-fn is_copy_dep_node<'tcx>(param_env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepConstructor<'tcx> {
-    DepConstructor::IsCopy { param_env }
-}
-
-fn is_sized_dep_node<'tcx>(param_env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepConstructor<'tcx> {
-    DepConstructor::IsSized { param_env }
-}
-
-fn is_freeze_dep_node<'tcx>(param_env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepConstructor<'tcx> {
-    DepConstructor::IsFreeze { param_env }
-}
-
-fn needs_drop_dep_node<'tcx>(param_env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepConstructor<'tcx> {
-    DepConstructor::NeedsDrop { param_env }
-}
-
-fn layout_dep_node<'tcx>(param_env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepConstructor<'tcx> {
-    DepConstructor::Layout { param_env }
-}
-
-fn lint_levels_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
-    DepConstructor::LintLevels
-}
-
-fn specializes_node<'tcx>((a, b): (DefId, DefId)) -> DepConstructor<'tcx> {
-    DepConstructor::Specializes { impl1: a, impl2: b }
-}
-
-fn implementations_of_trait_node<'tcx>((krate, trait_id): (CrateNum, DefId))
-    -> DepConstructor<'tcx>
-{
-    DepConstructor::ImplementationsOfTrait { krate, trait_id }
-}
-
-fn link_args_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
-    DepConstructor::LinkArgs
-}
-
-fn get_lang_items_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
-    DepConstructor::GetLangItems
-}
-
-fn visible_parent_map_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
-    DepConstructor::VisibleParentMap
-}
-
-fn postorder_cnums_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
-    DepConstructor::PostorderCnums
-}
-
-fn maybe_unused_extern_crates_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
-    DepConstructor::MaybeUnusedExternCrates
-}
-
-fn stability_index_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
-    DepConstructor::StabilityIndex
-}
-
-fn all_crate_nums_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
-    DepConstructor::AllCrateNums
-}
-
-fn all_traits_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
-    DepConstructor::AllTraits
-}
-
-fn collect_and_partition_mono_items_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
-    DepConstructor::CollectAndPartitionMonoItems
-}
-
-fn output_filenames_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
-    DepConstructor::OutputFilenames
-}
-
-fn vtable_methods_node<'tcx>(trait_ref: ty::PolyTraitRef<'tcx>) -> DepConstructor<'tcx> {
-    DepConstructor::VtableMethods{ trait_ref }
-}
-
-fn substitute_normalize_and_test_predicates_node<'tcx>(key: (DefId, &'tcx Substs<'tcx>))
-                                            -> DepConstructor<'tcx> {
-    DepConstructor::SubstituteNormalizeAndTestPredicates { key }
-}
-
-fn target_features_whitelist_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
-    DepConstructor::TargetFeaturesWhitelist
-}
-
-fn instance_def_size_estimate_dep_node<'tcx>(instance_def: ty::InstanceDef<'tcx>)
-                                              -> DepConstructor<'tcx> {
-    DepConstructor::InstanceDefSizeEstimate {
-        instance_def
-    }
-}
diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/maps/on_disk_cache.rs
deleted file mode 100644 (file)
index cd317ff..0000000
+++ /dev/null
@@ -1,1119 +0,0 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
-use errors::Diagnostic;
-use hir;
-use hir::def_id::{CrateNum, DefIndex, DefId, LocalDefId,
-                  RESERVED_FOR_INCR_COMP_CACHE, LOCAL_CRATE};
-use hir::map::definitions::DefPathHash;
-use ich::{CachingCodemapView, Fingerprint};
-use mir::{self, interpret};
-use mir::interpret::{AllocDecodingSession, AllocDecodingState};
-use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::sync::{Lrc, Lock, HashMapExt, Once};
-use rustc_data_structures::indexed_vec::{IndexVec, Idx};
-use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque,
-                      SpecializedDecoder, SpecializedEncoder,
-                      UseSpecializedDecodable, UseSpecializedEncodable};
-use session::{CrateDisambiguator, Session};
-use std::mem;
-use syntax::ast::NodeId;
-use syntax::codemap::{CodeMap, StableFilemapId};
-use syntax_pos::{BytePos, Span, DUMMY_SP, FileMap};
-use syntax_pos::hygiene::{Mark, SyntaxContext, ExpnInfo};
-use ty;
-use ty::codec::{self as ty_codec, TyDecoder, TyEncoder};
-use ty::context::TyCtxt;
-use util::common::time;
-
-const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE;
-
-const TAG_CLEAR_CROSS_CRATE_CLEAR: u8 = 0;
-const TAG_CLEAR_CROSS_CRATE_SET: u8 = 1;
-
-const TAG_NO_EXPANSION_INFO: u8 = 0;
-const TAG_EXPANSION_INFO_SHORTHAND: u8 = 1;
-const TAG_EXPANSION_INFO_INLINE: u8 = 2;
-
-const TAG_VALID_SPAN: u8 = 0;
-const TAG_INVALID_SPAN: u8 = 1;
-
-/// `OnDiskCache` provides an interface to incr. comp. data cached from the
-/// previous compilation session. This data will eventually include the results
-/// of a few selected queries (like `typeck_tables_of` and `mir_optimized`) and
-/// any diagnostics that have been emitted during a query.
-pub struct OnDiskCache<'sess> {
-
-    // The complete cache data in serialized form.
-    serialized_data: Vec<u8>,
-
-    // This field collects all Diagnostics emitted during the current
-    // compilation session.
-    current_diagnostics: Lock<FxHashMap<DepNodeIndex, Vec<Diagnostic>>>,
-
-    prev_cnums: Vec<(u32, String, CrateDisambiguator)>,
-    cnum_map: Once<IndexVec<CrateNum, Option<CrateNum>>>,
-
-    codemap: &'sess CodeMap,
-    file_index_to_stable_id: FxHashMap<FileMapIndex, StableFilemapId>,
-
-    // These two fields caches that are populated lazily during decoding.
-    file_index_to_file: Lock<FxHashMap<FileMapIndex, Lrc<FileMap>>>,
-    synthetic_expansion_infos: Lock<FxHashMap<AbsoluteBytePos, SyntaxContext>>,
-
-    // A map from dep-node to the position of the cached query result in
-    // `serialized_data`.
-    query_result_index: FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>,
-
-    // A map from dep-node to the position of any associated diagnostics in
-    // `serialized_data`.
-    prev_diagnostics_index: FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>,
-
-    alloc_decoding_state: AllocDecodingState,
-}
-
-// This type is used only for (de-)serialization.
-#[derive(RustcEncodable, RustcDecodable)]
-struct Footer {
-    file_index_to_stable_id: FxHashMap<FileMapIndex, StableFilemapId>,
-    prev_cnums: Vec<(u32, String, CrateDisambiguator)>,
-    query_result_index: EncodedQueryResultIndex,
-    diagnostics_index: EncodedQueryResultIndex,
-    // the location of all allocations
-    interpret_alloc_index: Vec<u32>,
-}
-
-type EncodedQueryResultIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>;
-type EncodedDiagnosticsIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>;
-type EncodedDiagnostics = Vec<Diagnostic>;
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
-struct FileMapIndex(u32);
-
-#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, RustcEncodable, RustcDecodable)]
-struct AbsoluteBytePos(u32);
-
-impl AbsoluteBytePos {
-    fn new(pos: usize) -> AbsoluteBytePos {
-        debug_assert!(pos <= ::std::u32::MAX as usize);
-        AbsoluteBytePos(pos as u32)
-    }
-
-    fn to_usize(self) -> usize {
-        self.0 as usize
-    }
-}
-
-impl<'sess> OnDiskCache<'sess> {
-    /// Create a new OnDiskCache instance from the serialized data in `data`.
-    pub fn new(sess: &'sess Session, data: Vec<u8>, start_pos: usize) -> OnDiskCache<'sess> {
-        debug_assert!(sess.opts.incremental.is_some());
-
-        // Wrapping in a scope so we can borrow `data`
-        let footer: Footer = {
-            let mut decoder = opaque::Decoder::new(&data[..], start_pos);
-
-            // Decode the *position* of the footer which can be found in the
-            // last 8 bytes of the file.
-            decoder.set_position(data.len() - IntEncodedWithFixedSize::ENCODED_SIZE);
-            let query_result_index_pos = IntEncodedWithFixedSize::decode(&mut decoder)
-                .expect("Error while trying to decode query result index position.")
-                .0 as usize;
-
-            // Decoder the file footer which contains all the lookup tables, etc.
-            decoder.set_position(query_result_index_pos);
-            decode_tagged(&mut decoder, TAG_FILE_FOOTER)
-                .expect("Error while trying to decode query result index position.")
-        };
-
-        OnDiskCache {
-            serialized_data: data,
-            file_index_to_stable_id: footer.file_index_to_stable_id,
-            file_index_to_file: Lock::new(FxHashMap()),
-            prev_cnums: footer.prev_cnums,
-            cnum_map: Once::new(),
-            codemap: sess.codemap(),
-            current_diagnostics: Lock::new(FxHashMap()),
-            query_result_index: footer.query_result_index.into_iter().collect(),
-            prev_diagnostics_index: footer.diagnostics_index.into_iter().collect(),
-            synthetic_expansion_infos: Lock::new(FxHashMap()),
-            alloc_decoding_state: AllocDecodingState::new(footer.interpret_alloc_index),
-        }
-    }
-
-    pub fn new_empty(codemap: &'sess CodeMap) -> OnDiskCache<'sess> {
-        OnDiskCache {
-            serialized_data: Vec::new(),
-            file_index_to_stable_id: FxHashMap(),
-            file_index_to_file: Lock::new(FxHashMap()),
-            prev_cnums: vec![],
-            cnum_map: Once::new(),
-            codemap,
-            current_diagnostics: Lock::new(FxHashMap()),
-            query_result_index: FxHashMap(),
-            prev_diagnostics_index: FxHashMap(),
-            synthetic_expansion_infos: Lock::new(FxHashMap()),
-            alloc_decoding_state: AllocDecodingState::new(Vec::new()),
-        }
-    }
-
-    pub fn serialize<'a, 'tcx, E>(&self,
-                                  tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                  encoder: &mut E)
-                                  -> Result<(), E::Error>
-        where E: ty_codec::TyEncoder
-     {
-        // Serializing the DepGraph should not modify it:
-        tcx.dep_graph.with_ignore(|| {
-            // Allocate FileMapIndices
-            let (file_to_file_index, file_index_to_stable_id) = {
-                let mut file_to_file_index = FxHashMap();
-                let mut file_index_to_stable_id = FxHashMap();
-
-                for (index, file) in tcx.sess.codemap().files().iter().enumerate() {
-                    let index = FileMapIndex(index as u32);
-                    let file_ptr: *const FileMap = &**file as *const _;
-                    file_to_file_index.insert(file_ptr, index);
-                    file_index_to_stable_id.insert(index, StableFilemapId::new(&file));
-                }
-
-                (file_to_file_index, file_index_to_stable_id)
-            };
-
-            let mut encoder = CacheEncoder {
-                tcx,
-                encoder,
-                type_shorthands: FxHashMap(),
-                predicate_shorthands: FxHashMap(),
-                expn_info_shorthands: FxHashMap(),
-                interpret_allocs: FxHashMap(),
-                interpret_allocs_inverse: Vec::new(),
-                codemap: CachingCodemapView::new(tcx.sess.codemap()),
-                file_to_file_index,
-            };
-
-            // Load everything into memory so we can write it out to the on-disk
-            // cache. The vast majority of cacheable query results should already
-            // be in memory, so this should be a cheap operation.
-            tcx.dep_graph.exec_cache_promotions(tcx);
-
-            // Encode query results
-            let mut query_result_index = EncodedQueryResultIndex::new();
-
-            time(tcx.sess, "encode query results", || {
-                use ty::maps::queries::*;
-                let enc = &mut encoder;
-                let qri = &mut query_result_index;
-
-                encode_query_results::<type_of, _>(tcx, enc, qri)?;
-                encode_query_results::<generics_of, _>(tcx, enc, qri)?;
-                encode_query_results::<predicates_of, _>(tcx, enc, qri)?;
-                encode_query_results::<used_trait_imports, _>(tcx, enc, qri)?;
-                encode_query_results::<typeck_tables_of, _>(tcx, enc, qri)?;
-                encode_query_results::<codegen_fulfill_obligation, _>(tcx, enc, qri)?;
-                encode_query_results::<optimized_mir, _>(tcx, enc, qri)?;
-                encode_query_results::<unsafety_check_result, _>(tcx, enc, qri)?;
-                encode_query_results::<borrowck, _>(tcx, enc, qri)?;
-                encode_query_results::<mir_borrowck, _>(tcx, enc, qri)?;
-                encode_query_results::<mir_const_qualif, _>(tcx, enc, qri)?;
-                encode_query_results::<def_symbol_name, _>(tcx, enc, qri)?;
-                encode_query_results::<const_is_rvalue_promotable_to_static, _>(tcx, enc, qri)?;
-                encode_query_results::<symbol_name, _>(tcx, enc, qri)?;
-                encode_query_results::<check_match, _>(tcx, enc, qri)?;
-                encode_query_results::<codegen_fn_attrs, _>(tcx, enc, qri)?;
-                encode_query_results::<specialization_graph_of, _>(tcx, enc, qri)?;
-
-                // const eval is special, it only encodes successfully evaluated constants
-                use ty::maps::QueryConfig;
-                let map = const_eval::query_map(tcx).borrow();
-                assert!(map.active.is_empty());
-                for (key, entry) in map.results.iter() {
-                    use ty::maps::config::QueryDescription;
-                    if const_eval::cache_on_disk(key.clone()) {
-                        if let Ok(ref value) = entry.value {
-                            let dep_node = SerializedDepNodeIndex::new(entry.index.index());
-
-                            // Record position of the cache entry
-                            qri.push((dep_node, AbsoluteBytePos::new(enc.position())));
-
-                            // Encode the type check tables with the SerializedDepNodeIndex
-                            // as tag.
-                            enc.encode_tagged(dep_node, value)?;
-                        }
-                    }
-                }
-
-                Ok(())
-            })?;
-
-            // Encode diagnostics
-            let diagnostics_index = {
-                let mut diagnostics_index = EncodedDiagnosticsIndex::new();
-
-                for (dep_node_index, diagnostics) in self.current_diagnostics
-                                                        .borrow()
-                                                        .iter() {
-                    let pos = AbsoluteBytePos::new(encoder.position());
-                    // Let's make sure we get the expected type here:
-                    let diagnostics: &EncodedDiagnostics = diagnostics;
-                    let dep_node_index =
-                        SerializedDepNodeIndex::new(dep_node_index.index());
-                    encoder.encode_tagged(dep_node_index, diagnostics)?;
-                    diagnostics_index.push((dep_node_index, pos));
-                }
-
-                diagnostics_index
-            };
-
-            let interpret_alloc_index = {
-                let mut interpret_alloc_index = Vec::new();
-                let mut n = 0;
-                loop {
-                    let new_n = encoder.interpret_allocs_inverse.len();
-                    // if we have found new ids, serialize those, too
-                    if n == new_n {
-                        // otherwise, abort
-                        break;
-                    }
-                    for idx in n..new_n {
-                        let id = encoder.interpret_allocs_inverse[idx];
-                        let pos = encoder.position() as u32;
-                        interpret_alloc_index.push(pos);
-                        interpret::specialized_encode_alloc_id(
-                            &mut encoder,
-                            tcx,
-                            id,
-                        )?;
-                    }
-                    n = new_n;
-                }
-                interpret_alloc_index
-            };
-
-            let sorted_cnums = sorted_cnums_including_local_crate(tcx);
-            let prev_cnums: Vec<_> = sorted_cnums.iter().map(|&cnum| {
-                let crate_name = tcx.original_crate_name(cnum).as_str().to_string();
-                let crate_disambiguator = tcx.crate_disambiguator(cnum);
-                (cnum.as_u32(), crate_name, crate_disambiguator)
-            }).collect();
-
-            // Encode the file footer
-            let footer_pos = encoder.position() as u64;
-            encoder.encode_tagged(TAG_FILE_FOOTER, &Footer {
-                file_index_to_stable_id,
-                prev_cnums,
-                query_result_index,
-                diagnostics_index,
-                interpret_alloc_index,
-            })?;
-
-            // Encode the position of the footer as the last 8 bytes of the
-            // file so we know where to look for it.
-            IntEncodedWithFixedSize(footer_pos).encode(encoder.encoder)?;
-
-            // DO NOT WRITE ANYTHING TO THE ENCODER AFTER THIS POINT! The address
-            // of the footer must be the last thing in the data stream.
-
-            return Ok(());
-
-            fn sorted_cnums_including_local_crate(tcx: TyCtxt) -> Vec<CrateNum> {
-                let mut cnums = vec![LOCAL_CRATE];
-                cnums.extend_from_slice(&tcx.crates()[..]);
-                cnums.sort_unstable();
-                // Just to be sure...
-                cnums.dedup();
-                cnums
-            }
-        })
-    }
-
-    /// Load a diagnostic emitted during the previous compilation session.
-    pub fn load_diagnostics<'a, 'tcx>(&self,
-                                      tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                      dep_node_index: SerializedDepNodeIndex)
-                                      -> Vec<Diagnostic> {
-        let diagnostics: Option<EncodedDiagnostics> = self.load_indexed(
-            tcx,
-            dep_node_index,
-            &self.prev_diagnostics_index,
-            "diagnostics");
-
-        diagnostics.unwrap_or(Vec::new())
-    }
-
-    /// Store a diagnostic emitted during the current compilation session.
-    /// Anything stored like this will be available via `load_diagnostics` in
-    /// the next compilation session.
-    pub fn store_diagnostics(&self,
-                             dep_node_index: DepNodeIndex,
-                             diagnostics: Vec<Diagnostic>) {
-        let mut current_diagnostics = self.current_diagnostics.borrow_mut();
-        let prev = current_diagnostics.insert(dep_node_index, diagnostics);
-        debug_assert!(prev.is_none());
-    }
-
-    /// Returns the cached query result if there is something in the cache for
-    /// the given SerializedDepNodeIndex. Otherwise returns None.
-    pub fn try_load_query_result<'tcx, T>(&self,
-                                          tcx: TyCtxt<'_, 'tcx, 'tcx>,
-                                          dep_node_index: SerializedDepNodeIndex)
-                                          -> Option<T>
-        where T: Decodable
-    {
-        self.load_indexed(tcx,
-                          dep_node_index,
-                          &self.query_result_index,
-                          "query result")
-    }
-
-    /// Store a diagnostic emitted during computation of an anonymous query.
-    /// Since many anonymous queries can share the same `DepNode`, we aggregate
-    /// them -- as opposed to regular queries where we assume that there is a
-    /// 1:1 relationship between query-key and `DepNode`.
-    pub fn store_diagnostics_for_anon_node(&self,
-                                           dep_node_index: DepNodeIndex,
-                                           mut diagnostics: Vec<Diagnostic>) {
-        let mut current_diagnostics = self.current_diagnostics.borrow_mut();
-
-        let x = current_diagnostics.entry(dep_node_index).or_insert_with(|| {
-            mem::replace(&mut diagnostics, Vec::new())
-        });
-
-        x.extend(diagnostics.into_iter());
-    }
-
-    fn load_indexed<'tcx, T>(&self,
-                             tcx: TyCtxt<'_, 'tcx, 'tcx>,
-                             dep_node_index: SerializedDepNodeIndex,
-                             index: &FxHashMap<SerializedDepNodeIndex,
-                                               AbsoluteBytePos>,
-                             debug_tag: &'static str)
-                             -> Option<T>
-        where T: Decodable
-    {
-        let pos = if let Some(&pos) = index.get(&dep_node_index) {
-            pos
-        } else {
-            return None
-        };
-
-        // Initialize the cnum_map using the value from the thread which finishes the closure first
-        self.cnum_map.init_nonlocking_same(|| {
-            Self::compute_cnum_map(tcx, &self.prev_cnums[..])
-        });
-
-        let mut decoder = CacheDecoder {
-            tcx,
-            opaque: opaque::Decoder::new(&self.serialized_data[..], pos.to_usize()),
-            codemap: self.codemap,
-            cnum_map: self.cnum_map.get(),
-            file_index_to_file: &self.file_index_to_file,
-            file_index_to_stable_id: &self.file_index_to_stable_id,
-            synthetic_expansion_infos: &self.synthetic_expansion_infos,
-            alloc_decoding_session: self.alloc_decoding_state.new_decoding_session(),
-        };
-
-        match decode_tagged(&mut decoder, dep_node_index) {
-            Ok(value) => {
-                Some(value)
-            }
-            Err(e) => {
-                bug!("Could not decode cached {}: {}", debug_tag, e)
-            }
-        }
-    }
-
-    // This function builds mapping from previous-session-CrateNum to
-    // current-session-CrateNum. There might be CrateNums from the previous
-    // Session that don't occur in the current one. For these, the mapping
-    // maps to None.
-    fn compute_cnum_map(tcx: TyCtxt,
-                        prev_cnums: &[(u32, String, CrateDisambiguator)])
-                        -> IndexVec<CrateNum, Option<CrateNum>>
-    {
-        tcx.dep_graph.with_ignore(|| {
-            let current_cnums = tcx.all_crate_nums(LOCAL_CRATE).iter().map(|&cnum| {
-                let crate_name = tcx.original_crate_name(cnum)
-                                    .as_str()
-                                    .to_string();
-                let crate_disambiguator = tcx.crate_disambiguator(cnum);
-                ((crate_name, crate_disambiguator), cnum)
-            }).collect::<FxHashMap<_,_>>();
-
-            let map_size = prev_cnums.iter()
-                                    .map(|&(cnum, ..)| cnum)
-                                    .max()
-                                    .unwrap_or(0) + 1;
-            let mut map = IndexVec::new();
-            map.resize(map_size as usize, None);
-
-            for &(prev_cnum, ref crate_name, crate_disambiguator) in prev_cnums {
-                let key = (crate_name.clone(), crate_disambiguator);
-                map[CrateNum::from_u32(prev_cnum)] = current_cnums.get(&key).cloned();
-            }
-
-            map[LOCAL_CRATE] = Some(LOCAL_CRATE);
-            map
-        })
-    }
-}
-
-
-//- DECODING -------------------------------------------------------------------
-
-/// A decoder that can read the incr. comp. cache. It is similar to the one
-/// we use for crate metadata decoding in that it can rebase spans and
-/// eventually will also handle things that contain `Ty` instances.
-struct CacheDecoder<'a, 'tcx: 'a, 'x> {
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    opaque: opaque::Decoder<'x>,
-    codemap: &'x CodeMap,
-    cnum_map: &'x IndexVec<CrateNum, Option<CrateNum>>,
-    synthetic_expansion_infos: &'x Lock<FxHashMap<AbsoluteBytePos, SyntaxContext>>,
-    file_index_to_file: &'x Lock<FxHashMap<FileMapIndex, Lrc<FileMap>>>,
-    file_index_to_stable_id: &'x FxHashMap<FileMapIndex, StableFilemapId>,
-    alloc_decoding_session: AllocDecodingSession<'x>,
-}
-
-impl<'a, 'tcx, 'x> CacheDecoder<'a, 'tcx, 'x> {
-    fn file_index_to_file(&self, index: FileMapIndex) -> Lrc<FileMap> {
-        let CacheDecoder {
-            ref file_index_to_file,
-            ref file_index_to_stable_id,
-            ref codemap,
-            ..
-        } = *self;
-
-        file_index_to_file.borrow_mut().entry(index).or_insert_with(|| {
-            let stable_id = file_index_to_stable_id[&index];
-            codemap.filemap_by_stable_id(stable_id)
-                   .expect("Failed to lookup FileMap in new context.")
-        }).clone()
-    }
-}
-
-trait DecoderWithPosition: Decoder {
-    fn position(&self) -> usize;
-}
-
-impl<'enc> DecoderWithPosition for opaque::Decoder<'enc> {
-    fn position(&self) -> usize {
-        self.position()
-    }
-}
-
-impl<'a, 'tcx, 'x> DecoderWithPosition for CacheDecoder<'a, 'tcx, 'x> {
-    fn position(&self) -> usize {
-        self.opaque.position()
-    }
-}
-
-// Decode something that was encoded with encode_tagged() and verify that the
-// tag matches and the correct amount of bytes was read.
-fn decode_tagged<'a, 'tcx, D, T, V>(decoder: &mut D,
-                                    expected_tag: T)
-                                    -> Result<V, D::Error>
-    where T: Decodable + Eq + ::std::fmt::Debug,
-          V: Decodable,
-          D: DecoderWithPosition,
-          'tcx: 'a,
-{
-    let start_pos = decoder.position();
-
-    let actual_tag = T::decode(decoder)?;
-    assert_eq!(actual_tag, expected_tag);
-    let value = V::decode(decoder)?;
-    let end_pos = decoder.position();
-
-    let expected_len: u64 = Decodable::decode(decoder)?;
-    assert_eq!((end_pos - start_pos) as u64, expected_len);
-
-    Ok(value)
-}
-
-
-impl<'a, 'tcx: 'a, 'x> ty_codec::TyDecoder<'a, 'tcx> for CacheDecoder<'a, 'tcx, 'x> {
-
-    #[inline]
-    fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> {
-        self.tcx
-    }
-
-    #[inline]
-    fn position(&self) -> usize {
-        self.opaque.position()
-    }
-
-    #[inline]
-    fn peek_byte(&self) -> u8 {
-        self.opaque.data[self.opaque.position()]
-    }
-
-    fn cached_ty_for_shorthand<F>(&mut self,
-                                  shorthand: usize,
-                                  or_insert_with: F)
-                                  -> Result<ty::Ty<'tcx>, Self::Error>
-        where F: FnOnce(&mut Self) -> Result<ty::Ty<'tcx>, Self::Error>
-    {
-        let tcx = self.tcx();
-
-        let cache_key = ty::CReaderCacheKey {
-            cnum: RESERVED_FOR_INCR_COMP_CACHE,
-            pos: shorthand,
-        };
-
-        if let Some(&ty) = tcx.rcache.borrow().get(&cache_key) {
-            return Ok(ty);
-        }
-
-        let ty = or_insert_with(self)?;
-        // This may overwrite the entry, but it should overwrite with the same value
-        tcx.rcache.borrow_mut().insert_same(cache_key, ty);
-        Ok(ty)
-    }
-
-    fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
-        where F: FnOnce(&mut Self) -> R
-    {
-        debug_assert!(pos < self.opaque.data.len());
-
-        let new_opaque = opaque::Decoder::new(self.opaque.data, pos);
-        let old_opaque = mem::replace(&mut self.opaque, new_opaque);
-        let r = f(self);
-        self.opaque = old_opaque;
-        r
-    }
-
-    fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum {
-        self.cnum_map[cnum].unwrap_or_else(|| {
-            bug!("Could not find new CrateNum for {:?}", cnum)
-        })
-    }
-}
-
-implement_ty_decoder!( CacheDecoder<'a, 'tcx, 'x> );
-
-impl<'a, 'tcx, 'x> SpecializedDecoder<interpret::AllocId> for CacheDecoder<'a, 'tcx, 'x> {
-    fn specialized_decode(&mut self) -> Result<interpret::AllocId, Self::Error> {
-        let alloc_decoding_session = self.alloc_decoding_session;
-        alloc_decoding_session.decode_alloc_id(self)
-    }
-}
-impl<'a, 'tcx, 'x> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx, 'x> {
-    fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
-        let tag: u8 = Decodable::decode(self)?;
-
-        if tag == TAG_INVALID_SPAN {
-            return Ok(DUMMY_SP);
-        } else {
-            debug_assert_eq!(tag, TAG_VALID_SPAN);
-        }
-
-        let file_lo_index = FileMapIndex::decode(self)?;
-        let line_lo = usize::decode(self)?;
-        let col_lo = BytePos::decode(self)?;
-        let len = BytePos::decode(self)?;
-
-        let file_lo = self.file_index_to_file(file_lo_index);
-        let lo = file_lo.lines.borrow()[line_lo - 1] + col_lo;
-        let hi = lo + len;
-
-        let expn_info_tag = u8::decode(self)?;
-
-        let ctxt = match expn_info_tag {
-            TAG_NO_EXPANSION_INFO => {
-                SyntaxContext::empty()
-            }
-            TAG_EXPANSION_INFO_INLINE => {
-                let pos = AbsoluteBytePos::new(self.opaque.position());
-                let expn_info: ExpnInfo = Decodable::decode(self)?;
-                let ctxt = SyntaxContext::allocate_directly(expn_info);
-                self.synthetic_expansion_infos.borrow_mut().insert(pos, ctxt);
-                ctxt
-            }
-            TAG_EXPANSION_INFO_SHORTHAND => {
-                let pos = AbsoluteBytePos::decode(self)?;
-                let cached_ctxt = self.synthetic_expansion_infos
-                                      .borrow()
-                                      .get(&pos)
-                                      .cloned();
-
-                if let Some(ctxt) = cached_ctxt {
-                    ctxt
-                } else {
-                    let expn_info = self.with_position(pos.to_usize(), |this| {
-                         ExpnInfo::decode(this)
-                    })?;
-                    let ctxt = SyntaxContext::allocate_directly(expn_info);
-                    self.synthetic_expansion_infos.borrow_mut().insert(pos, ctxt);
-                    ctxt
-                }
-            }
-            _ => {
-                unreachable!()
-            }
-        };
-
-        Ok(Span::new(lo, hi, ctxt))
-    }
-}
-
-// This impl makes sure that we get a runtime error when we try decode a
-// DefIndex that is not contained in a DefId. Such a case would be problematic
-// because we would not know how to transform the DefIndex to the current
-// context.
-impl<'a, 'tcx, 'x> SpecializedDecoder<DefIndex> for CacheDecoder<'a, 'tcx, 'x> {
-    fn specialized_decode(&mut self) -> Result<DefIndex, Self::Error> {
-        bug!("Trying to decode DefIndex outside the context of a DefId")
-    }
-}
-
-// Both the CrateNum and the DefIndex of a DefId can change in between two
-// compilation sessions. We use the DefPathHash, which is stable across
-// sessions, to map the old DefId to the new one.
-impl<'a, 'tcx, 'x> SpecializedDecoder<DefId> for CacheDecoder<'a, 'tcx, 'x> {
-    #[inline]
-    fn specialized_decode(&mut self) -> Result<DefId, Self::Error> {
-        // Load the DefPathHash which is was we encoded the DefId as.
-        let def_path_hash = DefPathHash::decode(self)?;
-
-        // Using the DefPathHash, we can lookup the new DefId
-        Ok(self.tcx().def_path_hash_to_def_id.as_ref().unwrap()[&def_path_hash])
-    }
-}
-
-impl<'a, 'tcx, 'x> SpecializedDecoder<LocalDefId> for CacheDecoder<'a, 'tcx, 'x> {
-    #[inline]
-    fn specialized_decode(&mut self) -> Result<LocalDefId, Self::Error> {
-        Ok(LocalDefId::from_def_id(DefId::decode(self)?))
-    }
-}
-
-impl<'a, 'tcx, 'x> SpecializedDecoder<hir::HirId> for CacheDecoder<'a, 'tcx, 'x> {
-    fn specialized_decode(&mut self) -> Result<hir::HirId, Self::Error> {
-        // Load the DefPathHash which is was we encoded the DefIndex as.
-        let def_path_hash = DefPathHash::decode(self)?;
-
-        // Use the DefPathHash to map to the current DefId.
-        let def_id = self.tcx()
-                         .def_path_hash_to_def_id
-                         .as_ref()
-                         .unwrap()[&def_path_hash];
-
-        debug_assert!(def_id.is_local());
-
-        // The ItemLocalId needs no remapping.
-        let local_id = hir::ItemLocalId::decode(self)?;
-
-        // Reconstruct the HirId and look up the corresponding NodeId in the
-        // context of the current session.
-        Ok(hir::HirId {
-            owner: def_id.index,
-            local_id
-        })
-    }
-}
-
-// NodeIds are not stable across compilation sessions, so we store them in their
-// HirId representation. This allows use to map them to the current NodeId.
-impl<'a, 'tcx, 'x> SpecializedDecoder<NodeId> for CacheDecoder<'a, 'tcx, 'x> {
-    #[inline]
-    fn specialized_decode(&mut self) -> Result<NodeId, Self::Error> {
-        let hir_id = hir::HirId::decode(self)?;
-        Ok(self.tcx().hir.hir_to_node_id(hir_id))
-    }
-}
-
-impl<'a, 'tcx, 'x> SpecializedDecoder<Fingerprint> for CacheDecoder<'a, 'tcx, 'x> {
-    fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
-        Fingerprint::decode_opaque(&mut self.opaque)
-    }
-}
-
-impl<'a, 'tcx, 'x, T: Decodable> SpecializedDecoder<mir::ClearCrossCrate<T>>
-for CacheDecoder<'a, 'tcx, 'x> {
-    #[inline]
-    fn specialized_decode(&mut self) -> Result<mir::ClearCrossCrate<T>, Self::Error> {
-        let discr = u8::decode(self)?;
-
-        match discr {
-            TAG_CLEAR_CROSS_CRATE_CLEAR => Ok(mir::ClearCrossCrate::Clear),
-            TAG_CLEAR_CROSS_CRATE_SET => {
-                let val = T::decode(self)?;
-                Ok(mir::ClearCrossCrate::Set(val))
-            }
-            _ => {
-                unreachable!()
-            }
-        }
-    }
-}
-
-//- ENCODING -------------------------------------------------------------------
-
-struct CacheEncoder<'enc, 'a, 'tcx, E>
-    where E: 'enc + ty_codec::TyEncoder,
-          'tcx: 'a,
-{
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    encoder: &'enc mut E,
-    type_shorthands: FxHashMap<ty::Ty<'tcx>, usize>,
-    predicate_shorthands: FxHashMap<ty::Predicate<'tcx>, usize>,
-    expn_info_shorthands: FxHashMap<Mark, AbsoluteBytePos>,
-    interpret_allocs: FxHashMap<interpret::AllocId, usize>,
-    interpret_allocs_inverse: Vec<interpret::AllocId>,
-    codemap: CachingCodemapView<'tcx>,
-    file_to_file_index: FxHashMap<*const FileMap, FileMapIndex>,
-}
-
-impl<'enc, 'a, 'tcx, E> CacheEncoder<'enc, 'a, 'tcx, E>
-    where E: 'enc + ty_codec::TyEncoder
-{
-    fn filemap_index(&mut self, filemap: Lrc<FileMap>) -> FileMapIndex {
-        self.file_to_file_index[&(&*filemap as *const FileMap)]
-    }
-
-    /// Encode something with additional information that allows to do some
-    /// sanity checks when decoding the data again. This method will first
-    /// encode the specified tag, then the given value, then the number of
-    /// bytes taken up by tag and value. On decoding, we can then verify that
-    /// we get the expected tag and read the expected number of bytes.
-    fn encode_tagged<T: Encodable, V: Encodable>(&mut self,
-                                                 tag: T,
-                                                 value: &V)
-                                                 -> Result<(), E::Error>
-    {
-        use ty::codec::TyEncoder;
-        let start_pos = self.position();
-
-        tag.encode(self)?;
-        value.encode(self)?;
-
-        let end_pos = self.position();
-        ((end_pos - start_pos) as u64).encode(self)
-    }
-}
-
-impl<'enc, 'a, 'tcx, E> SpecializedEncoder<interpret::AllocId> for CacheEncoder<'enc, 'a, 'tcx, E>
-    where E: 'enc + ty_codec::TyEncoder
-{
-    fn specialized_encode(&mut self, alloc_id: &interpret::AllocId) -> Result<(), Self::Error> {
-        use std::collections::hash_map::Entry;
-        let index = match self.interpret_allocs.entry(*alloc_id) {
-            Entry::Occupied(e) => *e.get(),
-            Entry::Vacant(e) => {
-                let idx = self.interpret_allocs_inverse.len();
-                self.interpret_allocs_inverse.push(*alloc_id);
-                e.insert(idx);
-                idx
-            },
-        };
-
-        index.encode(self)
-    }
-}
-
-impl<'enc, 'a, 'tcx, E> SpecializedEncoder<Span> for CacheEncoder<'enc, 'a, 'tcx, E>
-    where E: 'enc + ty_codec::TyEncoder
-{
-    fn specialized_encode(&mut self, span: &Span) -> Result<(), Self::Error> {
-
-        if *span == DUMMY_SP {
-            return TAG_INVALID_SPAN.encode(self);
-        }
-
-        let span_data = span.data();
-
-        if span_data.hi < span_data.lo {
-            return TAG_INVALID_SPAN.encode(self);
-        }
-
-        let (file_lo, line_lo, col_lo) = match self.codemap
-                                                   .byte_pos_to_line_and_col(span_data.lo) {
-            Some(pos) => pos,
-            None => {
-                return TAG_INVALID_SPAN.encode(self);
-            }
-        };
-
-        if !file_lo.contains(span_data.hi) {
-            return TAG_INVALID_SPAN.encode(self);
-        }
-
-        let len = span_data.hi - span_data.lo;
-
-        let filemap_index = self.filemap_index(file_lo);
-
-        TAG_VALID_SPAN.encode(self)?;
-        filemap_index.encode(self)?;
-        line_lo.encode(self)?;
-        col_lo.encode(self)?;
-        len.encode(self)?;
-
-        if span_data.ctxt == SyntaxContext::empty() {
-            TAG_NO_EXPANSION_INFO.encode(self)
-        } else {
-            let mark = span_data.ctxt.outer();
-
-            if let Some(expn_info) = mark.expn_info() {
-                if let Some(pos) = self.expn_info_shorthands.get(&mark).cloned() {
-                    TAG_EXPANSION_INFO_SHORTHAND.encode(self)?;
-                    pos.encode(self)
-                } else {
-                    TAG_EXPANSION_INFO_INLINE.encode(self)?;
-                    let pos = AbsoluteBytePos::new(self.position());
-                    self.expn_info_shorthands.insert(mark, pos);
-                    expn_info.encode(self)
-                }
-            } else {
-                TAG_NO_EXPANSION_INFO.encode(self)
-            }
-        }
-    }
-}
-
-impl<'enc, 'a, 'tcx, E> ty_codec::TyEncoder for CacheEncoder<'enc, 'a, 'tcx, E>
-    where E: 'enc + ty_codec::TyEncoder
-{
-    #[inline]
-    fn position(&self) -> usize {
-        self.encoder.position()
-    }
-}
-
-impl<'enc, 'a, 'tcx, E> SpecializedEncoder<CrateNum> for CacheEncoder<'enc, 'a, 'tcx, E>
-    where E: 'enc + ty_codec::TyEncoder
-{
-    #[inline]
-    fn specialized_encode(&mut self, cnum: &CrateNum) -> Result<(), Self::Error> {
-        self.emit_u32(cnum.as_u32())
-    }
-}
-
-impl<'enc, 'a, 'tcx, E> SpecializedEncoder<ty::Ty<'tcx>> for CacheEncoder<'enc, 'a, 'tcx, E>
-    where E: 'enc + ty_codec::TyEncoder
-{
-    #[inline]
-    fn specialized_encode(&mut self, ty: &ty::Ty<'tcx>) -> Result<(), Self::Error> {
-        ty_codec::encode_with_shorthand(self, ty,
-            |encoder| &mut encoder.type_shorthands)
-    }
-}
-
-impl<'enc, 'a, 'tcx, E> SpecializedEncoder<ty::GenericPredicates<'tcx>>
-    for CacheEncoder<'enc, 'a, 'tcx, E>
-    where E: 'enc + ty_codec::TyEncoder
-{
-    #[inline]
-    fn specialized_encode(&mut self,
-                          predicates: &ty::GenericPredicates<'tcx>)
-                          -> Result<(), Self::Error> {
-        ty_codec::encode_predicates(self, predicates,
-            |encoder| &mut encoder.predicate_shorthands)
-    }
-}
-
-impl<'enc, 'a, 'tcx, E> SpecializedEncoder<hir::HirId> for CacheEncoder<'enc, 'a, 'tcx, E>
-    where E: 'enc + ty_codec::TyEncoder
-{
-    #[inline]
-    fn specialized_encode(&mut self, id: &hir::HirId) -> Result<(), Self::Error> {
-        let hir::HirId {
-            owner,
-            local_id,
-        } = *id;
-
-        let def_path_hash = self.tcx.hir.definitions().def_path_hash(owner);
-
-        def_path_hash.encode(self)?;
-        local_id.encode(self)
-    }
-}
-
-
-impl<'enc, 'a, 'tcx, E> SpecializedEncoder<DefId> for CacheEncoder<'enc, 'a, 'tcx, E>
-    where E: 'enc + ty_codec::TyEncoder
-{
-    #[inline]
-    fn specialized_encode(&mut self, id: &DefId) -> Result<(), Self::Error> {
-        let def_path_hash = self.tcx.def_path_hash(*id);
-        def_path_hash.encode(self)
-    }
-}
-
-impl<'enc, 'a, 'tcx, E> SpecializedEncoder<LocalDefId> for CacheEncoder<'enc, 'a, 'tcx, E>
-    where E: 'enc + ty_codec::TyEncoder
-{
-    #[inline]
-    fn specialized_encode(&mut self, id: &LocalDefId) -> Result<(), Self::Error> {
-        id.to_def_id().encode(self)
-    }
-}
-
-impl<'enc, 'a, 'tcx, E> SpecializedEncoder<DefIndex> for CacheEncoder<'enc, 'a, 'tcx, E>
-    where E: 'enc + ty_codec::TyEncoder
-{
-    fn specialized_encode(&mut self, _: &DefIndex) -> Result<(), Self::Error> {
-        bug!("Encoding DefIndex without context.")
-    }
-}
-
-// NodeIds are not stable across compilation sessions, so we store them in their
-// HirId representation. This allows use to map them to the current NodeId.
-impl<'enc, 'a, 'tcx, E> SpecializedEncoder<NodeId> for CacheEncoder<'enc, 'a, 'tcx, E>
-    where E: 'enc + ty_codec::TyEncoder
-{
-    #[inline]
-    fn specialized_encode(&mut self, node_id: &NodeId) -> Result<(), Self::Error> {
-        let hir_id = self.tcx.hir.node_to_hir_id(*node_id);
-        hir_id.encode(self)
-    }
-}
-
-impl<'enc, 'a, 'tcx> SpecializedEncoder<Fingerprint>
-for CacheEncoder<'enc, 'a, 'tcx, opaque::Encoder<'enc>>
-{
-    fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
-        f.encode_opaque(&mut self.encoder)
-    }
-}
-
-impl<'enc, 'a, 'tcx, E, T> SpecializedEncoder<mir::ClearCrossCrate<T>>
-for CacheEncoder<'enc, 'a, 'tcx, E>
-    where E: 'enc + ty_codec::TyEncoder,
-          T: Encodable,
-{
-    #[inline]
-    fn specialized_encode(&mut self,
-                          val: &mir::ClearCrossCrate<T>)
-                          -> Result<(), Self::Error> {
-        match *val {
-            mir::ClearCrossCrate::Clear => {
-                TAG_CLEAR_CROSS_CRATE_CLEAR.encode(self)
-            }
-            mir::ClearCrossCrate::Set(ref val) => {
-                TAG_CLEAR_CROSS_CRATE_SET.encode(self)?;
-                val.encode(self)
-            }
-        }
-    }
-}
-
-macro_rules! encoder_methods {
-    ($($name:ident($ty:ty);)*) => {
-        $(fn $name(&mut self, value: $ty) -> Result<(), Self::Error> {
-            self.encoder.$name(value)
-        })*
-    }
-}
-
-impl<'enc, 'a, 'tcx, E> Encoder for CacheEncoder<'enc, 'a, 'tcx, E>
-    where E: 'enc + ty_codec::TyEncoder
-{
-    type Error = E::Error;
-
-    fn emit_nil(&mut self) -> Result<(), Self::Error> {
-        Ok(())
-    }
-
-    encoder_methods! {
-        emit_usize(usize);
-        emit_u128(u128);
-        emit_u64(u64);
-        emit_u32(u32);
-        emit_u16(u16);
-        emit_u8(u8);
-
-        emit_isize(isize);
-        emit_i128(i128);
-        emit_i64(i64);
-        emit_i32(i32);
-        emit_i16(i16);
-        emit_i8(i8);
-
-        emit_bool(bool);
-        emit_f64(f64);
-        emit_f32(f32);
-        emit_char(char);
-        emit_str(&str);
-    }
-}
-
-// An integer that will always encode to 8 bytes.
-struct IntEncodedWithFixedSize(u64);
-
-impl IntEncodedWithFixedSize {
-    pub const ENCODED_SIZE: usize = 8;
-}
-
-impl UseSpecializedEncodable for IntEncodedWithFixedSize {}
-impl UseSpecializedDecodable for IntEncodedWithFixedSize {}
-
-impl<'enc> SpecializedEncoder<IntEncodedWithFixedSize> for opaque::Encoder<'enc> {
-    fn specialized_encode(&mut self, x: &IntEncodedWithFixedSize) -> Result<(), Self::Error> {
-        let start_pos = self.position();
-        for i in 0 .. IntEncodedWithFixedSize::ENCODED_SIZE {
-            ((x.0 >> i * 8) as u8).encode(self)?;
-        }
-        let end_pos = self.position();
-        assert_eq!((end_pos - start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
-        Ok(())
-    }
-}
-
-impl<'enc> SpecializedDecoder<IntEncodedWithFixedSize> for opaque::Decoder<'enc> {
-    fn specialized_decode(&mut self) -> Result<IntEncodedWithFixedSize, Self::Error> {
-        let mut value: u64 = 0;
-        let start_pos = self.position();
-
-        for i in 0 .. IntEncodedWithFixedSize::ENCODED_SIZE {
-            let byte: u8 = Decodable::decode(self)?;
-            value |= (byte as u64) << (i * 8);
-        }
-
-        let end_pos = self.position();
-        assert_eq!((end_pos - start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
-
-        Ok(IntEncodedWithFixedSize(value))
-    }
-}
-
-fn encode_query_results<'enc, 'a, 'tcx, Q, E>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                              encoder: &mut CacheEncoder<'enc, 'a, 'tcx, E>,
-                                              query_result_index: &mut EncodedQueryResultIndex)
-                                              -> Result<(), E::Error>
-    where Q: super::config::QueryDescription<'tcx>,
-          E: 'enc + TyEncoder,
-          Q::Value: Encodable,
-{
-    let desc = &format!("encode_query_results for {}",
-        unsafe { ::std::intrinsics::type_name::<Q>() });
-
-    time(tcx.sess, desc, || {
-
-    let map = Q::query_map(tcx).borrow();
-    assert!(map.active.is_empty());
-    for (key, entry) in map.results.iter() {
-        if Q::cache_on_disk(key.clone()) {
-            let dep_node = SerializedDepNodeIndex::new(entry.index.index());
-
-            // Record position of the cache entry
-            query_result_index.push((dep_node, AbsoluteBytePos::new(encoder.position())));
-
-            // Encode the type check tables with the SerializedDepNodeIndex
-            // as tag.
-            encoder.encode_tagged(dep_node, &entry.value)?;
-        }
-    }
-
-    Ok(())
-    })
-}
diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs
deleted file mode 100644 (file)
index 44eb0df..0000000
+++ /dev/null
@@ -1,1264 +0,0 @@
-// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! The implementation of the query system itself. Defines the macros
-//! that generate the actual methods on tcx which find and execute the
-//! provider, manage the caches, and so forth.
-
-use dep_graph::{DepNodeIndex, DepNode, DepKind, DepNodeColor};
-use errors::DiagnosticBuilder;
-use errors::Level;
-use errors::Diagnostic;
-use errors::FatalError;
-use ty::tls;
-use ty::{TyCtxt};
-use ty::maps::Query;
-use ty::maps::config::QueryConfig;
-use ty::maps::config::QueryDescription;
-use ty::maps::job::{QueryJob, QueryResult, QueryInfo};
-use ty::item_path;
-
-use util::common::{profq_msg, ProfileQueriesMsg, QueryMsg};
-
-use rustc_data_structures::fx::{FxHashMap};
-use rustc_data_structures::sync::{Lrc, Lock};
-use std::mem;
-use std::ptr;
-use std::collections::hash_map::Entry;
-use syntax_pos::Span;
-use syntax::codemap::DUMMY_SP;
-
-pub struct QueryMap<'tcx, D: QueryConfig<'tcx> + ?Sized> {
-    pub(super) results: FxHashMap<D::Key, QueryValue<D::Value>>,
-    pub(super) active: FxHashMap<D::Key, QueryResult<'tcx>>,
-}
-
-pub(super) struct QueryValue<T> {
-    pub(super) value: T,
-    pub(super) index: DepNodeIndex,
-}
-
-impl<T> QueryValue<T> {
-    pub(super) fn new(value: T,
-                      dep_node_index: DepNodeIndex)
-                      -> QueryValue<T> {
-        QueryValue {
-            value,
-            index: dep_node_index,
-        }
-    }
-}
-
-impl<'tcx, M: QueryConfig<'tcx>> QueryMap<'tcx, M> {
-    pub(super) fn new() -> QueryMap<'tcx, M> {
-        QueryMap {
-            results: FxHashMap(),
-            active: FxHashMap(),
-        }
-    }
-}
-
-// If enabled, send a message to the profile-queries thread
-macro_rules! profq_msg {
-    ($tcx:expr, $msg:expr) => {
-        if cfg!(debug_assertions) {
-            if $tcx.sess.profile_queries() {
-                profq_msg($tcx.sess, $msg)
-            }
-        }
-    }
-}
-
-// If enabled, format a key using its debug string, which can be
-// expensive to compute (in terms of time).
-macro_rules! profq_query_msg {
-    ($query:expr, $tcx:expr, $key:expr) => {{
-        let msg = if cfg!(debug_assertions) {
-            if $tcx.sess.profile_queries_and_keys() {
-                Some(format!("{:?}", $key))
-            } else { None }
-        } else { None };
-        QueryMsg {
-            query: $query,
-            msg,
-        }
-    }}
-}
-
-/// A type representing the responsibility to execute the job in the `job` field.
-/// This will poison the relevant query if dropped.
-pub(super) struct JobOwner<'a, 'tcx: 'a, Q: QueryDescription<'tcx> + 'a> {
-    map: &'a Lock<QueryMap<'tcx, Q>>,
-    key: Q::Key,
-    job: Lrc<QueryJob<'tcx>>,
-}
-
-impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
-    /// Either gets a JobOwner corresponding the the query, allowing us to
-    /// start executing the query, or it returns with the result of the query.
-    /// If the query is executing elsewhere, this will wait for it.
-    /// If the query panicked, this will silently panic.
-    ///
-    /// This function is inlined because that results in a noticeable speedup
-    /// for some compile-time benchmarks.
-    #[inline(always)]
-    pub(super) fn try_get(
-        tcx: TyCtxt<'a, 'tcx, '_>,
-        span: Span,
-        key: &Q::Key,
-    ) -> TryGetJob<'a, 'tcx, Q> {
-        let map = Q::query_map(tcx);
-        loop {
-            let mut lock = map.borrow_mut();
-            if let Some(value) = lock.results.get(key) {
-                profq_msg!(tcx, ProfileQueriesMsg::CacheHit);
-                let result = Ok((value.value.clone(), value.index));
-                return TryGetJob::JobCompleted(result);
-            }
-            let job = match lock.active.entry((*key).clone()) {
-                Entry::Occupied(entry) => {
-                    match *entry.get() {
-                        QueryResult::Started(ref job) => job.clone(),
-                        QueryResult::Poisoned => FatalError.raise(),
-                    }
-                }
-                Entry::Vacant(entry) => {
-                    // No job entry for this query. Return a new one to be started later
-                    return tls::with_related_context(tcx, |icx| {
-                        let info = QueryInfo {
-                            span,
-                            query: Q::query(key.clone()),
-                        };
-                        let job = Lrc::new(QueryJob::new(info, icx.query.clone()));
-                        let owner = JobOwner {
-                            map,
-                            job: job.clone(),
-                            key: (*key).clone(),
-                        };
-                        entry.insert(QueryResult::Started(job));
-                        TryGetJob::NotYetStarted(owner)
-                    })
-                }
-            };
-            mem::drop(lock);
-
-            if let Err(cycle) = job.await(tcx, span) {
-                return TryGetJob::JobCompleted(Err(cycle));
-            }
-        }
-    }
-
-    /// Completes the query by updating the query map with the `result`,
-    /// signals the waiter and forgets the JobOwner, so it won't poison the query
-    pub(super) fn complete(self, result: &Q::Value, dep_node_index: DepNodeIndex) {
-        // We can move out of `self` here because we `mem::forget` it below
-        let key = unsafe { ptr::read(&self.key) };
-        let job = unsafe { ptr::read(&self.job) };
-        let map = self.map;
-
-        // Forget ourself so our destructor won't poison the query
-        mem::forget(self);
-
-        let value = QueryValue::new(result.clone(), dep_node_index);
-        {
-            let mut lock = map.borrow_mut();
-            lock.active.remove(&key);
-            lock.results.insert(key, value);
-        }
-
-        job.signal_complete();
-    }
-
-    /// Executes a job by changing the ImplicitCtxt to point to the
-    /// new query job while it executes. It returns the diagnostics
-    /// captured during execution and the actual result.
-    pub(super) fn start<'lcx, F, R>(
-        &self,
-        tcx: TyCtxt<'_, 'tcx, 'lcx>,
-        compute: F)
-    -> (R, Vec<Diagnostic>)
-    where
-        F: for<'b> FnOnce(TyCtxt<'b, 'tcx, 'lcx>) -> R
-    {
-        // The TyCtxt stored in TLS has the same global interner lifetime
-        // as `tcx`, so we use `with_related_context` to relate the 'gcx lifetimes
-        // when accessing the ImplicitCtxt
-        let r = tls::with_related_context(tcx, move |current_icx| {
-            // Update the ImplicitCtxt to point to our new query job
-            let new_icx = tls::ImplicitCtxt {
-                tcx,
-                query: Some(self.job.clone()),
-                layout_depth: current_icx.layout_depth,
-                task: current_icx.task,
-            };
-
-            // Use the ImplicitCtxt while we execute the query
-            tls::enter_context(&new_icx, |_| {
-                compute(tcx)
-            })
-        });
-
-        // Extract the diagnostic from the job
-        let diagnostics = mem::replace(&mut *self.job.diagnostics.lock(), Vec::new());
-
-        (r, diagnostics)
-    }
-}
-
-impl<'a, 'tcx, Q: QueryDescription<'tcx>> Drop for JobOwner<'a, 'tcx, Q> {
-    fn drop(&mut self) {
-        // Poison the query so jobs waiting on it panic
-        self.map.borrow_mut().active.insert(self.key.clone(), QueryResult::Poisoned);
-        // Also signal the completion of the job, so waiters
-        // will continue execution
-        self.job.signal_complete();
-    }
-}
-
-#[derive(Clone)]
-pub struct CycleError<'tcx> {
-    /// The query and related span which uses the cycle
-    pub(super) usage: Option<(Span, Query<'tcx>)>,
-    pub(super) cycle: Vec<QueryInfo<'tcx>>,
-}
-
-/// The result of `try_get_lock`
-pub(super) enum TryGetJob<'a, 'tcx: 'a, D: QueryDescription<'tcx> + 'a> {
-    /// The query is not yet started. Contains a guard to the map eventually used to start it.
-    NotYetStarted(JobOwner<'a, 'tcx, D>),
-
-    /// The query was already completed.
-    /// Returns the result of the query and its dep node index
-    /// if it succeeded or a cycle error if it failed
-    JobCompleted(Result<(D::Value, DepNodeIndex), CycleError<'tcx>>),
-}
-
-impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
-    pub(super) fn report_cycle(self, CycleError { usage, cycle: stack }: CycleError<'gcx>)
-        -> DiagnosticBuilder<'a>
-    {
-        assert!(!stack.is_empty());
-
-        let fix_span = |span: Span, query: &Query<'gcx>| {
-            self.sess.codemap().def_span(query.default_span(self, span))
-        };
-
-        // Disable naming impls with types in this path, since that
-        // sometimes cycles itself, leading to extra cycle errors.
-        // (And cycle errors around impls tend to occur during the
-        // collect/coherence phases anyhow.)
-        item_path::with_forced_impl_filename_line(|| {
-            let span = fix_span(stack[1 % stack.len()].span, &stack[0].query);
-            let mut err = struct_span_err!(self.sess,
-                                           span,
-                                           E0391,
-                                           "cycle detected when {}",
-                                           stack[0].query.describe(self));
-
-            for i in 1..stack.len() {
-                let query = &stack[i].query;
-                let span = fix_span(stack[(i + 1) % stack.len()].span, query);
-                err.span_note(span, &format!("...which requires {}...", query.describe(self)));
-            }
-
-            err.note(&format!("...which again requires {}, completing the cycle",
-                              stack[0].query.describe(self)));
-
-            if let Some((span, query)) = usage {
-                err.span_note(fix_span(span, &query),
-                              &format!("cycle used when {}", query.describe(self)));
-            }
-
-            return err
-        })
-    }
-
-    pub fn try_print_query_stack() {
-        eprintln!("query stack during panic:");
-
-        tls::with_context_opt(|icx| {
-            if let Some(icx) = icx {
-                let mut current_query = icx.query.clone();
-                let mut i = 0;
-
-                while let Some(query) = current_query {
-                    let mut db = DiagnosticBuilder::new(icx.tcx.sess.diagnostic(),
-                        Level::FailureNote,
-                        &format!("#{} [{}] {}",
-                                 i,
-                                 query.info.query.name(),
-                                 query.info.query.describe(icx.tcx)));
-                    db.set_span(icx.tcx.sess.codemap().def_span(query.info.span));
-                    icx.tcx.sess.diagnostic().force_print_db(db);
-
-                    current_query = query.parent.clone();
-                    i += 1;
-                }
-            }
-        });
-
-        eprintln!("end of query stack");
-    }
-
-    /// Try to read a node index for the node dep_node.
-    /// A node will have an index, when it's already been marked green, or when we can mark it
-    /// green. This function will mark the current task as a reader of the specified node, when
-    /// the a node index can be found for that node.
-    pub(super) fn try_mark_green_and_read(self, dep_node: &DepNode) -> Option<DepNodeIndex> {
-        match self.dep_graph.node_color(dep_node) {
-            Some(DepNodeColor::Green(dep_node_index)) => {
-                self.dep_graph.read_index(dep_node_index);
-                Some(dep_node_index)
-            }
-            Some(DepNodeColor::Red) => {
-                None
-            }
-            None => {
-                // try_mark_green (called below) will panic when full incremental
-                // compilation is disabled. If that's the case, we can't try to mark nodes
-                // as green anyway, so we can safely return None here.
-                if !self.dep_graph.is_fully_enabled() {
-                    return None;
-                }
-                match self.dep_graph.try_mark_green(self.global_tcx(), &dep_node) {
-                    Some(dep_node_index) => {
-                        debug_assert!(self.dep_graph.is_green(&dep_node));
-                        self.dep_graph.read_index(dep_node_index);
-                        Some(dep_node_index)
-                    }
-                    None => {
-                        None
-                    }
-                }
-            }
-        }
-    }
-
-    fn try_get_with<Q: QueryDescription<'gcx>>(
-        self,
-        span: Span,
-        key: Q::Key)
-    -> Result<Q::Value, CycleError<'gcx>>
-    {
-        debug!("ty::queries::{}::try_get_with(key={:?}, span={:?})",
-               Q::NAME,
-               key,
-               span);
-
-        profq_msg!(self,
-            ProfileQueriesMsg::QueryBegin(
-                span.data(),
-                profq_query_msg!(Q::NAME, self, key),
-            )
-        );
-
-        let job = match JobOwner::try_get(self, span, &key) {
-            TryGetJob::NotYetStarted(job) => job,
-            TryGetJob::JobCompleted(result) => {
-                return result.map(|(v, index)| {
-                    self.dep_graph.read_index(index);
-                    v
-                })
-            }
-        };
-
-        // Fast path for when incr. comp. is off. `to_dep_node` is
-        // expensive for some DepKinds.
-        if !self.dep_graph.is_fully_enabled() {
-            let null_dep_node = DepNode::new_no_params(::dep_graph::DepKind::Null);
-            return self.force_query_with_job::<Q>(key, job, null_dep_node).map(|(v, _)| v);
-        }
-
-        let dep_node = Q::to_dep_node(self, &key);
-
-        if dep_node.kind.is_anon() {
-            profq_msg!(self, ProfileQueriesMsg::ProviderBegin);
-
-            let res = job.start(self, |tcx| {
-                tcx.dep_graph.with_anon_task(dep_node.kind, || {
-                    Q::compute(tcx.global_tcx(), key)
-                })
-            });
-
-            profq_msg!(self, ProfileQueriesMsg::ProviderEnd);
-            let ((result, dep_node_index), diagnostics) = res;
-
-            self.dep_graph.read_index(dep_node_index);
-
-            self.on_disk_query_result_cache
-                .store_diagnostics_for_anon_node(dep_node_index, diagnostics);
-
-            job.complete(&result, dep_node_index);
-
-            return Ok(result);
-        }
-
-        if !dep_node.kind.is_input() {
-            if let Some(dep_node_index) = self.try_mark_green_and_read(&dep_node) {
-                profq_msg!(self, ProfileQueriesMsg::CacheHit);
-                return self.load_from_disk_and_cache_in_memory::<Q>(key,
-                                                                    job,
-                                                                    dep_node_index,
-                                                                    &dep_node)
-            }
-        }
-
-        match self.force_query_with_job::<Q>(key, job, dep_node) {
-            Ok((result, dep_node_index)) => {
-                self.dep_graph.read_index(dep_node_index);
-                Ok(result)
-            }
-            Err(e) => Err(e)
-        }
-    }
-
-    fn load_from_disk_and_cache_in_memory<Q: QueryDescription<'gcx>>(
-        self,
-        key: Q::Key,
-        job: JobOwner<'a, 'gcx, Q>,
-        dep_node_index: DepNodeIndex,
-        dep_node: &DepNode
-    ) -> Result<Q::Value, CycleError<'gcx>>
-    {
-        // Note this function can be called concurrently from the same query
-        // We must ensure that this is handled correctly
-
-        debug_assert!(self.dep_graph.is_green(dep_node));
-
-        // First we try to load the result from the on-disk cache
-        let result = if Q::cache_on_disk(key.clone()) &&
-                        self.sess.opts.debugging_opts.incremental_queries {
-            let prev_dep_node_index =
-                self.dep_graph.prev_dep_node_index_of(dep_node);
-            let result = Q::try_load_from_disk(self.global_tcx(),
-                                                    prev_dep_node_index);
-
-            // We always expect to find a cached result for things that
-            // can be forced from DepNode.
-            debug_assert!(!dep_node.kind.can_reconstruct_query_key() ||
-                            result.is_some(),
-                            "Missing on-disk cache entry for {:?}",
-                            dep_node);
-            result
-        } else {
-            // Some things are never cached on disk.
-            None
-        };
-
-        let result = if let Some(result) = result {
-            result
-        } else {
-            // We could not load a result from the on-disk cache, so
-            // recompute.
-
-            // The diagnostics for this query have already been
-            // promoted to the current session during
-            // try_mark_green(), so we can ignore them here.
-            let (result, _) = job.start(self, |tcx| {
-                // The dep-graph for this computation is already in
-                // place
-                tcx.dep_graph.with_ignore(|| {
-                    Q::compute(tcx, key)
-                })
-            });
-            result
-        };
-
-        // If -Zincremental-verify-ich is specified, re-hash results from
-        // the cache and make sure that they have the expected fingerprint.
-        if self.sess.opts.debugging_opts.incremental_verify_ich {
-            use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
-            use ich::Fingerprint;
-
-            assert!(Some(self.dep_graph.fingerprint_of(dep_node_index)) ==
-                    self.dep_graph.prev_fingerprint_of(dep_node),
-                    "Fingerprint for green query instance not loaded \
-                        from cache: {:?}", dep_node);
-
-            debug!("BEGIN verify_ich({:?})", dep_node);
-            let mut hcx = self.create_stable_hashing_context();
-            let mut hasher = StableHasher::new();
-
-            result.hash_stable(&mut hcx, &mut hasher);
-
-            let new_hash: Fingerprint = hasher.finish();
-            debug!("END verify_ich({:?})", dep_node);
-
-            let old_hash = self.dep_graph.fingerprint_of(dep_node_index);
-
-            assert!(new_hash == old_hash, "Found unstable fingerprints \
-                for {:?}", dep_node);
-        }
-
-        if self.sess.opts.debugging_opts.query_dep_graph {
-            self.dep_graph.mark_loaded_from_cache(dep_node_index, true);
-        }
-
-        job.complete(&result, dep_node_index);
-
-        Ok(result)
-    }
-
-    fn force_query_with_job<Q: QueryDescription<'gcx>>(
-        self,
-        key: Q::Key,
-        job: JobOwner<'_, 'gcx, Q>,
-        dep_node: DepNode)
-    -> Result<(Q::Value, DepNodeIndex), CycleError<'gcx>> {
-        // If the following assertion triggers, it can have two reasons:
-        // 1. Something is wrong with DepNode creation, either here or
-        //    in DepGraph::try_mark_green()
-        // 2. Two distinct query keys get mapped to the same DepNode
-        //    (see for example #48923)
-        assert!(!self.dep_graph.dep_node_exists(&dep_node),
-                "Forcing query with already existing DepNode.\n\
-                    - query-key: {:?}\n\
-                    - dep-node: {:?}",
-                key, dep_node);
-
-        profq_msg!(self, ProfileQueriesMsg::ProviderBegin);
-        let res = job.start(self, |tcx| {
-            if dep_node.kind.is_eval_always() {
-                tcx.dep_graph.with_eval_always_task(dep_node,
-                                                    tcx,
-                                                    key,
-                                                    Q::compute)
-            } else {
-                tcx.dep_graph.with_task(dep_node,
-                                        tcx,
-                                        key,
-                                        Q::compute)
-            }
-        });
-        profq_msg!(self, ProfileQueriesMsg::ProviderEnd);
-
-        let ((result, dep_node_index), diagnostics) = res;
-
-        if self.sess.opts.debugging_opts.query_dep_graph {
-            self.dep_graph.mark_loaded_from_cache(dep_node_index, false);
-        }
-
-        if dep_node.kind != ::dep_graph::DepKind::Null {
-            self.on_disk_query_result_cache
-                .store_diagnostics(dep_node_index, diagnostics);
-        }
-
-        job.complete(&result, dep_node_index);
-
-        Ok((result, dep_node_index))
-    }
-
-    /// Ensure that either this query has all green inputs or been executed.
-    /// Executing query::ensure(D) is considered a read of the dep-node D.
-    ///
-    /// This function is particularly useful when executing passes for their
-    /// side-effects -- e.g., in order to report errors for erroneous programs.
-    ///
-    /// Note: The optimization is only available during incr. comp.
-    pub fn ensure_query<Q: QueryDescription<'gcx>>(self, key: Q::Key) -> () {
-        let dep_node = Q::to_dep_node(self, &key);
-
-        // Ensuring an "input" or anonymous query makes no sense
-        assert!(!dep_node.kind.is_anon());
-        assert!(!dep_node.kind.is_input());
-        if self.try_mark_green_and_read(&dep_node).is_none() {
-            // A None return from `try_mark_green_and_read` means that this is either
-            // a new dep node or that the dep node has already been marked red.
-            // Either way, we can't call `dep_graph.read()` as we don't have the
-            // DepNodeIndex. We must invoke the query itself. The performance cost
-            // this introduces should be negligible as we'll immediately hit the
-            // in-memory cache, or another query down the line will.
-            let _ = self.get_query::<Q>(DUMMY_SP, key);
-        }
-    }
-
-    #[allow(dead_code)]
-    fn force_query<Q: QueryDescription<'gcx>>(
-        self,
-        key: Q::Key,
-        span: Span,
-        dep_node: DepNode
-    ) -> Result<(Q::Value, DepNodeIndex), CycleError<'gcx>> {
-        // We may be concurrently trying both execute and force a query
-        // Ensure that only one of them runs the query
-        let job = match JobOwner::try_get(self, span, &key) {
-            TryGetJob::NotYetStarted(job) => job,
-            TryGetJob::JobCompleted(result) => return result,
-        };
-        self.force_query_with_job::<Q>(key, job, dep_node)
-    }
-
-    pub fn try_get_query<Q: QueryDescription<'gcx>>(
-        self,
-        span: Span,
-        key: Q::Key
-    ) -> Result<Q::Value, DiagnosticBuilder<'a>> {
-        match self.try_get_with::<Q>(span, key) {
-            Ok(e) => Ok(e),
-            Err(e) => Err(self.report_cycle(e)),
-        }
-    }
-
-    pub fn get_query<Q: QueryDescription<'gcx>>(self, span: Span, key: Q::Key) -> Q::Value {
-        self.try_get_query::<Q>(span, key).unwrap_or_else(|mut e| {
-            e.emit();
-            Q::handle_cycle_error(self)
-        })
-    }
-}
-
-macro_rules! handle_cycle_error {
-    ([][$this: expr]) => {{
-        Value::from_cycle_error($this.global_tcx())
-    }};
-    ([fatal_cycle$(, $modifiers:ident)*][$this:expr]) => {{
-        $this.sess.abort_if_errors();
-        unreachable!();
-    }};
-    ([$other:ident$(, $modifiers:ident)*][$($args:tt)*]) => {
-        handle_cycle_error!([$($modifiers),*][$($args)*])
-    };
-}
-
-macro_rules! define_maps {
-    (<$tcx:tt>
-     $($(#[$attr:meta])*
-       [$($modifiers:tt)*] fn $name:ident: $node:ident($K:ty) -> $V:ty,)*) => {
-
-        use std::mem;
-        use ty::maps::job::QueryResult;
-        use rustc_data_structures::sync::Lock;
-        use {
-            rustc_data_structures::stable_hasher::HashStable,
-            rustc_data_structures::stable_hasher::StableHasherResult,
-            rustc_data_structures::stable_hasher::StableHasher,
-            ich::StableHashingContext
-        };
-
-        define_map_struct! {
-            tcx: $tcx,
-            input: ($(([$($modifiers)*] [$($attr)*] [$name]))*)
-        }
-
-        impl<$tcx> Maps<$tcx> {
-            pub fn new(providers: IndexVec<CrateNum, Providers<$tcx>>)
-                       -> Self {
-                Maps {
-                    providers,
-                    $($name: Lock::new(QueryMap::new())),*
-                }
-            }
-
-            pub fn collect_active_jobs(&self) -> Vec<Lrc<QueryJob<$tcx>>> {
-                let mut jobs = Vec::new();
-
-                // We use try_lock here since we are only called from the
-                // deadlock handler, and this shouldn't be locked
-                $(for v in self.$name.try_lock().unwrap().active.values() {
-                    match *v {
-                        QueryResult::Started(ref job) => jobs.push(job.clone()),
-                        _ => (),
-                    }
-                })*
-
-                return jobs;
-            }
-        }
-
-        #[allow(bad_style)]
-        #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
-        pub enum Query<$tcx> {
-            $($(#[$attr])* $name($K)),*
-        }
-
-        impl<$tcx> Query<$tcx> {
-            pub fn name(&self) -> &'static str {
-                match *self {
-                    $(Query::$name(_) => stringify!($name),)*
-                }
-            }
-
-            pub fn describe(&self, tcx: TyCtxt) -> String {
-                let (r, name) = match *self {
-                    $(Query::$name(key) => {
-                        (queries::$name::describe(tcx, key), stringify!($name))
-                    })*
-                };
-                if tcx.sess.verbose() {
-                    format!("{} [{}]", r, name)
-                } else {
-                    r
-                }
-            }
-
-            // FIXME(eddyb) Get more valid Span's on queries.
-            pub fn default_span(&self, tcx: TyCtxt<'_, $tcx, '_>, span: Span) -> Span {
-                if span != DUMMY_SP {
-                    return span;
-                }
-                // The def_span query is used to calculate default_span,
-                // so exit to avoid infinite recursion
-                match *self {
-                    Query::def_span(..) => return span,
-                    _ => ()
-                }
-                match *self {
-                    $(Query::$name(key) => key.default_span(tcx),)*
-                }
-            }
-        }
-
-        impl<'a, $tcx> HashStable<StableHashingContext<'a>> for Query<$tcx> {
-            fn hash_stable<W: StableHasherResult>(&self,
-                                                hcx: &mut StableHashingContext<'a>,
-                                                hasher: &mut StableHasher<W>) {
-                mem::discriminant(self).hash_stable(hcx, hasher);
-                match *self {
-                    $(Query::$name(key) => key.hash_stable(hcx, hasher),)*
-                }
-            }
-        }
-
-        pub mod queries {
-            use std::marker::PhantomData;
-
-            $(#[allow(bad_style)]
-            pub struct $name<$tcx> {
-                data: PhantomData<&$tcx ()>
-            })*
-        }
-
-        // This module and the functions in it exist only to provide a
-        // predictable symbol name prefix for query providers. This is helpful
-        // for analyzing queries in profilers.
-        pub(super) mod __query_compute {
-            $(#[inline(never)]
-            pub fn $name<F: FnOnce() -> R, R>(f: F) -> R {
-                f()
-            })*
-        }
-
-        $(impl<$tcx> QueryConfig<$tcx> for queries::$name<$tcx> {
-            type Key = $K;
-            type Value = $V;
-
-            const NAME: &'static str = stringify!($name);
-
-            fn query(key: Self::Key) -> Query<'tcx> {
-                Query::$name(key)
-            }
-
-            fn query_map<'a>(tcx: TyCtxt<'a, $tcx, '_>) -> &'a Lock<QueryMap<$tcx, Self>> {
-                &tcx.maps.$name
-            }
-
-            #[allow(unused)]
-            fn to_dep_node(tcx: TyCtxt<'_, $tcx, '_>, key: &Self::Key) -> DepNode {
-                use dep_graph::DepConstructor::*;
-
-                DepNode::new(tcx, $node(*key))
-            }
-
-            #[inline]
-            fn compute(tcx: TyCtxt<'_, 'tcx, '_>, key: Self::Key) -> Self::Value {
-                __query_compute::$name(move || {
-                    let provider = tcx.maps.providers[key.map_crate()].$name;
-                    provider(tcx.global_tcx(), key)
-                })
-            }
-
-            fn handle_cycle_error(tcx: TyCtxt<'_, 'tcx, '_>) -> Self::Value {
-                handle_cycle_error!([$($modifiers)*][tcx])
-            }
-        }
-
-        impl<'a, $tcx, 'lcx> queries::$name<$tcx> {
-            /// Ensure that either this query has all green inputs or been executed.
-            /// Executing query::ensure(D) is considered a read of the dep-node D.
-            ///
-            /// This function is particularly useful when executing passes for their
-            /// side-effects -- e.g., in order to report errors for erroneous programs.
-            ///
-            /// Note: The optimization is only available during incr. comp.
-            pub fn ensure(tcx: TyCtxt<'a, $tcx, 'lcx>, key: $K) -> () {
-                tcx.ensure_query::<queries::$name>(key);
-            }
-        })*
-
-        #[derive(Copy, Clone)]
-        pub struct TyCtxtAt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
-            pub tcx: TyCtxt<'a, 'gcx, 'tcx>,
-            pub span: Span,
-        }
-
-        impl<'a, 'gcx, 'tcx> Deref for TyCtxtAt<'a, 'gcx, 'tcx> {
-            type Target = TyCtxt<'a, 'gcx, 'tcx>;
-            fn deref(&self) -> &Self::Target {
-                &self.tcx
-            }
-        }
-
-        impl<'a, $tcx, 'lcx> TyCtxt<'a, $tcx, 'lcx> {
-            /// Return a transparent wrapper for `TyCtxt` which uses
-            /// `span` as the location of queries performed through it.
-            pub fn at(self, span: Span) -> TyCtxtAt<'a, $tcx, 'lcx> {
-                TyCtxtAt {
-                    tcx: self,
-                    span
-                }
-            }
-
-            $($(#[$attr])*
-            pub fn $name(self, key: $K) -> $V {
-                self.at(DUMMY_SP).$name(key)
-            })*
-        }
-
-        impl<'a, $tcx, 'lcx> TyCtxtAt<'a, $tcx, 'lcx> {
-            $($(#[$attr])*
-            pub fn $name(self, key: $K) -> $V {
-                self.tcx.get_query::<queries::$name>(self.span, key)
-            })*
-        }
-
-        define_provider_struct! {
-            tcx: $tcx,
-            input: ($(([$($modifiers)*] [$name] [$K] [$V]))*)
-        }
-
-        impl<$tcx> Copy for Providers<$tcx> {}
-        impl<$tcx> Clone for Providers<$tcx> {
-            fn clone(&self) -> Self { *self }
-        }
-    }
-}
-
-macro_rules! define_map_struct {
-    (tcx: $tcx:tt,
-     input: ($(([$($modifiers:tt)*] [$($attr:tt)*] [$name:ident]))*)) => {
-        pub struct Maps<$tcx> {
-            providers: IndexVec<CrateNum, Providers<$tcx>>,
-            $($(#[$attr])*  $name: Lock<QueryMap<$tcx, queries::$name<$tcx>>>,)*
-        }
-    };
-}
-
-macro_rules! define_provider_struct {
-    (tcx: $tcx:tt,
-     input: ($(([$($modifiers:tt)*] [$name:ident] [$K:ty] [$R:ty]))*)) => {
-        pub struct Providers<$tcx> {
-            $(pub $name: for<'a> fn(TyCtxt<'a, $tcx, $tcx>, $K) -> $R,)*
-        }
-
-        impl<$tcx> Default for Providers<$tcx> {
-            fn default() -> Self {
-                $(fn $name<'a, $tcx>(_: TyCtxt<'a, $tcx, $tcx>, key: $K) -> $R {
-                    bug!("tcx.maps.{}({:?}) unsupported by its crate",
-                         stringify!($name), key);
-                })*
-                Providers { $($name),* }
-            }
-        }
-    };
-}
-
-
-/// The red/green evaluation system will try to mark a specific DepNode in the
-/// dependency graph as green by recursively trying to mark the dependencies of
-/// that DepNode as green. While doing so, it will sometimes encounter a DepNode
-/// where we don't know if it is red or green and we therefore actually have
-/// to recompute its value in order to find out. Since the only piece of
-/// information that we have at that point is the DepNode we are trying to
-/// re-evaluate, we need some way to re-run a query from just that. This is what
-/// `force_from_dep_node()` implements.
-///
-/// In the general case, a DepNode consists of a DepKind and an opaque
-/// GUID/fingerprint that will uniquely identify the node. This GUID/fingerprint
-/// is usually constructed by computing a stable hash of the query-key that the
-/// DepNode corresponds to. Consequently, it is not in general possible to go
-/// back from hash to query-key (since hash functions are not reversible). For
-/// this reason `force_from_dep_node()` is expected to fail from time to time
-/// because we just cannot find out, from the DepNode alone, what the
-/// corresponding query-key is and therefore cannot re-run the query.
-///
-/// The system deals with this case letting `try_mark_green` fail which forces
-/// the root query to be re-evaluated.
-///
-/// Now, if force_from_dep_node() would always fail, it would be pretty useless.
-/// Fortunately, we can use some contextual information that will allow us to
-/// reconstruct query-keys for certain kinds of DepNodes. In particular, we
-/// enforce by construction that the GUID/fingerprint of certain DepNodes is a
-/// valid DefPathHash. Since we also always build a huge table that maps every
-/// DefPathHash in the current codebase to the corresponding DefId, we have
-/// everything we need to re-run the query.
-///
-/// Take the `mir_validated` query as an example. Like many other queries, it
-/// just has a single parameter: the DefId of the item it will compute the
-/// validated MIR for. Now, when we call `force_from_dep_node()` on a dep-node
-/// with kind `MirValidated`, we know that the GUID/fingerprint of the dep-node
-/// is actually a DefPathHash, and can therefore just look up the corresponding
-/// DefId in `tcx.def_path_hash_to_def_id`.
-///
-/// When you implement a new query, it will likely have a corresponding new
-/// DepKind, and you'll have to support it here in `force_from_dep_node()`. As
-/// a rule of thumb, if your query takes a DefId or DefIndex as sole parameter,
-/// then `force_from_dep_node()` should not fail for it. Otherwise, you can just
-/// add it to the "We don't have enough information to reconstruct..." group in
-/// the match below.
-pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
-                                           dep_node: &DepNode)
-                                           -> bool {
-    use hir::def_id::LOCAL_CRATE;
-
-    // We must avoid ever having to call force_from_dep_node() for a
-    // DepNode::CodegenUnit:
-    // Since we cannot reconstruct the query key of a DepNode::CodegenUnit, we
-    // would always end up having to evaluate the first caller of the
-    // `codegen_unit` query that *is* reconstructible. This might very well be
-    // the `compile_codegen_unit` query, thus re-codegenning the whole CGU just
-    // to re-trigger calling the `codegen_unit` query with the right key. At
-    // that point we would already have re-done all the work we are trying to
-    // avoid doing in the first place.
-    // The solution is simple: Just explicitly call the `codegen_unit` query for
-    // each CGU, right after partitioning. This way `try_mark_green` will always
-    // hit the cache instead of having to go through `force_from_dep_node`.
-    // This assertion makes sure, we actually keep applying the solution above.
-    debug_assert!(dep_node.kind != DepKind::CodegenUnit,
-                  "calling force_from_dep_node() on DepKind::CodegenUnit");
-
-    if !dep_node.kind.can_reconstruct_query_key() {
-        return false
-    }
-
-    macro_rules! def_id {
-        () => {
-            if let Some(def_id) = dep_node.extract_def_id(tcx) {
-                def_id
-            } else {
-                // return from the whole function
-                return false
-            }
-        }
-    };
-
-    macro_rules! krate {
-        () => { (def_id!()).krate }
-    };
-
-    macro_rules! force {
-        ($query:ident, $key:expr) => {
-            {
-                use $crate::util::common::{ProfileQueriesMsg, profq_msg};
-
-                profq_msg!(tcx,
-                    ProfileQueriesMsg::QueryBegin(
-                        DUMMY_SP.data(),
-                        profq_query_msg!(::ty::maps::queries::$query::NAME, tcx, $key),
-                    )
-                );
-
-                match tcx.force_query::<::ty::maps::queries::$query>($key, DUMMY_SP, *dep_node) {
-                    Ok(_) => {},
-                    Err(e) => {
-                        tcx.report_cycle(e).emit();
-                    }
-                }
-            }
-        }
-    };
-
-    // FIXME(#45015): We should try move this boilerplate code into a macro
-    //                somehow.
-    match dep_node.kind {
-        // These are inputs that are expected to be pre-allocated and that
-        // should therefore always be red or green already
-        DepKind::AllLocalTraitImpls |
-        DepKind::Krate |
-        DepKind::CrateMetadata |
-        DepKind::HirBody |
-        DepKind::Hir |
-
-        // This are anonymous nodes
-        DepKind::TraitSelect |
-
-        // We don't have enough information to reconstruct the query key of
-        // these
-        DepKind::IsCopy |
-        DepKind::IsSized |
-        DepKind::IsFreeze |
-        DepKind::NeedsDrop |
-        DepKind::Layout |
-        DepKind::ConstEval |
-        DepKind::InstanceSymbolName |
-        DepKind::MirShim |
-        DepKind::BorrowCheckKrate |
-        DepKind::Specializes |
-        DepKind::ImplementationsOfTrait |
-        DepKind::TypeParamPredicates |
-        DepKind::CodegenUnit |
-        DepKind::CompileCodegenUnit |
-        DepKind::FulfillObligation |
-        DepKind::VtableMethods |
-        DepKind::EraseRegionsTy |
-        DepKind::ConstValueToAllocation |
-        DepKind::NormalizeProjectionTy |
-        DepKind::NormalizeTyAfterErasingRegions |
-        DepKind::DropckOutlives |
-        DepKind::EvaluateObligation |
-        DepKind::SubstituteNormalizeAndTestPredicates |
-        DepKind::InstanceDefSizeEstimate |
-        DepKind::ProgramClausesForEnv |
-
-        // This one should never occur in this context
-        DepKind::Null => {
-            bug!("force_from_dep_node() - Encountered {:?}", dep_node)
-        }
-
-        // These are not queries
-        DepKind::CoherenceCheckTrait |
-        DepKind::ItemVarianceConstraints => {
-            return false
-        }
-
-        DepKind::RegionScopeTree => { force!(region_scope_tree, def_id!()); }
-
-        DepKind::Coherence => { force!(crate_inherent_impls, LOCAL_CRATE); }
-        DepKind::CoherenceInherentImplOverlapCheck => {
-            force!(crate_inherent_impls_overlap_check, LOCAL_CRATE)
-        },
-        DepKind::PrivacyAccessLevels => { force!(privacy_access_levels, LOCAL_CRATE); }
-        DepKind::MirBuilt => { force!(mir_built, def_id!()); }
-        DepKind::MirConstQualif => { force!(mir_const_qualif, def_id!()); }
-        DepKind::MirConst => { force!(mir_const, def_id!()); }
-        DepKind::MirValidated => { force!(mir_validated, def_id!()); }
-        DepKind::MirOptimized => { force!(optimized_mir, def_id!()); }
-
-        DepKind::BorrowCheck => { force!(borrowck, def_id!()); }
-        DepKind::MirBorrowCheck => { force!(mir_borrowck, def_id!()); }
-        DepKind::UnsafetyCheckResult => { force!(unsafety_check_result, def_id!()); }
-        DepKind::UnsafeDeriveOnReprPacked => { force!(unsafe_derive_on_repr_packed, def_id!()); }
-        DepKind::Reachability => { force!(reachable_set, LOCAL_CRATE); }
-        DepKind::MirKeys => { force!(mir_keys, LOCAL_CRATE); }
-        DepKind::CrateVariances => { force!(crate_variances, LOCAL_CRATE); }
-        DepKind::AssociatedItems => { force!(associated_item, def_id!()); }
-        DepKind::TypeOfItem => { force!(type_of, def_id!()); }
-        DepKind::GenericsOfItem => { force!(generics_of, def_id!()); }
-        DepKind::PredicatesOfItem => { force!(predicates_of, def_id!()); }
-        DepKind::ExplicitPredicatesOfItem => { force!(explicit_predicates_of, def_id!()); }
-        DepKind::InferredOutlivesOf => { force!(inferred_outlives_of, def_id!()); }
-        DepKind::InferredOutlivesCrate => { force!(inferred_outlives_crate, LOCAL_CRATE); }
-        DepKind::SuperPredicatesOfItem => { force!(super_predicates_of, def_id!()); }
-        DepKind::TraitDefOfItem => { force!(trait_def, def_id!()); }
-        DepKind::AdtDefOfItem => { force!(adt_def, def_id!()); }
-        DepKind::ImplTraitRef => { force!(impl_trait_ref, def_id!()); }
-        DepKind::ImplPolarity => { force!(impl_polarity, def_id!()); }
-        DepKind::FnSignature => { force!(fn_sig, def_id!()); }
-        DepKind::CoerceUnsizedInfo => { force!(coerce_unsized_info, def_id!()); }
-        DepKind::ItemVariances => { force!(variances_of, def_id!()); }
-        DepKind::IsConstFn => { force!(is_const_fn, def_id!()); }
-        DepKind::IsForeignItem => { force!(is_foreign_item, def_id!()); }
-        DepKind::SizedConstraint => { force!(adt_sized_constraint, def_id!()); }
-        DepKind::DtorckConstraint => { force!(adt_dtorck_constraint, def_id!()); }
-        DepKind::AdtDestructor => { force!(adt_destructor, def_id!()); }
-        DepKind::AssociatedItemDefIds => { force!(associated_item_def_ids, def_id!()); }
-        DepKind::InherentImpls => { force!(inherent_impls, def_id!()); }
-        DepKind::TypeckBodiesKrate => { force!(typeck_item_bodies, LOCAL_CRATE); }
-        DepKind::TypeckTables => { force!(typeck_tables_of, def_id!()); }
-        DepKind::UsedTraitImports => { force!(used_trait_imports, def_id!()); }
-        DepKind::HasTypeckTables => { force!(has_typeck_tables, def_id!()); }
-        DepKind::SymbolName => { force!(def_symbol_name, def_id!()); }
-        DepKind::SpecializationGraph => { force!(specialization_graph_of, def_id!()); }
-        DepKind::ObjectSafety => { force!(is_object_safe, def_id!()); }
-        DepKind::TraitImpls => { force!(trait_impls_of, def_id!()); }
-        DepKind::CheckMatch => { force!(check_match, def_id!()); }
-
-        DepKind::ParamEnv => { force!(param_env, def_id!()); }
-        DepKind::DescribeDef => { force!(describe_def, def_id!()); }
-        DepKind::DefSpan => { force!(def_span, def_id!()); }
-        DepKind::LookupStability => { force!(lookup_stability, def_id!()); }
-        DepKind::LookupDeprecationEntry => {
-            force!(lookup_deprecation_entry, def_id!());
-        }
-        DepKind::ConstIsRvaluePromotableToStatic => {
-            force!(const_is_rvalue_promotable_to_static, def_id!());
-        }
-        DepKind::RvaluePromotableMap => { force!(rvalue_promotable_map, def_id!()); }
-        DepKind::ImplParent => { force!(impl_parent, def_id!()); }
-        DepKind::TraitOfItem => { force!(trait_of_item, def_id!()); }
-        DepKind::IsReachableNonGeneric => { force!(is_reachable_non_generic, def_id!()); }
-        DepKind::IsUnreachableLocalDefinition => {
-            force!(is_unreachable_local_definition, def_id!());
-        }
-        DepKind::IsMirAvailable => { force!(is_mir_available, def_id!()); }
-        DepKind::ItemAttrs => { force!(item_attrs, def_id!()); }
-        DepKind::CodegenFnAttrs => { force!(codegen_fn_attrs, def_id!()); }
-        DepKind::FnArgNames => { force!(fn_arg_names, def_id!()); }
-        DepKind::RenderedConst => { force!(rendered_const, def_id!()); }
-        DepKind::DylibDepFormats => { force!(dylib_dependency_formats, krate!()); }
-        DepKind::IsPanicRuntime => { force!(is_panic_runtime, krate!()); }
-        DepKind::IsCompilerBuiltins => { force!(is_compiler_builtins, krate!()); }
-        DepKind::HasGlobalAllocator => { force!(has_global_allocator, krate!()); }
-        DepKind::ExternCrate => { force!(extern_crate, def_id!()); }
-        DepKind::LintLevels => { force!(lint_levels, LOCAL_CRATE); }
-        DepKind::InScopeTraits => { force!(in_scope_traits_map, def_id!().index); }
-        DepKind::ModuleExports => { force!(module_exports, def_id!()); }
-        DepKind::IsSanitizerRuntime => { force!(is_sanitizer_runtime, krate!()); }
-        DepKind::IsProfilerRuntime => { force!(is_profiler_runtime, krate!()); }
-        DepKind::GetPanicStrategy => { force!(panic_strategy, krate!()); }
-        DepKind::IsNoBuiltins => { force!(is_no_builtins, krate!()); }
-        DepKind::ImplDefaultness => { force!(impl_defaultness, def_id!()); }
-        DepKind::CheckItemWellFormed => { force!(check_item_well_formed, def_id!()); }
-        DepKind::CheckTraitItemWellFormed => { force!(check_trait_item_well_formed, def_id!()); }
-        DepKind::CheckImplItemWellFormed => { force!(check_impl_item_well_formed, def_id!()); }
-        DepKind::ReachableNonGenerics => { force!(reachable_non_generics, krate!()); }
-        DepKind::NativeLibraries => { force!(native_libraries, krate!()); }
-        DepKind::PluginRegistrarFn => { force!(plugin_registrar_fn, krate!()); }
-        DepKind::DeriveRegistrarFn => { force!(derive_registrar_fn, krate!()); }
-        DepKind::CrateDisambiguator => { force!(crate_disambiguator, krate!()); }
-        DepKind::CrateHash => { force!(crate_hash, krate!()); }
-        DepKind::OriginalCrateName => { force!(original_crate_name, krate!()); }
-        DepKind::ExtraFileName => { force!(extra_filename, krate!()); }
-
-        DepKind::AllTraitImplementations => {
-            force!(all_trait_implementations, krate!());
-        }
-
-        DepKind::DllimportForeignItems => {
-            force!(dllimport_foreign_items, krate!());
-        }
-        DepKind::IsDllimportForeignItem => {
-            force!(is_dllimport_foreign_item, def_id!());
-        }
-        DepKind::IsStaticallyIncludedForeignItem => {
-            force!(is_statically_included_foreign_item, def_id!());
-        }
-        DepKind::NativeLibraryKind => { force!(native_library_kind, def_id!()); }
-        DepKind::LinkArgs => { force!(link_args, LOCAL_CRATE); }
-
-        DepKind::ResolveLifetimes => { force!(resolve_lifetimes, krate!()); }
-        DepKind::NamedRegion => { force!(named_region_map, def_id!().index); }
-        DepKind::IsLateBound => { force!(is_late_bound_map, def_id!().index); }
-        DepKind::ObjectLifetimeDefaults => {
-            force!(object_lifetime_defaults_map, def_id!().index);
-        }
-
-        DepKind::Visibility => { force!(visibility, def_id!()); }
-        DepKind::DepKind => { force!(dep_kind, krate!()); }
-        DepKind::CrateName => { force!(crate_name, krate!()); }
-        DepKind::ItemChildren => { force!(item_children, def_id!()); }
-        DepKind::ExternModStmtCnum => { force!(extern_mod_stmt_cnum, def_id!()); }
-        DepKind::GetLangItems => { force!(get_lang_items, LOCAL_CRATE); }
-        DepKind::DefinedLangItems => { force!(defined_lang_items, krate!()); }
-        DepKind::MissingLangItems => { force!(missing_lang_items, krate!()); }
-        DepKind::VisibleParentMap => { force!(visible_parent_map, LOCAL_CRATE); }
-        DepKind::MissingExternCrateItem => {
-            force!(missing_extern_crate_item, krate!());
-        }
-        DepKind::UsedCrateSource => { force!(used_crate_source, krate!()); }
-        DepKind::PostorderCnums => { force!(postorder_cnums, LOCAL_CRATE); }
-
-        DepKind::Freevars => { force!(freevars, def_id!()); }
-        DepKind::MaybeUnusedTraitImport => {
-            force!(maybe_unused_trait_import, def_id!());
-        }
-        DepKind::MaybeUnusedExternCrates => { force!(maybe_unused_extern_crates, LOCAL_CRATE); }
-        DepKind::StabilityIndex => { force!(stability_index, LOCAL_CRATE); }
-        DepKind::AllTraits => { force!(all_traits, LOCAL_CRATE); }
-        DepKind::AllCrateNums => { force!(all_crate_nums, LOCAL_CRATE); }
-        DepKind::ExportedSymbols => { force!(exported_symbols, krate!()); }
-        DepKind::CollectAndPartitionMonoItems => {
-            force!(collect_and_partition_mono_items, LOCAL_CRATE);
-        }
-        DepKind::IsCodegenedItem => { force!(is_codegened_item, def_id!()); }
-        DepKind::OutputFilenames => { force!(output_filenames, LOCAL_CRATE); }
-
-        DepKind::TargetFeaturesWhitelist => { force!(target_features_whitelist, LOCAL_CRATE); }
-
-        DepKind::Features => { force!(features_query, LOCAL_CRATE); }
-
-        DepKind::ProgramClausesFor => { force!(program_clauses_for, def_id!()); }
-        DepKind::WasmCustomSections => { force!(wasm_custom_sections, krate!()); }
-        DepKind::WasmImportModuleMap => { force!(wasm_import_module_map, krate!()); }
-        DepKind::ForeignModules => { force!(foreign_modules, krate!()); }
-
-        DepKind::UpstreamMonomorphizations => {
-            force!(upstream_monomorphizations, krate!());
-        }
-        DepKind::UpstreamMonomorphizationsFor => {
-            force!(upstream_monomorphizations_for, def_id!());
-        }
-    }
-
-    true
-}
-
-
-// FIXME(#45015): Another piece of boilerplate code that could be generated in
-//                a combined define_dep_nodes!()/define_maps!() macro.
-macro_rules! impl_load_from_cache {
-    ($($dep_kind:ident => $query_name:ident,)*) => {
-        impl DepNode {
-            // Check whether the query invocation corresponding to the given
-            // DepNode is eligible for on-disk-caching.
-            pub fn cache_on_disk(&self, tcx: TyCtxt) -> bool {
-                use ty::maps::queries;
-                use ty::maps::QueryDescription;
-
-                match self.kind {
-                    $(DepKind::$dep_kind => {
-                        let def_id = self.extract_def_id(tcx).unwrap();
-                        queries::$query_name::cache_on_disk(def_id)
-                    })*
-                    _ => false
-                }
-            }
-
-            // This is method will execute the query corresponding to the given
-            // DepNode. It is only expected to work for DepNodes where the
-            // above `cache_on_disk` methods returns true.
-            // Also, as a sanity check, it expects that the corresponding query
-            // invocation has been marked as green already.
-            pub fn load_from_on_disk_cache(&self, tcx: TyCtxt) {
-                match self.kind {
-                    $(DepKind::$dep_kind => {
-                        debug_assert!(tcx.dep_graph
-                                         .node_color(self)
-                                         .map(|c| c.is_green())
-                                         .unwrap_or(false));
-
-                        let def_id = self.extract_def_id(tcx).unwrap();
-                        let _ = tcx.$query_name(def_id);
-                    })*
-                    _ => {
-                        bug!()
-                    }
-                }
-            }
-        }
-    }
-}
-
-impl_load_from_cache!(
-    TypeckTables => typeck_tables_of,
-    MirOptimized => optimized_mir,
-    UnsafetyCheckResult => unsafety_check_result,
-    BorrowCheck => borrowck,
-    MirBorrowCheck => mir_borrowck,
-    MirConstQualif => mir_const_qualif,
-    SymbolName => def_symbol_name,
-    ConstIsRvaluePromotableToStatic => const_is_rvalue_promotable_to_static,
-    CheckMatch => check_match,
-    TypeOfItem => type_of,
-    GenericsOfItem => generics_of,
-    PredicatesOfItem => predicates_of,
-    UsedTraitImports => used_trait_imports,
-    CodegenFnAttrs => codegen_fn_attrs,
-    SpecializationGraph => specialization_graph_of,
-);
diff --git a/src/librustc/ty/maps/values.rs b/src/librustc/ty/maps/values.rs
deleted file mode 100644 (file)
index d3d0624..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use ty::{self, Ty, TyCtxt};
-
-use syntax::symbol::Symbol;
-
-pub(super) trait Value<'tcx>: Sized {
-    fn from_cycle_error<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self;
-}
-
-impl<'tcx, T> Value<'tcx> for T {
-    default fn from_cycle_error<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> T {
-        tcx.sess.abort_if_errors();
-        bug!("Value::from_cycle_error called without errors");
-    }
-}
-
-impl<'tcx, T: Default> Value<'tcx> for T {
-    default fn from_cycle_error<'a>(_: TyCtxt<'a, 'tcx, 'tcx>) -> T {
-        T::default()
-    }
-}
-
-impl<'tcx> Value<'tcx> for Ty<'tcx> {
-    fn from_cycle_error<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
-        tcx.types.err
-    }
-}
-
-impl<'tcx> Value<'tcx> for ty::SymbolName {
-    fn from_cycle_error<'a>(_: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
-        ty::SymbolName { name: Symbol::intern("<error>").as_interned_str() }
-    }
-}
-
index f947ed456862451ed361eac87bc11b993c84c7fd..2758503c60c9a3b98324521a146a7fe941da8594 100644 (file)
@@ -85,7 +85,7 @@
 
 pub use self::trait_def::TraitDef;
 
-pub use self::maps::queries;
+pub use self::query::queries;
 
 pub mod adjustment;
 pub mod binding;
 pub mod item_path;
 pub mod layout;
 pub mod _match;
-pub mod maps;
 pub mod outlives;
+pub mod query;
 pub mod relate;
 pub mod steal;
 pub mod subst;
@@ -2175,7 +2175,7 @@ pub fn destructor(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Destructor> {
     /// Due to normalization being eager, this applies even if
     /// the associated type is behind a pointer, e.g. issue #31299.
     pub fn sized_constraint(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> &'tcx [Ty<'tcx>] {
-        match tcx.try_get_query::<queries::adt_sized_constraint>(DUMMY_SP, self.did) {
+        match tcx.try_adt_sized_constraint(DUMMY_SP, self.did) {
             Ok(tys) => tys,
             Err(mut bug) => {
                 debug!("adt_sized_constraint: {:?} is recursive", self);
@@ -2917,12 +2917,12 @@ fn instance_def_size_estimate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     }
 }
 
-pub fn provide(providers: &mut ty::maps::Providers) {
+pub fn provide(providers: &mut ty::query::Providers) {
     context::provide(providers);
     erase_regions::provide(providers);
     layout::provide(providers);
     util::provide(providers);
-    *providers = ty::maps::Providers {
+    *providers = ty::query::Providers {
         associated_item,
         associated_item_def_ids,
         adt_sized_constraint,
diff --git a/src/librustc/ty/query/README.md b/src/librustc/ty/query/README.md
new file mode 100644 (file)
index 0000000..ca6f0b7
--- /dev/null
@@ -0,0 +1,302 @@
+# The Rust Compiler Query System
+
+The Compiler Query System is the key to our new demand-driven
+organization.  The idea is pretty simple. You have various queries
+that compute things about the input -- for example, there is a query
+called `type_of(def_id)` that, given the def-id of some item, will
+compute the type of that item and return it to you.
+
+Query execution is **memoized** -- so the first time you invoke a
+query, it will go do the computation, but the next time, the result is
+returned from a hashtable. Moreover, query execution fits nicely into
+**incremental computation**; the idea is roughly that, when you do a
+query, the result **may** be returned to you by loading stored data
+from disk (but that's a separate topic we won't discuss further here).
+
+The overall vision is that, eventually, the entire compiler
+control-flow will be query driven. There will effectively be one
+top-level query ("compile") that will run compilation on a crate; this
+will in turn demand information about that crate, starting from the
+*end*.  For example:
+
+- This "compile" query might demand to get a list of codegen-units
+  (i.e., modules that need to be compiled by LLVM).
+- But computing the list of codegen-units would invoke some subquery
+  that returns the list of all modules defined in the Rust source.
+- That query in turn would invoke something asking for the HIR.
+- This keeps going further and further back until we wind up doing the
+  actual parsing.
+
+However, that vision is not fully realized. Still, big chunks of the
+compiler (for example, generating MIR) work exactly like this.
+
+### Invoking queries
+
+To invoke a query is simple. The tcx ("type context") offers a method
+for each defined query. So, for example, to invoke the `type_of`
+query, you would just do this:
+
+```rust
+let ty = tcx.type_of(some_def_id);
+```
+
+### Cycles between queries
+
+Currently, cycles during query execution should always result in a
+compilation error. Typically, they arise because of illegal programs
+that contain cyclic references they shouldn't (though sometimes they
+arise because of compiler bugs, in which case we need to factor our
+queries in a more fine-grained fashion to avoid them).
+
+However, it is nonetheless often useful to *recover* from a cycle
+(after reporting an error, say) and try to soldier on, so as to give a
+better user experience. In order to recover from a cycle, you don't
+get to use the nice method-call-style syntax. Instead, you invoke
+using the `try_get` method, which looks roughly like this:
+
+```rust
+use ty::query::queries;
+...
+match queries::type_of::try_get(tcx, DUMMY_SP, self.did) {
+  Ok(result) => {
+    // no cycle occurred! You can use `result`
+  }
+  Err(err) => {
+    // A cycle occurred! The error value `err` is a `DiagnosticBuilder`,
+    // meaning essentially an "in-progress", not-yet-reported error message.
+    // See below for more details on what to do here.
+  }
+}
+```
+
+So, if you get back an `Err` from `try_get`, then a cycle *did* occur. This means that
+you must ensure that a compiler error message is reported. You can do that in two ways:
+
+The simplest is to invoke `err.emit()`. This will emit the cycle error to the user.
+
+However, often cycles happen because of an illegal program, and you
+know at that point that an error either already has been reported or
+will be reported due to this cycle by some other bit of code. In that
+case, you can invoke `err.cancel()` to not emit any error. It is
+traditional to then invoke:
+
+```
+tcx.sess.delay_span_bug(some_span, "some message")
+```
+
+`delay_span_bug()` is a helper that says: we expect a compilation
+error to have happened or to happen in the future; so, if compilation
+ultimately succeeds, make an ICE with the message `"some
+message"`. This is basically just a precaution in case you are wrong.
+
+### How the compiler executes a query
+
+So you may be wondering what happens when you invoke a query
+method. The answer is that, for each query, the compiler maintains a
+cache -- if your query has already been executed, then, the answer is
+simple: we clone the return value out of the cache and return it
+(therefore, you should try to ensure that the return types of queries
+are cheaply cloneable; insert a `Rc` if necessary).
+
+#### Providers
+
+If, however, the query is *not* in the cache, then the compiler will
+try to find a suitable **provider**. A provider is a function that has
+been defined and linked into the compiler somewhere that contains the
+code to compute the result of the query.
+
+**Providers are defined per-crate.** The compiler maintains,
+internally, a table of providers for every crate, at least
+conceptually. Right now, there are really two sets: the providers for
+queries about the **local crate** (that is, the one being compiled)
+and providers for queries about **external crates** (that is,
+dependencies of the local crate). Note that what determines the crate
+that a query is targeting is not the *kind* of query, but the *key*.
+For example, when you invoke `tcx.type_of(def_id)`, that could be a
+local query or an external query, depending on what crate the `def_id`
+is referring to (see the `self::keys::Key` trait for more information
+on how that works).
+
+Providers always have the same signature:
+
+```rust
+fn provider<'cx, 'tcx>(tcx: TyCtxt<'cx, 'tcx, 'tcx>,
+                       key: QUERY_KEY)
+                       -> QUERY_RESULT
+{
+    ...
+}
+```
+
+Providers take two arguments: the `tcx` and the query key. Note also
+that they take the *global* tcx (i.e., they use the `'tcx` lifetime
+twice), rather than taking a tcx with some active inference context.
+They return the result of the query.
+
+####  How providers are setup
+
+When the tcx is created, it is given the providers by its creator using
+the `Providers` struct. This struct is generate by the macros here, but it
+is basically a big list of function pointers:
+
+```rust
+struct Providers {
+    type_of: for<'cx, 'tcx> fn(TyCtxt<'cx, 'tcx, 'tcx>, DefId) -> Ty<'tcx>,
+    ...
+}
+```
+
+At present, we have one copy of the struct for local crates, and one
+for external crates, though the plan is that we may eventually have
+one per crate.
+
+These `Provider` structs are ultimately created and populated by
+`librustc_driver`, but it does this by distributing the work
+throughout the other `rustc_*` crates. This is done by invoking
+various `provide` functions. These functions tend to look something
+like this:
+
+```rust
+pub fn provide(providers: &mut Providers) {
+    *providers = Providers {
+        type_of,
+        ..*providers
+    };
+}
+```
+
+That is, they take an `&mut Providers` and mutate it in place. Usually
+we use the formulation above just because it looks nice, but you could
+as well do `providers.type_of = type_of`, which would be equivalent.
+(Here, `type_of` would be a top-level function, defined as we saw
+before.) So, if we want to add a provider for some other query,
+let's call it `fubar`, into the crate above, we might modify the `provide()`
+function like so:
+
+```rust
+pub fn provide(providers: &mut Providers) {
+    *providers = Providers {
+        type_of,
+        fubar,
+        ..*providers
+    };
+}
+
+fn fubar<'cx, 'tcx>(tcx: TyCtxt<'cx, 'tcx>, key: DefId) -> Fubar<'tcx> { .. }
+```
+
+NB. Most of the `rustc_*` crates only provide **local
+providers**. Almost all **extern providers** wind up going through the
+`rustc_metadata` crate, which loads the information from the crate
+metadata.  But in some cases there are crates that provide queries for
+*both* local and external crates, in which case they define both a
+`provide` and a `provide_extern` function that `rustc_driver` can
+invoke.
+
+### Adding a new kind of query
+
+So suppose you want to add a new kind of query, how do you do so?
+Well, defining a query takes place in two steps:
+
+1. first, you have to specify the query name and arguments; and then,
+2. you have to supply query providers where needed.
+
+To specify the query name and arguments, you simply add an entry
+to the big macro invocation in `mod.rs`. This will probably have changed
+by the time you read this README, but at present it looks something
+like:
+
+```
+define_queries! { <'tcx>
+    /// Records the type of every item.
+    [] fn type_of: TypeOfItem(DefId) -> Ty<'tcx>,
+
+    ...
+}
+```
+
+Each line of the macro defines one query. The name is broken up like this:
+
+```
+[] fn type_of: TypeOfItem(DefId) -> Ty<'tcx>,
+^^    ^^^^^^^  ^^^^^^^^^^ ^^^^^     ^^^^^^^^
+|     |        |          |         |
+|     |        |          |         result type of query
+|     |        |          query key type
+|     |        dep-node constructor
+|     name of query
+query flags
+```
+
+Let's go over them one by one:
+
+- **Query flags:** these are largely unused right now, but the intention
+  is that we'll be able to customize various aspects of how the query is
+  processed.
+- **Name of query:** the name of the query method
+  (`tcx.type_of(..)`). Also used as the name of a struct
+  (`ty::query::queries::type_of`) that will be generated to represent
+  this query.
+- **Dep-node constructor:** indicates the constructor function that
+  connects this query to incremental compilation. Typically, this is a
+  `DepNode` variant, which can be added by modifying the
+  `define_dep_nodes!` macro invocation in
+  `librustc/dep_graph/dep_node.rs`.
+  - However, sometimes we use a custom function, in which case the
+    name will be in snake case and the function will be defined at the
+    bottom of the file. This is typically used when the query key is
+    not a def-id, or just not the type that the dep-node expects.
+- **Query key type:** the type of the argument to this query.
+  This type must implement the `ty::query::keys::Key` trait, which
+  defines (for example) how to map it to a crate, and so forth.
+- **Result type of query:** the type produced by this query. This type
+  should (a) not use `RefCell` or other interior mutability and (b) be
+  cheaply cloneable. Interning or using `Rc` or `Arc` is recommended for
+  non-trivial data types.
+  - The one exception to those rules is the `ty::steal::Steal` type,
+    which is used to cheaply modify MIR in place. See the definition
+    of `Steal` for more details. New uses of `Steal` should **not** be
+    added without alerting `@rust-lang/compiler`.
+
+So, to add a query:
+
+- Add an entry to `define_queries!` using the format above.
+- Possibly add a corresponding entry to the dep-node macro.
+- Link the provider by modifying the appropriate `provide` method;
+  or add a new one if needed and ensure that `rustc_driver` is invoking it.
+
+#### Query structs and descriptions
+
+For each kind, the `define_queries` macro will generate a "query struct"
+named after the query. This struct is a kind of a place-holder
+describing the query. Each such struct implements the
+`self::config::QueryConfig` trait, which has associated types for the
+key/value of that particular query. Basically the code generated looks something
+like this:
+
+```rust
+// Dummy struct representing a particular kind of query:
+pub struct type_of<'tcx> { phantom: PhantomData<&'tcx ()> }
+
+impl<'tcx> QueryConfig for type_of<'tcx> {
+  type Key = DefId;
+  type Value = Ty<'tcx>;
+}
+```
+
+There is an additional trait that you may wish to implement called
+`self::config::QueryDescription`. This trait is used during cycle
+errors to give a "human readable" name for the query, so that we can
+summarize what was happening when the cycle occurred. Implementing
+this trait is optional if the query key is `DefId`, but if you *don't*
+implement it, you get a pretty generic error ("processing `foo`...").
+You can put new impls into the `config` module. They look something like this:
+
+```rust
+impl<'tcx> QueryDescription for queries::type_of<'tcx> {
+    fn describe(tcx: TyCtxt, key: DefId) -> String {
+        format!("computing the type of `{}`", tcx.item_path_str(key))
+    }
+}
+```
+
diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs
new file mode 100644 (file)
index 0000000..cc00e9a
--- /dev/null
@@ -0,0 +1,801 @@
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use dep_graph::SerializedDepNodeIndex;
+use dep_graph::DepNode;
+use hir::def_id::{CrateNum, DefId, DefIndex};
+use mir::interpret::{GlobalId, ConstValue};
+use traits::query::{CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal};
+use ty::{self, ParamEnvAnd, Ty, TyCtxt};
+use ty::subst::Substs;
+use ty::query::queries;
+use ty::query::Query;
+use ty::query::QueryCache;
+
+use std::hash::Hash;
+use std::fmt::Debug;
+use syntax_pos::symbol::InternedString;
+use rustc_data_structures::sync::Lock;
+use rustc_data_structures::stable_hasher::HashStable;
+use ich::StableHashingContext;
+
+// Query configuration and description traits.
+
+pub trait QueryConfig<'tcx> {
+    const NAME: &'static str;
+
+    type Key: Eq + Hash + Clone + Debug;
+    type Value: Clone + for<'a> HashStable<StableHashingContext<'a>>;
+}
+
+pub(super) trait QueryAccessors<'tcx>: QueryConfig<'tcx> {
+    fn query(key: Self::Key) -> Query<'tcx>;
+
+    // Don't use this method to access query results, instead use the methods on TyCtxt
+    fn query_cache<'a>(tcx: TyCtxt<'a, 'tcx, '_>) -> &'a Lock<QueryCache<'tcx, Self>>;
+
+    fn to_dep_node(tcx: TyCtxt<'_, 'tcx, '_>, key: &Self::Key) -> DepNode;
+
+    // Don't use this method to compute query results, instead use the methods on TyCtxt
+    fn compute(tcx: TyCtxt<'_, 'tcx, '_>, key: Self::Key) -> Self::Value;
+
+    fn handle_cycle_error(tcx: TyCtxt<'_, 'tcx, '_>) -> Self::Value;
+}
+
+pub(super) trait QueryDescription<'tcx>: QueryAccessors<'tcx> {
+    fn describe(tcx: TyCtxt, key: Self::Key) -> String;
+
+    #[inline]
+    fn cache_on_disk(_: Self::Key) -> bool {
+        false
+    }
+
+    fn try_load_from_disk(_: TyCtxt<'_, 'tcx, 'tcx>,
+                          _: SerializedDepNodeIndex)
+                          -> Option<Self::Value> {
+        bug!("QueryDescription::load_from_disk() called for an unsupported query.")
+    }
+}
+
+impl<'tcx, M: QueryAccessors<'tcx, Key=DefId>> QueryDescription<'tcx> for M {
+    default fn describe(tcx: TyCtxt, def_id: DefId) -> String {
+        if !tcx.sess.verbose() {
+            format!("processing `{}`", tcx.item_path_str(def_id))
+        } else {
+            let name = unsafe { ::std::intrinsics::type_name::<M>() };
+            format!("processing `{}` applied to `{:?}`", name, def_id)
+        }
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::normalize_projection_ty<'tcx> {
+    fn describe(
+        _tcx: TyCtxt,
+        goal: CanonicalProjectionGoal<'tcx>,
+    ) -> String {
+        format!("normalizing `{:?}`", goal)
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::dropck_outlives<'tcx> {
+    fn describe(_tcx: TyCtxt, goal: CanonicalTyGoal<'tcx>) -> String {
+        format!("computing dropck types for `{:?}`", goal)
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::normalize_ty_after_erasing_regions<'tcx> {
+    fn describe(_tcx: TyCtxt, goal: ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
+        format!("normalizing `{:?}`", goal)
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::evaluate_obligation<'tcx> {
+    fn describe(_tcx: TyCtxt, goal: CanonicalPredicateGoal<'tcx>) -> String {
+        format!("evaluating trait selection obligation `{}`", goal.value.value)
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::is_copy_raw<'tcx> {
+    fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
+        format!("computing whether `{}` is `Copy`", env.value)
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::is_sized_raw<'tcx> {
+    fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
+        format!("computing whether `{}` is `Sized`", env.value)
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::is_freeze_raw<'tcx> {
+    fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
+        format!("computing whether `{}` is freeze", env.value)
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::needs_drop_raw<'tcx> {
+    fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
+        format!("computing whether `{}` needs drop", env.value)
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::layout_raw<'tcx> {
+    fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
+        format!("computing layout of `{}`", env.value)
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::super_predicates_of<'tcx> {
+    fn describe(tcx: TyCtxt, def_id: DefId) -> String {
+        format!("computing the supertraits of `{}`",
+                tcx.item_path_str(def_id))
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::const_value_to_allocation<'tcx> {
+    fn describe(_tcx: TyCtxt, (val, ty): (ConstValue<'tcx>, Ty<'tcx>)) -> String {
+        format!("converting value `{:?}` ({}) to an allocation", val, ty)
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::erase_regions_ty<'tcx> {
+    fn describe(_tcx: TyCtxt, ty: Ty<'tcx>) -> String {
+        format!("erasing regions from `{:?}`", ty)
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::type_param_predicates<'tcx> {
+    fn describe(tcx: TyCtxt, (_, def_id): (DefId, DefId)) -> String {
+        let id = tcx.hir.as_local_node_id(def_id).unwrap();
+        format!("computing the bounds for type parameter `{}`",
+                tcx.hir.ty_param_name(id))
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::coherent_trait<'tcx> {
+    fn describe(tcx: TyCtxt, def_id: DefId) -> String {
+        format!("coherence checking all impls of trait `{}`",
+                tcx.item_path_str(def_id))
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::upstream_monomorphizations<'tcx> {
+    fn describe(_: TyCtxt, k: CrateNum) -> String {
+        format!("collecting available upstream monomorphizations `{:?}`", k)
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::crate_inherent_impls<'tcx> {
+    fn describe(_: TyCtxt, k: CrateNum) -> String {
+        format!("all inherent impls defined in crate `{:?}`", k)
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::crate_inherent_impls_overlap_check<'tcx> {
+    fn describe(_: TyCtxt, _: CrateNum) -> String {
+        format!("check for overlap between inherent impls defined in this crate")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::crate_variances<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("computing the variances for items in this crate")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::inferred_outlives_crate<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("computing the inferred outlives predicates for items in this crate")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::mir_shims<'tcx> {
+    fn describe(tcx: TyCtxt, def: ty::InstanceDef<'tcx>) -> String {
+        format!("generating MIR shim for `{}`",
+                tcx.item_path_str(def.def_id()))
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::privacy_access_levels<'tcx> {
+    fn describe(_: TyCtxt, _: CrateNum) -> String {
+        format!("privacy access levels")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::typeck_item_bodies<'tcx> {
+    fn describe(_: TyCtxt, _: CrateNum) -> String {
+        format!("type-checking all item bodies")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::reachable_set<'tcx> {
+    fn describe(_: TyCtxt, _: CrateNum) -> String {
+        format!("reachability")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::const_eval<'tcx> {
+    fn describe(tcx: TyCtxt, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) -> String {
+        format!("const-evaluating `{}`", tcx.item_path_str(key.value.instance.def.def_id()))
+    }
+
+    #[inline]
+    fn cache_on_disk(_key: Self::Key) -> bool {
+        true
+    }
+
+    #[inline]
+    fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                              id: SerializedDepNodeIndex)
+                              -> Option<Self::Value> {
+        tcx.queries.on_disk_cache.try_load_query_result(tcx, id).map(Ok)
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::mir_keys<'tcx> {
+    fn describe(_: TyCtxt, _: CrateNum) -> String {
+        format!("getting a list of all mir_keys")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::symbol_name<'tcx> {
+    fn describe(_tcx: TyCtxt, instance: ty::Instance<'tcx>) -> String {
+        format!("computing the symbol for `{}`", instance)
+    }
+
+    #[inline]
+    fn cache_on_disk(_: Self::Key) -> bool {
+        true
+    }
+
+    #[inline]
+    fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                              id: SerializedDepNodeIndex)
+                              -> Option<Self::Value> {
+        tcx.queries.on_disk_cache.try_load_query_result(tcx, id)
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::describe_def<'tcx> {
+    fn describe(_: TyCtxt, _: DefId) -> String {
+        bug!("describe_def")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::def_span<'tcx> {
+    fn describe(_: TyCtxt, _: DefId) -> String {
+        bug!("def_span")
+    }
+}
+
+
+impl<'tcx> QueryDescription<'tcx> for queries::lookup_stability<'tcx> {
+    fn describe(_: TyCtxt, _: DefId) -> String {
+        bug!("stability")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::lookup_deprecation_entry<'tcx> {
+    fn describe(_: TyCtxt, _: DefId) -> String {
+        bug!("deprecation")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::item_attrs<'tcx> {
+    fn describe(_: TyCtxt, _: DefId) -> String {
+        bug!("item_attrs")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::is_reachable_non_generic<'tcx> {
+    fn describe(_: TyCtxt, _: DefId) -> String {
+        bug!("is_reachable_non_generic")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::fn_arg_names<'tcx> {
+    fn describe(_: TyCtxt, _: DefId) -> String {
+        bug!("fn_arg_names")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::impl_parent<'tcx> {
+    fn describe(_: TyCtxt, _: DefId) -> String {
+        bug!("impl_parent")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::trait_of_item<'tcx> {
+    fn describe(_: TyCtxt, _: DefId) -> String {
+        bug!("trait_of_item")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::const_is_rvalue_promotable_to_static<'tcx> {
+    fn describe(tcx: TyCtxt, def_id: DefId) -> String {
+        format!("const checking if rvalue is promotable to static `{}`",
+            tcx.item_path_str(def_id))
+    }
+
+    #[inline]
+    fn cache_on_disk(_: Self::Key) -> bool {
+        true
+    }
+
+    #[inline]
+    fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                          id: SerializedDepNodeIndex)
+                          -> Option<Self::Value> {
+        tcx.queries.on_disk_cache.try_load_query_result(tcx, id)
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::rvalue_promotable_map<'tcx> {
+    fn describe(tcx: TyCtxt, def_id: DefId) -> String {
+        format!("checking which parts of `{}` are promotable to static",
+                tcx.item_path_str(def_id))
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::is_mir_available<'tcx> {
+    fn describe(tcx: TyCtxt, def_id: DefId) -> String {
+        format!("checking if item is mir available: `{}`",
+            tcx.item_path_str(def_id))
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::codegen_fulfill_obligation<'tcx> {
+    fn describe(tcx: TyCtxt, key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)) -> String {
+        format!("checking if `{}` fulfills its obligations", tcx.item_path_str(key.1.def_id()))
+    }
+
+    #[inline]
+    fn cache_on_disk(_: Self::Key) -> bool {
+        true
+    }
+
+    #[inline]
+    fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                              id: SerializedDepNodeIndex)
+                              -> Option<Self::Value> {
+        tcx.queries.on_disk_cache.try_load_query_result(tcx, id)
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::trait_impls_of<'tcx> {
+    fn describe(tcx: TyCtxt, def_id: DefId) -> String {
+        format!("trait impls of `{}`", tcx.item_path_str(def_id))
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::is_object_safe<'tcx> {
+    fn describe(tcx: TyCtxt, def_id: DefId) -> String {
+        format!("determine object safety of trait `{}`", tcx.item_path_str(def_id))
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::is_const_fn<'tcx> {
+    fn describe(tcx: TyCtxt, def_id: DefId) -> String {
+        format!("checking if item is const fn: `{}`", tcx.item_path_str(def_id))
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::dylib_dependency_formats<'tcx> {
+    fn describe(_: TyCtxt, _: CrateNum) -> String {
+        "dylib dependency formats of crate".to_string()
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::is_panic_runtime<'tcx> {
+    fn describe(_: TyCtxt, _: CrateNum) -> String {
+        "checking if the crate is_panic_runtime".to_string()
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::is_compiler_builtins<'tcx> {
+    fn describe(_: TyCtxt, _: CrateNum) -> String {
+        "checking if the crate is_compiler_builtins".to_string()
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::has_global_allocator<'tcx> {
+    fn describe(_: TyCtxt, _: CrateNum) -> String {
+        "checking if the crate has_global_allocator".to_string()
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::extern_crate<'tcx> {
+    fn describe(_: TyCtxt, _: DefId) -> String {
+        "getting crate's ExternCrateData".to_string()
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::lint_levels<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("computing the lint levels for items in this crate")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::specializes<'tcx> {
+    fn describe(_tcx: TyCtxt, _: (DefId, DefId)) -> String {
+        format!("computing whether impls specialize one another")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::in_scope_traits_map<'tcx> {
+    fn describe(_tcx: TyCtxt, _: DefIndex) -> String {
+        format!("traits in scope at a block")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::is_no_builtins<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("test whether a crate has #![no_builtins]")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::panic_strategy<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("query a crate's configured panic strategy")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::is_profiler_runtime<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("query a crate is #![profiler_runtime]")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::is_sanitizer_runtime<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("query a crate is #![sanitizer_runtime]")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::reachable_non_generics<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("looking up the exported symbols of a crate")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::native_libraries<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("looking up the native libraries of a linked crate")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::foreign_modules<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("looking up the foreign modules of a linked crate")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::plugin_registrar_fn<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("looking up the plugin registrar for a crate")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::derive_registrar_fn<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("looking up the derive registrar for a crate")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::crate_disambiguator<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("looking up the disambiguator a crate")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::crate_hash<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("looking up the hash a crate")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::original_crate_name<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("looking up the original name a crate")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::extra_filename<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("looking up the extra filename for a crate")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::implementations_of_trait<'tcx> {
+    fn describe(_tcx: TyCtxt, _: (CrateNum, DefId)) -> String {
+        format!("looking up implementations of a trait in a crate")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::all_trait_implementations<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("looking up all (?) trait implementations")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::link_args<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("looking up link arguments for a crate")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::resolve_lifetimes<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("resolving lifetimes")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::named_region_map<'tcx> {
+    fn describe(_tcx: TyCtxt, _: DefIndex) -> String {
+        format!("looking up a named region")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::is_late_bound_map<'tcx> {
+    fn describe(_tcx: TyCtxt, _: DefIndex) -> String {
+        format!("testing if a region is late bound")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::object_lifetime_defaults_map<'tcx> {
+    fn describe(_tcx: TyCtxt, _: DefIndex) -> String {
+        format!("looking up lifetime defaults for a region")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::dep_kind<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("fetching what a dependency looks like")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::crate_name<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("fetching what a crate is named")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::get_lang_items<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("calculating the lang items map")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::defined_lang_items<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("calculating the lang items defined in a crate")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::missing_lang_items<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("calculating the missing lang items in a crate")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::visible_parent_map<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("calculating the visible parent map")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::missing_extern_crate_item<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("seeing if we're missing an `extern crate` item for this crate")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::used_crate_source<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("looking at the source for a crate")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::postorder_cnums<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("generating a postorder list of CrateNums")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::maybe_unused_extern_crates<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("looking up all possibly unused extern crates")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::stability_index<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("calculating the stability index for the local crate")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::all_traits<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("fetching all foreign and local traits")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::all_crate_nums<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("fetching all foreign CrateNum instances")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::exported_symbols<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("exported_symbols")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::collect_and_partition_mono_items<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("collect_and_partition_mono_items")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::codegen_unit<'tcx> {
+    fn describe(_tcx: TyCtxt, _: InternedString) -> String {
+        format!("codegen_unit")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::compile_codegen_unit<'tcx> {
+    fn describe(_tcx: TyCtxt, _: InternedString) -> String {
+        format!("compile_codegen_unit")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::output_filenames<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("output_filenames")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::vtable_methods<'tcx> {
+    fn describe(tcx: TyCtxt, key: ty::PolyTraitRef<'tcx> ) -> String {
+        format!("finding all methods for trait {}", tcx.item_path_str(key.def_id()))
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::features_query<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("looking up enabled feature gates")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::typeck_tables_of<'tcx> {
+    #[inline]
+    fn cache_on_disk(def_id: Self::Key) -> bool {
+        def_id.is_local()
+    }
+
+    fn try_load_from_disk(tcx: TyCtxt<'_, 'tcx, 'tcx>,
+                          id: SerializedDepNodeIndex)
+                          -> Option<Self::Value> {
+        let typeck_tables: Option<ty::TypeckTables<'tcx>> = tcx
+            .queries.on_disk_cache
+            .try_load_query_result(tcx, id);
+
+        typeck_tables.map(|tables| tcx.alloc_tables(tables))
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::optimized_mir<'tcx> {
+    #[inline]
+    fn cache_on_disk(def_id: Self::Key) -> bool {
+        def_id.is_local()
+    }
+
+    fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                              id: SerializedDepNodeIndex)
+                              -> Option<Self::Value> {
+        let mir: Option<::mir::Mir<'tcx>> = tcx.queries.on_disk_cache
+                                               .try_load_query_result(tcx, id);
+        mir.map(|x| tcx.alloc_mir(x))
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::substitute_normalize_and_test_predicates<'tcx> {
+    fn describe(tcx: TyCtxt, key: (DefId, &'tcx Substs<'tcx>)) -> String {
+        format!("testing substituted normalized predicates:`{}`", tcx.item_path_str(key.0))
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::target_features_whitelist<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("looking up the whitelist of target features")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::instance_def_size_estimate<'tcx> {
+    fn describe(tcx: TyCtxt, def: ty::InstanceDef<'tcx>) -> String {
+        format!("estimating size for `{}`", tcx.item_path_str(def.def_id()))
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::wasm_custom_sections<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("custom wasm sections for a crate")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::generics_of<'tcx> {
+    #[inline]
+    fn cache_on_disk(def_id: Self::Key) -> bool {
+        def_id.is_local()
+    }
+
+    fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                              id: SerializedDepNodeIndex)
+                              -> Option<Self::Value> {
+        let generics: Option<ty::Generics> = tcx.queries.on_disk_cache
+                                                .try_load_query_result(tcx, id);
+        generics.map(|x| tcx.alloc_generics(x))
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::program_clauses_for<'tcx> {
+    fn describe(_tcx: TyCtxt, _: DefId) -> String {
+        format!("generating chalk-style clauses")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::program_clauses_for_env<'tcx> {
+    fn describe(_tcx: TyCtxt, _: ty::ParamEnv<'tcx>) -> String {
+        format!("generating chalk-style clauses for param env")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::wasm_import_module_map<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("wasm import module map")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::dllimport_foreign_items<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("wasm import module map")
+    }
+}
+
+macro_rules! impl_disk_cacheable_query(
+    ($query_name:ident, |$key:tt| $cond:expr) => {
+        impl<'tcx> QueryDescription<'tcx> for queries::$query_name<'tcx> {
+            #[inline]
+            fn cache_on_disk($key: Self::Key) -> bool {
+                $cond
+            }
+
+            #[inline]
+            fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                      id: SerializedDepNodeIndex)
+                                      -> Option<Self::Value> {
+                tcx.queries.on_disk_cache.try_load_query_result(tcx, id)
+            }
+        }
+    }
+);
+
+impl_disk_cacheable_query!(unsafety_check_result, |def_id| def_id.is_local());
+impl_disk_cacheable_query!(borrowck, |def_id| def_id.is_local());
+impl_disk_cacheable_query!(mir_borrowck, |def_id| def_id.is_local());
+impl_disk_cacheable_query!(mir_const_qualif, |def_id| def_id.is_local());
+impl_disk_cacheable_query!(check_match, |def_id| def_id.is_local());
+impl_disk_cacheable_query!(def_symbol_name, |_| true);
+impl_disk_cacheable_query!(type_of, |def_id| def_id.is_local());
+impl_disk_cacheable_query!(predicates_of, |def_id| def_id.is_local());
+impl_disk_cacheable_query!(used_trait_imports, |def_id| def_id.is_local());
+impl_disk_cacheable_query!(codegen_fn_attrs, |_| true);
+impl_disk_cacheable_query!(specialization_graph_of, |_| true);
diff --git a/src/librustc/ty/query/job.rs b/src/librustc/ty/query/job.rs
new file mode 100644 (file)
index 0000000..a54deec
--- /dev/null
@@ -0,0 +1,525 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(warnings)]
+
+use std::mem;
+use rustc_data_structures::sync::{Lock, LockGuard, Lrc, Weak};
+use rustc_data_structures::OnDrop;
+use syntax_pos::Span;
+use ty::tls;
+use ty::query::Query;
+use ty::query::plumbing::CycleError;
+use ty::context::TyCtxt;
+use errors::Diagnostic;
+use std::process;
+use std::fmt;
+use std::collections::HashSet;
+#[cfg(parallel_queries)]
+use {
+    rayon_core,
+    parking_lot::{Mutex, Condvar},
+    std::sync::atomic::Ordering,
+    std::thread,
+    std::iter,
+    std::iter::FromIterator,
+    syntax_pos::DUMMY_SP,
+    rustc_data_structures::stable_hasher::{StableHasherResult, StableHasher, HashStable},
+};
+
+/// Indicates the state of a query for a given key in a query map
+pub(super) enum QueryResult<'tcx> {
+    /// An already executing query. The query job can be used to await for its completion
+    Started(Lrc<QueryJob<'tcx>>),
+
+    /// The query panicked. Queries trying to wait on this will raise a fatal error / silently panic
+    Poisoned,
+}
+
+/// A span and a query key
+#[derive(Clone, Debug)]
+pub struct QueryInfo<'tcx> {
+    /// The span for a reason this query was required
+    pub span: Span,
+    pub query: Query<'tcx>,
+}
+
+/// A object representing an active query job.
+pub struct QueryJob<'tcx> {
+    pub info: QueryInfo<'tcx>,
+
+    /// The parent query job which created this job and is implicitly waiting on it.
+    pub parent: Option<Lrc<QueryJob<'tcx>>>,
+
+    /// Diagnostic messages which are emitted while the query executes
+    pub diagnostics: Lock<Vec<Diagnostic>>,
+
+    /// The latch which is used to wait on this job
+    #[cfg(parallel_queries)]
+    latch: QueryLatch<'tcx>,
+}
+
+impl<'tcx> QueryJob<'tcx> {
+    /// Creates a new query job
+    pub fn new(info: QueryInfo<'tcx>, parent: Option<Lrc<QueryJob<'tcx>>>) -> Self {
+        QueryJob {
+            diagnostics: Lock::new(Vec::new()),
+            info,
+            parent,
+            #[cfg(parallel_queries)]
+            latch: QueryLatch::new(),
+        }
+    }
+
+    /// Awaits for the query job to complete.
+    ///
+    /// For single threaded rustc there's no concurrent jobs running, so if we are waiting for any
+    /// query that means that there is a query cycle, thus this always running a cycle error.
+    pub(super) fn await<'lcx>(
+        &self,
+        tcx: TyCtxt<'_, 'tcx, 'lcx>,
+        span: Span,
+    ) -> Result<(), CycleError<'tcx>> {
+        #[cfg(not(parallel_queries))]
+        {
+            self.find_cycle_in_stack(tcx, span)
+        }
+
+        #[cfg(parallel_queries)]
+        {
+            tls::with_related_context(tcx, move |icx| {
+                let mut waiter = Lrc::new(QueryWaiter {
+                    query: icx.query.clone(),
+                    span,
+                    cycle: Lock::new(None),
+                    condvar: Condvar::new(),
+                });
+                self.latch.await(&waiter);
+
+                match Lrc::get_mut(&mut waiter).unwrap().cycle.get_mut().take() {
+                    None => Ok(()),
+                    Some(cycle) => Err(cycle)
+                }
+            })
+        }
+    }
+
+    #[cfg(not(parallel_queries))]
+    fn find_cycle_in_stack<'lcx>(
+        &self,
+        tcx: TyCtxt<'_, 'tcx, 'lcx>,
+        span: Span,
+    ) -> Result<(), CycleError<'tcx>> {
+        // Get the current executing query (waiter) and find the waitee amongst its parents
+        let mut current_job = tls::with_related_context(tcx, |icx| icx.query.clone());
+        let mut cycle = Vec::new();
+
+        while let Some(job) = current_job {
+            cycle.insert(0, job.info.clone());
+
+            if &*job as *const _ == self as *const _ {
+                // This is the end of the cycle
+                // The span entry we included was for the usage
+                // of the cycle itself, and not part of the cycle
+                // Replace it with the span which caused the cycle to form
+                cycle[0].span = span;
+                // Find out why the cycle itself was used
+                let usage = job.parent.as_ref().map(|parent| {
+                    (job.info.span, parent.info.query.clone())
+                });
+                return Err(CycleError { usage, cycle });
+            }
+
+            current_job = job.parent.clone();
+        }
+
+        panic!("did not find a cycle")
+    }
+
+    /// Signals to waiters that the query is complete.
+    ///
+    /// This does nothing for single threaded rustc,
+    /// as there are no concurrent jobs which could be waiting on us
+    pub fn signal_complete(&self) {
+        #[cfg(parallel_queries)]
+        self.latch.set();
+    }
+
+    fn as_ptr(&self) -> *const QueryJob<'tcx> {
+        self as *const _
+    }
+}
+
+#[cfg(parallel_queries)]
+struct QueryWaiter<'tcx> {
+    query: Option<Lrc<QueryJob<'tcx>>>,
+    condvar: Condvar,
+    span: Span,
+    cycle: Lock<Option<CycleError<'tcx>>>,
+}
+
+#[cfg(parallel_queries)]
+impl<'tcx> QueryWaiter<'tcx> {
+    fn notify(&self, registry: &rayon_core::Registry) {
+        rayon_core::mark_unblocked(registry);
+        self.condvar.notify_one();
+    }
+}
+
+#[cfg(parallel_queries)]
+struct QueryLatchInfo<'tcx> {
+    complete: bool,
+    waiters: Vec<Lrc<QueryWaiter<'tcx>>>,
+}
+
+#[cfg(parallel_queries)]
+struct QueryLatch<'tcx> {
+    info: Mutex<QueryLatchInfo<'tcx>>,
+}
+
+#[cfg(parallel_queries)]
+impl<'tcx> QueryLatch<'tcx> {
+    fn new() -> Self {
+        QueryLatch {
+            info: Mutex::new(QueryLatchInfo {
+                complete: false,
+                waiters: Vec::new(),
+            }),
+        }
+    }
+
+    /// Awaits the caller on this latch by blocking the current thread.
+    fn await(&self, waiter: &Lrc<QueryWaiter<'tcx>>) {
+        let mut info = self.info.lock();
+        if !info.complete {
+            // We push the waiter on to the `waiters` list. It can be accessed inside
+            // the `wait` call below, by 1) the `set` method or 2) by deadlock detection.
+            // Both of these will remove it from the `waiters` list before resuming
+            // this thread.
+            info.waiters.push(waiter.clone());
+
+            // If this detects a deadlock and the deadlock handler wants to resume this thread
+            // we have to be in the `wait` call. This is ensured by the deadlock handler
+            // getting the self.info lock.
+            rayon_core::mark_blocked();
+            waiter.condvar.wait(&mut info);
+        }
+    }
+
+    /// Sets the latch and resumes all waiters on it
+    fn set(&self) {
+        let mut info = self.info.lock();
+        debug_assert!(!info.complete);
+        info.complete = true;
+        let registry = rayon_core::Registry::current();
+        for waiter in info.waiters.drain(..) {
+            waiter.notify(&registry);
+        }
+    }
+
+    /// Remove a single waiter from the list of waiters.
+    /// This is used to break query cycles.
+    fn extract_waiter(
+        &self,
+        waiter: usize,
+    ) -> Lrc<QueryWaiter<'tcx>> {
+        let mut info = self.info.lock();
+        debug_assert!(!info.complete);
+        // Remove the waiter from the list of waiters
+        info.waiters.remove(waiter)
+    }
+}
+
+/// A resumable waiter of a query. The usize is the index into waiters in the query's latch
+#[cfg(parallel_queries)]
+type Waiter<'tcx> = (Lrc<QueryJob<'tcx>>, usize);
+
+/// Visits all the non-resumable and resumable waiters of a query.
+/// Only waiters in a query are visited.
+/// `visit` is called for every waiter and is passed a query waiting on `query_ref`
+/// and a span indicating the reason the query waited on `query_ref`.
+/// If `visit` returns Some, this function returns.
+/// For visits of non-resumable waiters it returns the return value of `visit`.
+/// For visits of resumable waiters it returns Some(Some(Waiter)) which has the
+/// required information to resume the waiter.
+/// If all `visit` calls returns None, this function also returns None.
+#[cfg(parallel_queries)]
+fn visit_waiters<'tcx, F>(query: Lrc<QueryJob<'tcx>>, mut visit: F) -> Option<Option<Waiter<'tcx>>>
+where
+    F: FnMut(Span, Lrc<QueryJob<'tcx>>) -> Option<Option<Waiter<'tcx>>>
+{
+    // Visit the parent query which is a non-resumable waiter since it's on the same stack
+    if let Some(ref parent) = query.parent {
+        if let Some(cycle) = visit(query.info.span, parent.clone()) {
+            return Some(cycle);
+        }
+    }
+
+    // Visit the explict waiters which use condvars and are resumable
+    for (i, waiter) in query.latch.info.lock().waiters.iter().enumerate() {
+        if let Some(ref waiter_query) = waiter.query {
+            if visit(waiter.span, waiter_query.clone()).is_some() {
+                // Return a value which indicates that this waiter can be resumed
+                return Some(Some((query.clone(), i)));
+            }
+        }
+    }
+    None
+}
+
+/// Look for query cycles by doing a depth first search starting at `query`.
+/// `span` is the reason for the `query` to execute. This is initially DUMMY_SP.
+/// If a cycle is detected, this initial value is replaced with the span causing
+/// the cycle.
+#[cfg(parallel_queries)]
+fn cycle_check<'tcx>(query: Lrc<QueryJob<'tcx>>,
+                     span: Span,
+                     stack: &mut Vec<(Span, Lrc<QueryJob<'tcx>>)>,
+                     visited: &mut HashSet<*const QueryJob<'tcx>>
+) -> Option<Option<Waiter<'tcx>>> {
+    if visited.contains(&query.as_ptr()) {
+        return if let Some(p) = stack.iter().position(|q| q.1.as_ptr() == query.as_ptr()) {
+            // We detected a query cycle, fix up the initial span and return Some
+
+            // Remove previous stack entries
+            stack.splice(0..p, iter::empty());
+            // Replace the span for the first query with the cycle cause
+            stack[0].0 = span;
+            Some(None)
+        } else {
+            None
+        }
+    }
+
+    // Mark this query is visited and add it to the stack
+    visited.insert(query.as_ptr());
+    stack.push((span, query.clone()));
+
+    // Visit all the waiters
+    let r = visit_waiters(query, |span, successor| {
+        cycle_check(successor, span, stack, visited)
+    });
+
+    // Remove the entry in our stack if we didn't find a cycle
+    if r.is_none() {
+        stack.pop();
+    }
+
+    r
+}
+
+/// Finds out if there's a path to the compiler root (aka. code which isn't in a query)
+/// from `query` without going through any of the queries in `visited`.
+/// This is achieved with a depth first search.
+#[cfg(parallel_queries)]
+fn connected_to_root<'tcx>(
+    query: Lrc<QueryJob<'tcx>>,
+    visited: &mut HashSet<*const QueryJob<'tcx>>
+) -> bool {
+    // We already visited this or we're deliberately ignoring it
+    if visited.contains(&query.as_ptr()) {
+        return false;
+    }
+
+    // This query is connected to the root (it has no query parent), return true
+    if query.parent.is_none() {
+        return true;
+    }
+
+    visited.insert(query.as_ptr());
+
+    let mut connected = false;
+
+    visit_waiters(query, |_, successor| {
+        if connected_to_root(successor, visited) {
+            Some(None)
+        } else {
+            None
+        }
+    }).is_some()
+}
+
+/// Looks for query cycles starting from the last query in `jobs`.
+/// If a cycle is found, all queries in the cycle is removed from `jobs` and
+/// the function return true.
+/// If a cycle was not found, the starting query is removed from `jobs` and
+/// the function returns false.
+#[cfg(parallel_queries)]
+fn remove_cycle<'tcx>(
+    jobs: &mut Vec<Lrc<QueryJob<'tcx>>>,
+    wakelist: &mut Vec<Lrc<QueryWaiter<'tcx>>>,
+    tcx: TyCtxt<'_, 'tcx, '_>
+) -> bool {
+    let mut visited = HashSet::new();
+    let mut stack = Vec::new();
+    // Look for a cycle starting with the last query in `jobs`
+    if let Some(waiter) = cycle_check(jobs.pop().unwrap(),
+                                      DUMMY_SP,
+                                      &mut stack,
+                                      &mut visited) {
+        // Reverse the stack so earlier entries require later entries
+        stack.reverse();
+
+        // Extract the spans and queries into separate arrays
+        let mut spans: Vec<_> = stack.iter().map(|e| e.0).collect();
+        let queries = stack.into_iter().map(|e| e.1);
+
+        // Shift the spans so that queries are matched with the span for their waitee
+        let last = spans.pop().unwrap();
+        spans.insert(0, last);
+
+        // Zip them back together
+        let mut stack: Vec<_> = spans.into_iter().zip(queries).collect();
+
+        // Remove the queries in our cycle from the list of jobs to look at
+        for r in &stack {
+            if let Some(pos) = jobs.iter().position(|j| j.as_ptr() == r.1.as_ptr()) {
+                jobs.remove(pos);
+            }
+        }
+
+        // Find the queries in the cycle which are
+        // connected to queries outside the cycle
+        let entry_points: Vec<Lrc<QueryJob<'tcx>>> = stack.iter().filter_map(|query| {
+            // Mark all the other queries in the cycle as already visited
+            let mut visited = HashSet::from_iter(stack.iter().filter_map(|q| {
+                if q.1.as_ptr() != query.1.as_ptr() {
+                    Some(q.1.as_ptr())
+                } else {
+                    None
+                }
+            }));
+
+            if connected_to_root(query.1.clone(), &mut visited) {
+                Some(query.1.clone())
+            } else {
+                None
+            }
+        }).collect();
+
+        // Deterministically pick an entry point
+        // FIXME: Sort this instead
+        let mut hcx = tcx.create_stable_hashing_context();
+        let entry_point = entry_points.iter().min_by_key(|q| {
+            let mut stable_hasher = StableHasher::<u64>::new();
+            q.info.query.hash_stable(&mut hcx, &mut stable_hasher);
+            stable_hasher.finish()
+        }).unwrap().as_ptr();
+
+        // Shift the stack until our entry point is first
+        while stack[0].1.as_ptr() != entry_point {
+            let last = stack.pop().unwrap();
+            stack.insert(0, last);
+        }
+
+        // Create the cycle error
+        let mut error = CycleError {
+            usage: None,
+            cycle: stack.iter().map(|&(s, ref q)| QueryInfo {
+                span: s,
+                query: q.info.query.clone(),
+            } ).collect(),
+        };
+
+        // We unwrap `waiter` here since there must always be one
+        // edge which is resumeable / waited using a query latch
+        let (waitee_query, waiter_idx) = waiter.unwrap();
+
+        // Extract the waiter we want to resume
+        let waiter = waitee_query.latch.extract_waiter(waiter_idx);
+
+        // Set the cycle error so it will be picked up when resumed
+        *waiter.cycle.lock() = Some(error);
+
+        // Put the waiter on the list of things to resume
+        wakelist.push(waiter);
+
+        true
+    } else {
+        false
+    }
+}
+
+/// Creates a new thread and forwards information in thread locals to it.
+/// The new thread runs the deadlock handler.
+/// Must only be called when a deadlock is about to happen.
+#[cfg(parallel_queries)]
+pub unsafe fn handle_deadlock() {
+    use syntax;
+    use syntax_pos;
+
+    let registry = rayon_core::Registry::current();
+
+    let gcx_ptr = tls::GCX_PTR.with(|gcx_ptr| {
+        gcx_ptr as *const _
+    });
+    let gcx_ptr = &*gcx_ptr;
+
+    let syntax_globals = syntax::GLOBALS.with(|syntax_globals| {
+        syntax_globals as *const _
+    });
+    let syntax_globals = &*syntax_globals;
+
+    let syntax_pos_globals = syntax_pos::GLOBALS.with(|syntax_pos_globals| {
+        syntax_pos_globals as *const _
+    });
+    let syntax_pos_globals = &*syntax_pos_globals;
+    thread::spawn(move || {
+        tls::GCX_PTR.set(gcx_ptr, || {
+            syntax_pos::GLOBALS.set(syntax_pos_globals, || {
+                syntax_pos::GLOBALS.set(syntax_pos_globals, || {
+                    tls::with_thread_locals(|| {
+                        tls::with_global(|tcx| deadlock(tcx, &registry))
+                    })
+                })
+            })
+        })
+    });
+}
+
+/// Detects query cycles by using depth first search over all active query jobs.
+/// If a query cycle is found it will break the cycle by finding an edge which
+/// uses a query latch and then resuming that waiter.
+/// There may be multiple cycles involved in a deadlock, so this searches
+/// all active queries for cycles before finally resuming all the waiters at once.
+#[cfg(parallel_queries)]
+fn deadlock(tcx: TyCtxt<'_, '_, '_>, registry: &rayon_core::Registry) {
+    let on_panic = OnDrop(|| {
+        eprintln!("deadlock handler panicked, aborting process");
+        process::abort();
+    });
+
+    let mut wakelist = Vec::new();
+    let mut jobs: Vec<_> = tcx.queries.collect_active_jobs();
+
+    let mut found_cycle = false;
+
+    while jobs.len() > 0 {
+        if remove_cycle(&mut jobs, &mut wakelist, tcx) {
+            found_cycle = true;
+        }
+    }
+
+    // Check that a cycle was found. It is possible for a deadlock to occur without
+    // a query cycle if a query which can be waited on uses Rayon to do multithreading
+    // internally. Such a query (X) may be executing on 2 threads (A and B) and A may
+    // wait using Rayon on B. Rayon may then switch to executing another query (Y)
+    // which in turn will wait on X causing a deadlock. We have a false dependency from
+    // X to Y due to Rayon waiting and a true dependency from Y to X. The algorithm here
+    // only considers the true dependency and won't detect a cycle.
+    assert!(found_cycle);
+
+    // FIXME: Ensure this won't cause a deadlock before we return
+    for waiter in wakelist.into_iter() {
+        waiter.notify(registry);
+    }
+
+    on_panic.disable();
+}
diff --git a/src/librustc/ty/query/keys.rs b/src/librustc/ty/query/keys.rs
new file mode 100644 (file)
index 0000000..279d5eb
--- /dev/null
@@ -0,0 +1,221 @@
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Defines the set of legal keys that can be used in queries.
+
+use hir::def_id::{CrateNum, DefId, LOCAL_CRATE, DefIndex};
+use traits::query::{CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal};
+use ty::{self, Ty, TyCtxt};
+use ty::subst::Substs;
+use ty::fast_reject::SimplifiedType;
+use mir;
+
+use std::fmt::Debug;
+use std::hash::Hash;
+use syntax_pos::{Span, DUMMY_SP};
+use syntax_pos::symbol::InternedString;
+
+/// The `Key` trait controls what types can legally be used as the key
+/// for a query.
+pub(super) trait Key: Clone + Hash + Eq + Debug {
+    /// Given an instance of this key, what crate is it referring to?
+    /// This is used to find the provider.
+    fn query_crate(&self) -> CrateNum;
+
+    /// In the event that a cycle occurs, if no explicit span has been
+    /// given for a query with key `self`, what span should we use?
+    fn default_span(&self, tcx: TyCtxt) -> Span;
+}
+
+impl<'tcx> Key for ty::InstanceDef<'tcx> {
+    fn query_crate(&self) -> CrateNum {
+        LOCAL_CRATE
+    }
+
+    fn default_span(&self, tcx: TyCtxt) -> Span {
+        tcx.def_span(self.def_id())
+    }
+}
+
+impl<'tcx> Key for ty::Instance<'tcx> {
+    fn query_crate(&self) -> CrateNum {
+        LOCAL_CRATE
+    }
+
+    fn default_span(&self, tcx: TyCtxt) -> Span {
+        tcx.def_span(self.def_id())
+    }
+}
+
+impl<'tcx> Key for mir::interpret::GlobalId<'tcx> {
+    fn query_crate(&self) -> CrateNum {
+        self.instance.query_crate()
+    }
+
+    fn default_span(&self, tcx: TyCtxt) -> Span {
+        self.instance.default_span(tcx)
+    }
+}
+
+impl Key for CrateNum {
+    fn query_crate(&self) -> CrateNum {
+        *self
+    }
+    fn default_span(&self, _: TyCtxt) -> Span {
+        DUMMY_SP
+    }
+}
+
+impl Key for DefIndex {
+    fn query_crate(&self) -> CrateNum {
+        LOCAL_CRATE
+    }
+    fn default_span(&self, _tcx: TyCtxt) -> Span {
+        DUMMY_SP
+    }
+}
+
+impl Key for DefId {
+    fn query_crate(&self) -> CrateNum {
+        self.krate
+    }
+    fn default_span(&self, tcx: TyCtxt) -> Span {
+        tcx.def_span(*self)
+    }
+}
+
+impl Key for (DefId, DefId) {
+    fn query_crate(&self) -> CrateNum {
+        self.0.krate
+    }
+    fn default_span(&self, tcx: TyCtxt) -> Span {
+        self.1.default_span(tcx)
+    }
+}
+
+impl Key for (CrateNum, DefId) {
+    fn query_crate(&self) -> CrateNum {
+        self.0
+    }
+    fn default_span(&self, tcx: TyCtxt) -> Span {
+        self.1.default_span(tcx)
+    }
+}
+
+impl Key for (DefId, SimplifiedType) {
+    fn query_crate(&self) -> CrateNum {
+        self.0.krate
+    }
+    fn default_span(&self, tcx: TyCtxt) -> Span {
+        self.0.default_span(tcx)
+    }
+}
+
+impl<'tcx> Key for (DefId, &'tcx Substs<'tcx>) {
+    fn query_crate(&self) -> CrateNum {
+        self.0.krate
+    }
+    fn default_span(&self, tcx: TyCtxt) -> Span {
+        self.0.default_span(tcx)
+    }
+}
+
+impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) {
+    fn query_crate(&self) -> CrateNum {
+        self.1.def_id().krate
+    }
+    fn default_span(&self, tcx: TyCtxt) -> Span {
+        tcx.def_span(self.1.def_id())
+    }
+}
+
+impl<'tcx> Key for ty::PolyTraitRef<'tcx>{
+    fn query_crate(&self) -> CrateNum {
+        self.def_id().krate
+    }
+    fn default_span(&self, tcx: TyCtxt) -> Span {
+        tcx.def_span(self.def_id())
+    }
+}
+
+impl<'tcx> Key for (mir::interpret::ConstValue<'tcx>, Ty<'tcx>) {
+    fn query_crate(&self) -> CrateNum {
+        LOCAL_CRATE
+    }
+    fn default_span(&self, _: TyCtxt) -> Span {
+        DUMMY_SP
+    }
+}
+
+impl<'tcx> Key for Ty<'tcx> {
+    fn query_crate(&self) -> CrateNum {
+        LOCAL_CRATE
+    }
+    fn default_span(&self, _: TyCtxt) -> Span {
+        DUMMY_SP
+    }
+}
+
+impl<'tcx> Key for ty::ParamEnv<'tcx> {
+    fn query_crate(&self) -> CrateNum {
+        LOCAL_CRATE
+    }
+    fn default_span(&self, _: TyCtxt) -> Span {
+        DUMMY_SP
+    }
+}
+
+impl<'tcx, T: Key> Key for ty::ParamEnvAnd<'tcx, T> {
+    fn query_crate(&self) -> CrateNum {
+        self.value.query_crate()
+    }
+    fn default_span(&self, tcx: TyCtxt) -> Span {
+        self.value.default_span(tcx)
+    }
+}
+
+impl Key for InternedString {
+    fn query_crate(&self) -> CrateNum {
+        LOCAL_CRATE
+    }
+    fn default_span(&self, _tcx: TyCtxt) -> Span {
+        DUMMY_SP
+    }
+}
+
+impl<'tcx> Key for CanonicalProjectionGoal<'tcx> {
+    fn query_crate(&self) -> CrateNum {
+        LOCAL_CRATE
+    }
+
+    fn default_span(&self, _tcx: TyCtxt) -> Span {
+        DUMMY_SP
+    }
+}
+
+impl<'tcx> Key for CanonicalTyGoal<'tcx> {
+    fn query_crate(&self) -> CrateNum {
+        LOCAL_CRATE
+    }
+
+    fn default_span(&self, _tcx: TyCtxt) -> Span {
+        DUMMY_SP
+    }
+}
+
+impl<'tcx> Key for CanonicalPredicateGoal<'tcx> {
+    fn query_crate(&self) -> CrateNum {
+        LOCAL_CRATE
+    }
+
+    fn default_span(&self, _tcx: TyCtxt) -> Span {
+        DUMMY_SP
+    }
+}
diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs
new file mode 100644 (file)
index 0000000..f19bc01
--- /dev/null
@@ -0,0 +1,667 @@
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use dep_graph::{DepConstructor, DepNode};
+use errors::DiagnosticBuilder;
+use hir::def_id::{CrateNum, DefId, DefIndex};
+use hir::def::{Def, Export};
+use hir::{self, TraitCandidate, ItemLocalId, CodegenFnAttrs};
+use hir::svh::Svh;
+use infer::canonical::{self, Canonical};
+use lint;
+use middle::borrowck::BorrowCheckResult;
+use middle::cstore::{ExternCrate, LinkagePreference, NativeLibrary, ForeignModule};
+use middle::cstore::{NativeLibraryKind, DepKind, CrateSource};
+use middle::privacy::AccessLevels;
+use middle::reachable::ReachableSet;
+use middle::region;
+use middle::resolve_lifetime::{ResolveLifetimes, Region, ObjectLifetimeDefault};
+use middle::stability::{self, DeprecationEntry};
+use middle::lang_items::{LanguageItems, LangItem};
+use middle::exported_symbols::{SymbolExportLevel, ExportedSymbol};
+use middle::const_val::EvalResult;
+use mir::mono::{CodegenUnit, Stats};
+use mir;
+use mir::interpret::{GlobalId, Allocation, ConstValue};
+use session::{CompileResult, CrateDisambiguator};
+use session::config::OutputFilenames;
+use traits::{self, Vtable};
+use traits::query::{CanonicalPredicateGoal, CanonicalProjectionGoal,
+                    CanonicalTyGoal, NoSolution};
+use traits::query::dropck_outlives::{DtorckConstraint, DropckOutlivesResult};
+use traits::query::normalize::NormalizationResult;
+use traits::specialization_graph;
+use traits::Clauses;
+use ty::{self, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt};
+use ty::steal::Steal;
+use ty::subst::Substs;
+use util::nodemap::{DefIdSet, DefIdMap, ItemLocalSet};
+use util::common::{ErrorReported};
+
+use rustc_data_structures::indexed_set::IdxSetBuf;
+use rustc_target::spec::PanicStrategy;
+use rustc_data_structures::indexed_vec::IndexVec;
+use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::stable_hasher::StableVec;
+
+use std::ops::Deref;
+use rustc_data_structures::sync::Lrc;
+use std::sync::Arc;
+use syntax_pos::{Span, DUMMY_SP};
+use syntax_pos::symbol::InternedString;
+use syntax::attr;
+use syntax::ast;
+use syntax::feature_gate;
+use syntax::symbol::Symbol;
+
+#[macro_use]
+mod plumbing;
+use self::plumbing::*;
+pub use self::plumbing::{force_from_dep_node, CycleError};
+
+mod job;
+pub use self::job::{QueryJob, QueryInfo};
+#[cfg(parallel_queries)]
+pub use self::job::handle_deadlock;
+
+mod keys;
+use self::keys::Key;
+
+mod values;
+use self::values::Value;
+
+mod config;
+pub use self::config::QueryConfig;
+use self::config::{QueryAccessors, QueryDescription};
+
+mod on_disk_cache;
+pub use self::on_disk_cache::OnDiskCache;
+
+// Each of these quries corresponds to a function pointer field in the
+// `Providers` struct for requesting a value of that type, and a method
+// on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
+// which memoizes and does dep-graph tracking, wrapping around the actual
+// `Providers` that the driver creates (using several `rustc_*` crates).
+//
+// The result type of each query must implement `Clone`, and additionally
+// `ty::query::values::Value`, which produces an appropriate placeholder
+// (error) value if the query resulted in a query cycle.
+// Queries marked with `fatal_cycle` do not need the latter implementation,
+// as they will raise an fatal error on query cycles instead.
+define_queries! { <'tcx>
+    /// Records the type of every item.
+    [] fn type_of: TypeOfItem(DefId) -> Ty<'tcx>,
+
+    /// Maps from the def-id of an item (trait/struct/enum/fn) to its
+    /// associated generics and predicates.
+    [] fn generics_of: GenericsOfItem(DefId) -> &'tcx ty::Generics,
+    [] fn predicates_of: PredicatesOfItem(DefId) -> ty::GenericPredicates<'tcx>,
+    [] fn explicit_predicates_of: ExplicitPredicatesOfItem(DefId) -> ty::GenericPredicates<'tcx>,
+
+    /// Maps from the def-id of a trait to the list of
+    /// super-predicates. This is a subset of the full list of
+    /// predicates. We store these in a separate map because we must
+    /// evaluate them even during type conversion, often before the
+    /// full predicates are available (note that supertraits have
+    /// additional acyclicity requirements).
+    [] fn super_predicates_of: SuperPredicatesOfItem(DefId) -> ty::GenericPredicates<'tcx>,
+
+    /// To avoid cycles within the predicates of a single item we compute
+    /// per-type-parameter predicates for resolving `T::AssocTy`.
+    [] fn type_param_predicates: type_param_predicates((DefId, DefId))
+        -> ty::GenericPredicates<'tcx>,
+
+    [] fn trait_def: TraitDefOfItem(DefId) -> &'tcx ty::TraitDef,
+    [] fn adt_def: AdtDefOfItem(DefId) -> &'tcx ty::AdtDef,
+    [] fn adt_destructor: AdtDestructor(DefId) -> Option<ty::Destructor>,
+    [] fn adt_sized_constraint: SizedConstraint(DefId) -> &'tcx [Ty<'tcx>],
+    [] fn adt_dtorck_constraint: DtorckConstraint(
+        DefId
+    ) -> Result<DtorckConstraint<'tcx>, NoSolution>,
+
+    /// True if this is a const fn
+    [] fn is_const_fn: IsConstFn(DefId) -> bool,
+
+    /// True if this is a foreign item (i.e., linked via `extern { ... }`).
+    [] fn is_foreign_item: IsForeignItem(DefId) -> bool,
+
+    /// Get a map with the variance of every item; use `item_variance`
+    /// instead.
+    [] fn crate_variances: crate_variances(CrateNum) -> Lrc<ty::CrateVariancesMap>,
+
+    /// Maps from def-id of a type or region parameter to its
+    /// (inferred) variance.
+    [] fn variances_of: ItemVariances(DefId) -> Lrc<Vec<ty::Variance>>,
+
+    /// Maps from def-id of a type to its (inferred) outlives.
+    [] fn inferred_outlives_of: InferredOutlivesOf(DefId) -> Lrc<Vec<ty::Predicate<'tcx>>>,
+
+    /// Maps from def-id of a type to its (inferred) outlives.
+    [] fn inferred_outlives_crate: InferredOutlivesCrate(CrateNum)
+        -> Lrc<ty::CratePredicatesMap<'tcx>>,
+
+    /// Maps from an impl/trait def-id to a list of the def-ids of its items
+    [] fn associated_item_def_ids: AssociatedItemDefIds(DefId) -> Lrc<Vec<DefId>>,
+
+    /// Maps from a trait item to the trait item "descriptor"
+    [] fn associated_item: AssociatedItems(DefId) -> ty::AssociatedItem,
+
+    [] fn impl_trait_ref: ImplTraitRef(DefId) -> Option<ty::TraitRef<'tcx>>,
+    [] fn impl_polarity: ImplPolarity(DefId) -> hir::ImplPolarity,
+
+    /// Maps a DefId of a type to a list of its inherent impls.
+    /// Contains implementations of methods that are inherent to a type.
+    /// Methods in these implementations don't need to be exported.
+    [] fn inherent_impls: InherentImpls(DefId) -> Lrc<Vec<DefId>>,
+
+    /// Set of all the def-ids in this crate that have MIR associated with
+    /// them. This includes all the body owners, but also things like struct
+    /// constructors.
+    [] fn mir_keys: mir_keys(CrateNum) -> Lrc<DefIdSet>,
+
+    /// Maps DefId's that have an associated Mir to the result
+    /// of the MIR qualify_consts pass. The actual meaning of
+    /// the value isn't known except to the pass itself.
+    [] fn mir_const_qualif: MirConstQualif(DefId) -> (u8, Lrc<IdxSetBuf<mir::Local>>),
+
+    /// Fetch the MIR for a given def-id right after it's built - this includes
+    /// unreachable code.
+    [] fn mir_built: MirBuilt(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
+
+    /// Fetch the MIR for a given def-id up till the point where it is
+    /// ready for const evaluation.
+    ///
+    /// See the README for the `mir` module for details.
+    [] fn mir_const: MirConst(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
+
+    [] fn mir_validated: MirValidated(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
+
+    /// MIR after our optimization passes have run. This is MIR that is ready
+    /// for codegen. This is also the only query that can fetch non-local MIR, at present.
+    [] fn optimized_mir: MirOptimized(DefId) -> &'tcx mir::Mir<'tcx>,
+
+    /// The result of unsafety-checking this def-id.
+    [] fn unsafety_check_result: UnsafetyCheckResult(DefId) -> mir::UnsafetyCheckResult,
+
+    /// HACK: when evaluated, this reports a "unsafe derive on repr(packed)" error
+    [] fn unsafe_derive_on_repr_packed: UnsafeDeriveOnReprPacked(DefId) -> (),
+
+    /// The signature of functions and closures.
+    [] fn fn_sig: FnSignature(DefId) -> ty::PolyFnSig<'tcx>,
+
+    /// Caches CoerceUnsized kinds for impls on custom types.
+    [] fn coerce_unsized_info: CoerceUnsizedInfo(DefId)
+        -> ty::adjustment::CoerceUnsizedInfo,
+
+    [] fn typeck_item_bodies: typeck_item_bodies_dep_node(CrateNum) -> CompileResult,
+
+    [] fn typeck_tables_of: TypeckTables(DefId) -> &'tcx ty::TypeckTables<'tcx>,
+
+    [] fn used_trait_imports: UsedTraitImports(DefId) -> Lrc<DefIdSet>,
+
+    [] fn has_typeck_tables: HasTypeckTables(DefId) -> bool,
+
+    [] fn coherent_trait: CoherenceCheckTrait(DefId) -> (),
+
+    [] fn borrowck: BorrowCheck(DefId) -> Lrc<BorrowCheckResult>,
+
+    /// Borrow checks the function body. If this is a closure, returns
+    /// additional requirements that the closure's creator must verify.
+    [] fn mir_borrowck: MirBorrowCheck(DefId) -> mir::BorrowCheckResult<'tcx>,
+
+    /// Gets a complete map from all types to their inherent impls.
+    /// Not meant to be used directly outside of coherence.
+    /// (Defined only for LOCAL_CRATE)
+    [] fn crate_inherent_impls: crate_inherent_impls_dep_node(CrateNum) -> CrateInherentImpls,
+
+    /// Checks all types in the krate for overlap in their inherent impls. Reports errors.
+    /// Not meant to be used directly outside of coherence.
+    /// (Defined only for LOCAL_CRATE)
+    [] fn crate_inherent_impls_overlap_check: inherent_impls_overlap_check_dep_node(CrateNum) -> (),
+
+    /// Results of evaluating const items or constants embedded in
+    /// other items (such as enum variant explicit discriminants).
+    [] fn const_eval: const_eval_dep_node(ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
+        -> EvalResult<'tcx>,
+
+    /// Converts a constant value to an constant allocation
+    [] fn const_value_to_allocation: const_value_to_allocation(
+        (ConstValue<'tcx>, Ty<'tcx>)
+    ) -> &'tcx Allocation,
+
+    [] fn check_match: CheckMatch(DefId)
+        -> Result<(), ErrorReported>,
+
+    /// Performs the privacy check and computes "access levels".
+    [] fn privacy_access_levels: PrivacyAccessLevels(CrateNum) -> Lrc<AccessLevels>,
+
+    [] fn reachable_set: reachability_dep_node(CrateNum) -> ReachableSet,
+
+    /// Per-body `region::ScopeTree`. The `DefId` should be the owner-def-id for the body;
+    /// in the case of closures, this will be redirected to the enclosing function.
+    [] fn region_scope_tree: RegionScopeTree(DefId) -> Lrc<region::ScopeTree>,
+
+    [] fn mir_shims: mir_shim_dep_node(ty::InstanceDef<'tcx>) -> &'tcx mir::Mir<'tcx>,
+
+    [] fn def_symbol_name: SymbolName(DefId) -> ty::SymbolName,
+    [] fn symbol_name: symbol_name_dep_node(ty::Instance<'tcx>) -> ty::SymbolName,
+
+    [] fn describe_def: DescribeDef(DefId) -> Option<Def>,
+    [] fn def_span: DefSpan(DefId) -> Span,
+    [] fn lookup_stability: LookupStability(DefId) -> Option<&'tcx attr::Stability>,
+    [] fn lookup_deprecation_entry: LookupDeprecationEntry(DefId) -> Option<DeprecationEntry>,
+    [] fn item_attrs: ItemAttrs(DefId) -> Lrc<[ast::Attribute]>,
+    [] fn codegen_fn_attrs: codegen_fn_attrs(DefId) -> CodegenFnAttrs,
+    [] fn fn_arg_names: FnArgNames(DefId) -> Vec<ast::Name>,
+    /// Gets the rendered value of the specified constant or associated constant.
+    /// Used by rustdoc.
+    [] fn rendered_const: RenderedConst(DefId) -> String,
+    [] fn impl_parent: ImplParent(DefId) -> Option<DefId>,
+    [] fn trait_of_item: TraitOfItem(DefId) -> Option<DefId>,
+    [] fn const_is_rvalue_promotable_to_static: ConstIsRvaluePromotableToStatic(DefId) -> bool,
+    [] fn rvalue_promotable_map: RvaluePromotableMap(DefId) -> Lrc<ItemLocalSet>,
+    [] fn is_mir_available: IsMirAvailable(DefId) -> bool,
+    [] fn vtable_methods: vtable_methods_node(ty::PolyTraitRef<'tcx>)
+                          -> Lrc<Vec<Option<(DefId, &'tcx Substs<'tcx>)>>>,
+
+    [] fn codegen_fulfill_obligation: fulfill_obligation_dep_node(
+        (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)) -> Vtable<'tcx, ()>,
+    [] fn trait_impls_of: TraitImpls(DefId) -> Lrc<ty::trait_def::TraitImpls>,
+    [] fn specialization_graph_of: SpecializationGraph(DefId) -> Lrc<specialization_graph::Graph>,
+    [] fn is_object_safe: ObjectSafety(DefId) -> bool,
+
+    // Get the ParameterEnvironment for a given item; this environment
+    // will be in "user-facing" mode, meaning that it is suitabe for
+    // type-checking etc, and it does not normalize specializable
+    // associated types. This is almost always what you want,
+    // unless you are doing MIR optimizations, in which case you
+    // might want to use `reveal_all()` method to change modes.
+    [] fn param_env: ParamEnv(DefId) -> ty::ParamEnv<'tcx>,
+
+    // Trait selection queries. These are best used by invoking `ty.moves_by_default()`,
+    // `ty.is_copy()`, etc, since that will prune the environment where possible.
+    [] fn is_copy_raw: is_copy_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool,
+    [] fn is_sized_raw: is_sized_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool,
+    [] fn is_freeze_raw: is_freeze_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool,
+    [] fn needs_drop_raw: needs_drop_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool,
+    [] fn layout_raw: layout_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
+                                  -> Result<&'tcx ty::layout::LayoutDetails,
+                                            ty::layout::LayoutError<'tcx>>,
+
+    [] fn dylib_dependency_formats: DylibDepFormats(CrateNum)
+                                    -> Lrc<Vec<(CrateNum, LinkagePreference)>>,
+
+    [fatal_cycle] fn is_panic_runtime: IsPanicRuntime(CrateNum) -> bool,
+    [fatal_cycle] fn is_compiler_builtins: IsCompilerBuiltins(CrateNum) -> bool,
+    [fatal_cycle] fn has_global_allocator: HasGlobalAllocator(CrateNum) -> bool,
+    [fatal_cycle] fn is_sanitizer_runtime: IsSanitizerRuntime(CrateNum) -> bool,
+    [fatal_cycle] fn is_profiler_runtime: IsProfilerRuntime(CrateNum) -> bool,
+    [fatal_cycle] fn panic_strategy: GetPanicStrategy(CrateNum) -> PanicStrategy,
+    [fatal_cycle] fn is_no_builtins: IsNoBuiltins(CrateNum) -> bool,
+
+    [] fn extern_crate: ExternCrate(DefId) -> Lrc<Option<ExternCrate>>,
+
+    [] fn specializes: specializes_node((DefId, DefId)) -> bool,
+    [] fn in_scope_traits_map: InScopeTraits(DefIndex)
+        -> Option<Lrc<FxHashMap<ItemLocalId, Lrc<StableVec<TraitCandidate>>>>>,
+    [] fn module_exports: ModuleExports(DefId) -> Option<Lrc<Vec<Export>>>,
+    [] fn lint_levels: lint_levels_node(CrateNum) -> Lrc<lint::LintLevelMap>,
+
+    [] fn impl_defaultness: ImplDefaultness(DefId) -> hir::Defaultness,
+
+    [] fn check_item_well_formed: CheckItemWellFormed(DefId) -> (),
+    [] fn check_trait_item_well_formed: CheckTraitItemWellFormed(DefId) -> (),
+    [] fn check_impl_item_well_formed: CheckImplItemWellFormed(DefId) -> (),
+
+    // The DefIds of all non-generic functions and statics in the given crate
+    // that can be reached from outside the crate.
+    //
+    // We expect this items to be available for being linked to.
+    //
+    // This query can also be called for LOCAL_CRATE. In this case it will
+    // compute which items will be reachable to other crates, taking into account
+    // the kind of crate that is currently compiled. Crates with only a
+    // C interface have fewer reachable things.
+    //
+    // Does not include external symbols that don't have a corresponding DefId,
+    // like the compiler-generated `main` function and so on.
+    [] fn reachable_non_generics: ReachableNonGenerics(CrateNum)
+        -> Lrc<DefIdMap<SymbolExportLevel>>,
+    [] fn is_reachable_non_generic: IsReachableNonGeneric(DefId) -> bool,
+    [] fn is_unreachable_local_definition: IsUnreachableLocalDefinition(DefId) -> bool,
+
+    [] fn upstream_monomorphizations: UpstreamMonomorphizations(CrateNum)
+        -> Lrc<DefIdMap<Lrc<FxHashMap<&'tcx Substs<'tcx>, CrateNum>>>>,
+    [] fn upstream_monomorphizations_for: UpstreamMonomorphizationsFor(DefId)
+        -> Option<Lrc<FxHashMap<&'tcx Substs<'tcx>, CrateNum>>>,
+
+    [] fn native_libraries: NativeLibraries(CrateNum) -> Lrc<Vec<NativeLibrary>>,
+
+    [] fn foreign_modules: ForeignModules(CrateNum) -> Lrc<Vec<ForeignModule>>,
+
+    [] fn plugin_registrar_fn: PluginRegistrarFn(CrateNum) -> Option<DefId>,
+    [] fn derive_registrar_fn: DeriveRegistrarFn(CrateNum) -> Option<DefId>,
+    [] fn crate_disambiguator: CrateDisambiguator(CrateNum) -> CrateDisambiguator,
+    [] fn crate_hash: CrateHash(CrateNum) -> Svh,
+    [] fn original_crate_name: OriginalCrateName(CrateNum) -> Symbol,
+    [] fn extra_filename: ExtraFileName(CrateNum) -> String,
+
+    [] fn implementations_of_trait: implementations_of_trait_node((CrateNum, DefId))
+        -> Lrc<Vec<DefId>>,
+    [] fn all_trait_implementations: AllTraitImplementations(CrateNum)
+        -> Lrc<Vec<DefId>>,
+
+    [] fn dllimport_foreign_items: DllimportForeignItems(CrateNum)
+        -> Lrc<FxHashSet<DefId>>,
+    [] fn is_dllimport_foreign_item: IsDllimportForeignItem(DefId) -> bool,
+    [] fn is_statically_included_foreign_item: IsStaticallyIncludedForeignItem(DefId) -> bool,
+    [] fn native_library_kind: NativeLibraryKind(DefId)
+        -> Option<NativeLibraryKind>,
+    [] fn link_args: link_args_node(CrateNum) -> Lrc<Vec<String>>,
+
+    // Lifetime resolution. See `middle::resolve_lifetimes`.
+    [] fn resolve_lifetimes: ResolveLifetimes(CrateNum) -> Lrc<ResolveLifetimes>,
+    [] fn named_region_map: NamedRegion(DefIndex) ->
+        Option<Lrc<FxHashMap<ItemLocalId, Region>>>,
+    [] fn is_late_bound_map: IsLateBound(DefIndex) ->
+        Option<Lrc<FxHashSet<ItemLocalId>>>,
+    [] fn object_lifetime_defaults_map: ObjectLifetimeDefaults(DefIndex)
+        -> Option<Lrc<FxHashMap<ItemLocalId, Lrc<Vec<ObjectLifetimeDefault>>>>>,
+
+    [] fn visibility: Visibility(DefId) -> ty::Visibility,
+    [] fn dep_kind: DepKind(CrateNum) -> DepKind,
+    [] fn crate_name: CrateName(CrateNum) -> Symbol,
+    [] fn item_children: ItemChildren(DefId) -> Lrc<Vec<Export>>,
+    [] fn extern_mod_stmt_cnum: ExternModStmtCnum(DefId) -> Option<CrateNum>,
+
+    [] fn get_lang_items: get_lang_items_node(CrateNum) -> Lrc<LanguageItems>,
+    [] fn defined_lang_items: DefinedLangItems(CrateNum) -> Lrc<Vec<(DefId, usize)>>,
+    [] fn missing_lang_items: MissingLangItems(CrateNum) -> Lrc<Vec<LangItem>>,
+    [] fn visible_parent_map: visible_parent_map_node(CrateNum)
+        -> Lrc<DefIdMap<DefId>>,
+    [] fn missing_extern_crate_item: MissingExternCrateItem(CrateNum) -> bool,
+    [] fn used_crate_source: UsedCrateSource(CrateNum) -> Lrc<CrateSource>,
+    [] fn postorder_cnums: postorder_cnums_node(CrateNum) -> Lrc<Vec<CrateNum>>,
+
+    [] fn freevars: Freevars(DefId) -> Option<Lrc<Vec<hir::Freevar>>>,
+    [] fn maybe_unused_trait_import: MaybeUnusedTraitImport(DefId) -> bool,
+    [] fn maybe_unused_extern_crates: maybe_unused_extern_crates_node(CrateNum)
+        -> Lrc<Vec<(DefId, Span)>>,
+
+    [] fn stability_index: stability_index_node(CrateNum) -> Lrc<stability::Index<'tcx>>,
+    [] fn all_crate_nums: all_crate_nums_node(CrateNum) -> Lrc<Vec<CrateNum>>,
+
+    /// A vector of every trait accessible in the whole crate
+    /// (i.e. including those from subcrates). This is used only for
+    /// error reporting.
+    [] fn all_traits: all_traits_node(CrateNum) -> Lrc<Vec<DefId>>,
+
+    [] fn exported_symbols: ExportedSymbols(CrateNum)
+        -> Arc<Vec<(ExportedSymbol<'tcx>, SymbolExportLevel)>>,
+    [] fn collect_and_partition_mono_items:
+        collect_and_partition_mono_items_node(CrateNum)
+        -> (Arc<DefIdSet>, Arc<Vec<Arc<CodegenUnit<'tcx>>>>),
+    [] fn is_codegened_item: IsCodegenedItem(DefId) -> bool,
+    [] fn codegen_unit: CodegenUnit(InternedString) -> Arc<CodegenUnit<'tcx>>,
+    [] fn compile_codegen_unit: CompileCodegenUnit(InternedString) -> Stats,
+    [] fn output_filenames: output_filenames_node(CrateNum)
+        -> Arc<OutputFilenames>,
+
+    // Erases regions from `ty` to yield a new type.
+    // Normally you would just use `tcx.erase_regions(&value)`,
+    // however, which uses this query as a kind of cache.
+    [] fn erase_regions_ty: erase_regions_ty(Ty<'tcx>) -> Ty<'tcx>,
+
+    /// Do not call this query directly: invoke `normalize` instead.
+    [] fn normalize_projection_ty: NormalizeProjectionTy(
+        CanonicalProjectionGoal<'tcx>
+    ) -> Result<
+        Lrc<Canonical<'tcx, canonical::QueryResult<'tcx, NormalizationResult<'tcx>>>>,
+        NoSolution,
+    >,
+
+    /// Do not call this query directly: invoke `normalize_erasing_regions` instead.
+    [] fn normalize_ty_after_erasing_regions: NormalizeTyAfterErasingRegions(
+        ParamEnvAnd<'tcx, Ty<'tcx>>
+    ) -> Ty<'tcx>,
+
+    /// Do not call this query directly: invoke `infcx.at().dropck_outlives()` instead.
+    [] fn dropck_outlives: DropckOutlives(
+        CanonicalTyGoal<'tcx>
+    ) -> Result<
+        Lrc<Canonical<'tcx, canonical::QueryResult<'tcx, DropckOutlivesResult<'tcx>>>>,
+        NoSolution,
+    >,
+
+    /// Do not call this query directly: invoke `infcx.predicate_may_hold()` or
+    /// `infcx.predicate_must_hold()` instead.
+    [] fn evaluate_obligation: EvaluateObligation(
+        CanonicalPredicateGoal<'tcx>
+    ) -> Result<traits::EvaluationResult, traits::OverflowError>,
+
+    [] fn substitute_normalize_and_test_predicates:
+        substitute_normalize_and_test_predicates_node((DefId, &'tcx Substs<'tcx>)) -> bool,
+
+    [] fn target_features_whitelist:
+        target_features_whitelist_node(CrateNum) -> Lrc<FxHashMap<String, Option<String>>>,
+
+    // Get an estimate of the size of an InstanceDef based on its MIR for CGU partitioning.
+    [] fn instance_def_size_estimate: instance_def_size_estimate_dep_node(ty::InstanceDef<'tcx>)
+        -> usize,
+
+    [] fn features_query: features_node(CrateNum) -> Lrc<feature_gate::Features>,
+
+    [] fn program_clauses_for: ProgramClausesFor(DefId) -> Clauses<'tcx>,
+
+    [] fn program_clauses_for_env: ProgramClausesForEnv(
+        ty::ParamEnv<'tcx>
+    ) -> Clauses<'tcx>,
+
+    [] fn wasm_custom_sections: WasmCustomSections(CrateNum) -> Lrc<Vec<DefId>>,
+    [] fn wasm_import_module_map: WasmImportModuleMap(CrateNum)
+        -> Lrc<FxHashMap<DefId, String>>,
+}
+
+// `try_get_query` can't be public because it uses the private query
+// implementation traits, so we provide access to it selectively.
+impl<'a, 'tcx, 'lcx> TyCtxt<'a, 'tcx, 'lcx> {
+    pub fn try_adt_sized_constraint(
+        self,
+        span: Span,
+        key: DefId,
+    ) -> Result<&'tcx [Ty<'tcx>], DiagnosticBuilder<'a>> {
+        self.try_get_query::<queries::adt_sized_constraint>(span, key)
+    }
+    pub fn try_needs_drop_raw(
+        self,
+        span: Span,
+        key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
+    ) -> Result<bool, DiagnosticBuilder<'a>> {
+        self.try_get_query::<queries::needs_drop_raw>(span, key)
+    }
+    pub fn try_optimized_mir(
+        self,
+        span: Span,
+        key: DefId,
+    ) -> Result<&'tcx mir::Mir<'tcx>, DiagnosticBuilder<'a>> {
+        self.try_get_query::<queries::optimized_mir>(span, key)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////
+// These functions are little shims used to find the dep-node for a
+// given query when there is not a *direct* mapping:
+
+
+fn features_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
+    DepConstructor::Features
+}
+
+fn codegen_fn_attrs<'tcx>(id: DefId) -> DepConstructor<'tcx> {
+    DepConstructor::CodegenFnAttrs { 0: id }
+}
+
+fn erase_regions_ty<'tcx>(ty: Ty<'tcx>) -> DepConstructor<'tcx> {
+    DepConstructor::EraseRegionsTy { ty }
+}
+
+fn const_value_to_allocation<'tcx>(
+    (val, ty): (ConstValue<'tcx>, Ty<'tcx>)
+) -> DepConstructor<'tcx> {
+    DepConstructor::ConstValueToAllocation { val, ty }
+}
+
+fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> {
+    DepConstructor::TypeParamPredicates {
+        item_id,
+        param_id
+    }
+}
+
+fn fulfill_obligation_dep_node<'tcx>((param_env, trait_ref):
+    (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)) -> DepConstructor<'tcx> {
+    DepConstructor::FulfillObligation {
+        param_env,
+        trait_ref
+    }
+}
+
+fn crate_inherent_impls_dep_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
+    DepConstructor::Coherence
+}
+
+fn inherent_impls_overlap_check_dep_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
+    DepConstructor::CoherenceInherentImplOverlapCheck
+}
+
+fn reachability_dep_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
+    DepConstructor::Reachability
+}
+
+fn mir_shim_dep_node<'tcx>(instance_def: ty::InstanceDef<'tcx>) -> DepConstructor<'tcx> {
+    DepConstructor::MirShim {
+        instance_def
+    }
+}
+
+fn symbol_name_dep_node<'tcx>(instance: ty::Instance<'tcx>) -> DepConstructor<'tcx> {
+    DepConstructor::InstanceSymbolName { instance }
+}
+
+fn typeck_item_bodies_dep_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
+    DepConstructor::TypeckBodiesKrate
+}
+
+fn const_eval_dep_node<'tcx>(param_env: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
+                             -> DepConstructor<'tcx> {
+    DepConstructor::ConstEval { param_env }
+}
+
+fn mir_keys<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
+    DepConstructor::MirKeys
+}
+
+fn crate_variances<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
+    DepConstructor::CrateVariances
+}
+
+fn is_copy_dep_node<'tcx>(param_env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepConstructor<'tcx> {
+    DepConstructor::IsCopy { param_env }
+}
+
+fn is_sized_dep_node<'tcx>(param_env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepConstructor<'tcx> {
+    DepConstructor::IsSized { param_env }
+}
+
+fn is_freeze_dep_node<'tcx>(param_env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepConstructor<'tcx> {
+    DepConstructor::IsFreeze { param_env }
+}
+
+fn needs_drop_dep_node<'tcx>(param_env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepConstructor<'tcx> {
+    DepConstructor::NeedsDrop { param_env }
+}
+
+fn layout_dep_node<'tcx>(param_env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepConstructor<'tcx> {
+    DepConstructor::Layout { param_env }
+}
+
+fn lint_levels_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
+    DepConstructor::LintLevels
+}
+
+fn specializes_node<'tcx>((a, b): (DefId, DefId)) -> DepConstructor<'tcx> {
+    DepConstructor::Specializes { impl1: a, impl2: b }
+}
+
+fn implementations_of_trait_node<'tcx>((krate, trait_id): (CrateNum, DefId))
+    -> DepConstructor<'tcx>
+{
+    DepConstructor::ImplementationsOfTrait { krate, trait_id }
+}
+
+fn link_args_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
+    DepConstructor::LinkArgs
+}
+
+fn get_lang_items_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
+    DepConstructor::GetLangItems
+}
+
+fn visible_parent_map_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
+    DepConstructor::VisibleParentMap
+}
+
+fn postorder_cnums_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
+    DepConstructor::PostorderCnums
+}
+
+fn maybe_unused_extern_crates_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
+    DepConstructor::MaybeUnusedExternCrates
+}
+
+fn stability_index_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
+    DepConstructor::StabilityIndex
+}
+
+fn all_crate_nums_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
+    DepConstructor::AllCrateNums
+}
+
+fn all_traits_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
+    DepConstructor::AllTraits
+}
+
+fn collect_and_partition_mono_items_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
+    DepConstructor::CollectAndPartitionMonoItems
+}
+
+fn output_filenames_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
+    DepConstructor::OutputFilenames
+}
+
+fn vtable_methods_node<'tcx>(trait_ref: ty::PolyTraitRef<'tcx>) -> DepConstructor<'tcx> {
+    DepConstructor::VtableMethods{ trait_ref }
+}
+
+fn substitute_normalize_and_test_predicates_node<'tcx>(key: (DefId, &'tcx Substs<'tcx>))
+                                            -> DepConstructor<'tcx> {
+    DepConstructor::SubstituteNormalizeAndTestPredicates { key }
+}
+
+fn target_features_whitelist_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
+    DepConstructor::TargetFeaturesWhitelist
+}
+
+fn instance_def_size_estimate_dep_node<'tcx>(instance_def: ty::InstanceDef<'tcx>)
+                                              -> DepConstructor<'tcx> {
+    DepConstructor::InstanceDefSizeEstimate {
+        instance_def
+    }
+}
diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
new file mode 100644 (file)
index 0000000..3285380
--- /dev/null
@@ -0,0 +1,1119 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
+use errors::Diagnostic;
+use hir;
+use hir::def_id::{CrateNum, DefIndex, DefId, LocalDefId,
+                  RESERVED_FOR_INCR_COMP_CACHE, LOCAL_CRATE};
+use hir::map::definitions::DefPathHash;
+use ich::{CachingCodemapView, Fingerprint};
+use mir::{self, interpret};
+use mir::interpret::{AllocDecodingSession, AllocDecodingState};
+use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::sync::{Lrc, Lock, HashMapExt, Once};
+use rustc_data_structures::indexed_vec::{IndexVec, Idx};
+use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque,
+                      SpecializedDecoder, SpecializedEncoder,
+                      UseSpecializedDecodable, UseSpecializedEncodable};
+use session::{CrateDisambiguator, Session};
+use std::mem;
+use syntax::ast::NodeId;
+use syntax::codemap::{CodeMap, StableFilemapId};
+use syntax_pos::{BytePos, Span, DUMMY_SP, FileMap};
+use syntax_pos::hygiene::{Mark, SyntaxContext, ExpnInfo};
+use ty;
+use ty::codec::{self as ty_codec, TyDecoder, TyEncoder};
+use ty::context::TyCtxt;
+use util::common::time;
+
+const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE;
+
+const TAG_CLEAR_CROSS_CRATE_CLEAR: u8 = 0;
+const TAG_CLEAR_CROSS_CRATE_SET: u8 = 1;
+
+const TAG_NO_EXPANSION_INFO: u8 = 0;
+const TAG_EXPANSION_INFO_SHORTHAND: u8 = 1;
+const TAG_EXPANSION_INFO_INLINE: u8 = 2;
+
+const TAG_VALID_SPAN: u8 = 0;
+const TAG_INVALID_SPAN: u8 = 1;
+
+/// `OnDiskCache` provides an interface to incr. comp. data cached from the
+/// previous compilation session. This data will eventually include the results
+/// of a few selected queries (like `typeck_tables_of` and `mir_optimized`) and
+/// any diagnostics that have been emitted during a query.
+pub struct OnDiskCache<'sess> {
+
+    // The complete cache data in serialized form.
+    serialized_data: Vec<u8>,
+
+    // This field collects all Diagnostics emitted during the current
+    // compilation session.
+    current_diagnostics: Lock<FxHashMap<DepNodeIndex, Vec<Diagnostic>>>,
+
+    prev_cnums: Vec<(u32, String, CrateDisambiguator)>,
+    cnum_map: Once<IndexVec<CrateNum, Option<CrateNum>>>,
+
+    codemap: &'sess CodeMap,
+    file_index_to_stable_id: FxHashMap<FileMapIndex, StableFilemapId>,
+
+    // These two fields caches that are populated lazily during decoding.
+    file_index_to_file: Lock<FxHashMap<FileMapIndex, Lrc<FileMap>>>,
+    synthetic_expansion_infos: Lock<FxHashMap<AbsoluteBytePos, SyntaxContext>>,
+
+    // A map from dep-node to the position of the cached query result in
+    // `serialized_data`.
+    query_result_index: FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>,
+
+    // A map from dep-node to the position of any associated diagnostics in
+    // `serialized_data`.
+    prev_diagnostics_index: FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>,
+
+    alloc_decoding_state: AllocDecodingState,
+}
+
+// This type is used only for (de-)serialization.
+#[derive(RustcEncodable, RustcDecodable)]
+struct Footer {
+    file_index_to_stable_id: FxHashMap<FileMapIndex, StableFilemapId>,
+    prev_cnums: Vec<(u32, String, CrateDisambiguator)>,
+    query_result_index: EncodedQueryResultIndex,
+    diagnostics_index: EncodedQueryResultIndex,
+    // the location of all allocations
+    interpret_alloc_index: Vec<u32>,
+}
+
+type EncodedQueryResultIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>;
+type EncodedDiagnosticsIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>;
+type EncodedDiagnostics = Vec<Diagnostic>;
+
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
+struct FileMapIndex(u32);
+
+#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, RustcEncodable, RustcDecodable)]
+struct AbsoluteBytePos(u32);
+
+impl AbsoluteBytePos {
+    fn new(pos: usize) -> AbsoluteBytePos {
+        debug_assert!(pos <= ::std::u32::MAX as usize);
+        AbsoluteBytePos(pos as u32)
+    }
+
+    fn to_usize(self) -> usize {
+        self.0 as usize
+    }
+}
+
+impl<'sess> OnDiskCache<'sess> {
+    /// Create a new OnDiskCache instance from the serialized data in `data`.
+    pub fn new(sess: &'sess Session, data: Vec<u8>, start_pos: usize) -> OnDiskCache<'sess> {
+        debug_assert!(sess.opts.incremental.is_some());
+
+        // Wrapping in a scope so we can borrow `data`
+        let footer: Footer = {
+            let mut decoder = opaque::Decoder::new(&data[..], start_pos);
+
+            // Decode the *position* of the footer which can be found in the
+            // last 8 bytes of the file.
+            decoder.set_position(data.len() - IntEncodedWithFixedSize::ENCODED_SIZE);
+            let query_result_index_pos = IntEncodedWithFixedSize::decode(&mut decoder)
+                .expect("Error while trying to decode query result index position.")
+                .0 as usize;
+
+            // Decoder the file footer which contains all the lookup tables, etc.
+            decoder.set_position(query_result_index_pos);
+            decode_tagged(&mut decoder, TAG_FILE_FOOTER)
+                .expect("Error while trying to decode query result index position.")
+        };
+
+        OnDiskCache {
+            serialized_data: data,
+            file_index_to_stable_id: footer.file_index_to_stable_id,
+            file_index_to_file: Lock::new(FxHashMap()),
+            prev_cnums: footer.prev_cnums,
+            cnum_map: Once::new(),
+            codemap: sess.codemap(),
+            current_diagnostics: Lock::new(FxHashMap()),
+            query_result_index: footer.query_result_index.into_iter().collect(),
+            prev_diagnostics_index: footer.diagnostics_index.into_iter().collect(),
+            synthetic_expansion_infos: Lock::new(FxHashMap()),
+            alloc_decoding_state: AllocDecodingState::new(footer.interpret_alloc_index),
+        }
+    }
+
+    pub fn new_empty(codemap: &'sess CodeMap) -> OnDiskCache<'sess> {
+        OnDiskCache {
+            serialized_data: Vec::new(),
+            file_index_to_stable_id: FxHashMap(),
+            file_index_to_file: Lock::new(FxHashMap()),
+            prev_cnums: vec![],
+            cnum_map: Once::new(),
+            codemap,
+            current_diagnostics: Lock::new(FxHashMap()),
+            query_result_index: FxHashMap(),
+            prev_diagnostics_index: FxHashMap(),
+            synthetic_expansion_infos: Lock::new(FxHashMap()),
+            alloc_decoding_state: AllocDecodingState::new(Vec::new()),
+        }
+    }
+
+    pub fn serialize<'a, 'tcx, E>(&self,
+                                  tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                  encoder: &mut E)
+                                  -> Result<(), E::Error>
+        where E: ty_codec::TyEncoder
+     {
+        // Serializing the DepGraph should not modify it:
+        tcx.dep_graph.with_ignore(|| {
+            // Allocate FileMapIndices
+            let (file_to_file_index, file_index_to_stable_id) = {
+                let mut file_to_file_index = FxHashMap();
+                let mut file_index_to_stable_id = FxHashMap();
+
+                for (index, file) in tcx.sess.codemap().files().iter().enumerate() {
+                    let index = FileMapIndex(index as u32);
+                    let file_ptr: *const FileMap = &**file as *const _;
+                    file_to_file_index.insert(file_ptr, index);
+                    file_index_to_stable_id.insert(index, StableFilemapId::new(&file));
+                }
+
+                (file_to_file_index, file_index_to_stable_id)
+            };
+
+            let mut encoder = CacheEncoder {
+                tcx,
+                encoder,
+                type_shorthands: FxHashMap(),
+                predicate_shorthands: FxHashMap(),
+                expn_info_shorthands: FxHashMap(),
+                interpret_allocs: FxHashMap(),
+                interpret_allocs_inverse: Vec::new(),
+                codemap: CachingCodemapView::new(tcx.sess.codemap()),
+                file_to_file_index,
+            };
+
+            // Load everything into memory so we can write it out to the on-disk
+            // cache. The vast majority of cacheable query results should already
+            // be in memory, so this should be a cheap operation.
+            tcx.dep_graph.exec_cache_promotions(tcx);
+
+            // Encode query results
+            let mut query_result_index = EncodedQueryResultIndex::new();
+
+            time(tcx.sess, "encode query results", || {
+                use ty::query::queries::*;
+                let enc = &mut encoder;
+                let qri = &mut query_result_index;
+
+                encode_query_results::<type_of, _>(tcx, enc, qri)?;
+                encode_query_results::<generics_of, _>(tcx, enc, qri)?;
+                encode_query_results::<predicates_of, _>(tcx, enc, qri)?;
+                encode_query_results::<used_trait_imports, _>(tcx, enc, qri)?;
+                encode_query_results::<typeck_tables_of, _>(tcx, enc, qri)?;
+                encode_query_results::<codegen_fulfill_obligation, _>(tcx, enc, qri)?;
+                encode_query_results::<optimized_mir, _>(tcx, enc, qri)?;
+                encode_query_results::<unsafety_check_result, _>(tcx, enc, qri)?;
+                encode_query_results::<borrowck, _>(tcx, enc, qri)?;
+                encode_query_results::<mir_borrowck, _>(tcx, enc, qri)?;
+                encode_query_results::<mir_const_qualif, _>(tcx, enc, qri)?;
+                encode_query_results::<def_symbol_name, _>(tcx, enc, qri)?;
+                encode_query_results::<const_is_rvalue_promotable_to_static, _>(tcx, enc, qri)?;
+                encode_query_results::<symbol_name, _>(tcx, enc, qri)?;
+                encode_query_results::<check_match, _>(tcx, enc, qri)?;
+                encode_query_results::<codegen_fn_attrs, _>(tcx, enc, qri)?;
+                encode_query_results::<specialization_graph_of, _>(tcx, enc, qri)?;
+
+                // const eval is special, it only encodes successfully evaluated constants
+                use ty::query::QueryAccessors;
+                let cache = const_eval::query_cache(tcx).borrow();
+                assert!(cache.active.is_empty());
+                for (key, entry) in cache.results.iter() {
+                    use ty::query::config::QueryDescription;
+                    if const_eval::cache_on_disk(key.clone()) {
+                        if let Ok(ref value) = entry.value {
+                            let dep_node = SerializedDepNodeIndex::new(entry.index.index());
+
+                            // Record position of the cache entry
+                            qri.push((dep_node, AbsoluteBytePos::new(enc.position())));
+
+                            // Encode the type check tables with the SerializedDepNodeIndex
+                            // as tag.
+                            enc.encode_tagged(dep_node, value)?;
+                        }
+                    }
+                }
+
+                Ok(())
+            })?;
+
+            // Encode diagnostics
+            let diagnostics_index = {
+                let mut diagnostics_index = EncodedDiagnosticsIndex::new();
+
+                for (dep_node_index, diagnostics) in self.current_diagnostics
+                                                        .borrow()
+                                                        .iter() {
+                    let pos = AbsoluteBytePos::new(encoder.position());
+                    // Let's make sure we get the expected type here:
+                    let diagnostics: &EncodedDiagnostics = diagnostics;
+                    let dep_node_index =
+                        SerializedDepNodeIndex::new(dep_node_index.index());
+                    encoder.encode_tagged(dep_node_index, diagnostics)?;
+                    diagnostics_index.push((dep_node_index, pos));
+                }
+
+                diagnostics_index
+            };
+
+            let interpret_alloc_index = {
+                let mut interpret_alloc_index = Vec::new();
+                let mut n = 0;
+                loop {
+                    let new_n = encoder.interpret_allocs_inverse.len();
+                    // if we have found new ids, serialize those, too
+                    if n == new_n {
+                        // otherwise, abort
+                        break;
+                    }
+                    for idx in n..new_n {
+                        let id = encoder.interpret_allocs_inverse[idx];
+                        let pos = encoder.position() as u32;
+                        interpret_alloc_index.push(pos);
+                        interpret::specialized_encode_alloc_id(
+                            &mut encoder,
+                            tcx,
+                            id,
+                        )?;
+                    }
+                    n = new_n;
+                }
+                interpret_alloc_index
+            };
+
+            let sorted_cnums = sorted_cnums_including_local_crate(tcx);
+            let prev_cnums: Vec<_> = sorted_cnums.iter().map(|&cnum| {
+                let crate_name = tcx.original_crate_name(cnum).as_str().to_string();
+                let crate_disambiguator = tcx.crate_disambiguator(cnum);
+                (cnum.as_u32(), crate_name, crate_disambiguator)
+            }).collect();
+
+            // Encode the file footer
+            let footer_pos = encoder.position() as u64;
+            encoder.encode_tagged(TAG_FILE_FOOTER, &Footer {
+                file_index_to_stable_id,
+                prev_cnums,
+                query_result_index,
+                diagnostics_index,
+                interpret_alloc_index,
+            })?;
+
+            // Encode the position of the footer as the last 8 bytes of the
+            // file so we know where to look for it.
+            IntEncodedWithFixedSize(footer_pos).encode(encoder.encoder)?;
+
+            // DO NOT WRITE ANYTHING TO THE ENCODER AFTER THIS POINT! The address
+            // of the footer must be the last thing in the data stream.
+
+            return Ok(());
+
+            fn sorted_cnums_including_local_crate(tcx: TyCtxt) -> Vec<CrateNum> {
+                let mut cnums = vec![LOCAL_CRATE];
+                cnums.extend_from_slice(&tcx.crates()[..]);
+                cnums.sort_unstable();
+                // Just to be sure...
+                cnums.dedup();
+                cnums
+            }
+        })
+    }
+
+    /// Load a diagnostic emitted during the previous compilation session.
+    pub fn load_diagnostics<'a, 'tcx>(&self,
+                                      tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                      dep_node_index: SerializedDepNodeIndex)
+                                      -> Vec<Diagnostic> {
+        let diagnostics: Option<EncodedDiagnostics> = self.load_indexed(
+            tcx,
+            dep_node_index,
+            &self.prev_diagnostics_index,
+            "diagnostics");
+
+        diagnostics.unwrap_or(Vec::new())
+    }
+
+    /// Store a diagnostic emitted during the current compilation session.
+    /// Anything stored like this will be available via `load_diagnostics` in
+    /// the next compilation session.
+    pub fn store_diagnostics(&self,
+                             dep_node_index: DepNodeIndex,
+                             diagnostics: Vec<Diagnostic>) {
+        let mut current_diagnostics = self.current_diagnostics.borrow_mut();
+        let prev = current_diagnostics.insert(dep_node_index, diagnostics);
+        debug_assert!(prev.is_none());
+    }
+
+    /// Returns the cached query result if there is something in the cache for
+    /// the given SerializedDepNodeIndex. Otherwise returns None.
+    pub fn try_load_query_result<'tcx, T>(&self,
+                                          tcx: TyCtxt<'_, 'tcx, 'tcx>,
+                                          dep_node_index: SerializedDepNodeIndex)
+                                          -> Option<T>
+        where T: Decodable
+    {
+        self.load_indexed(tcx,
+                          dep_node_index,
+                          &self.query_result_index,
+                          "query result")
+    }
+
+    /// Store a diagnostic emitted during computation of an anonymous query.
+    /// Since many anonymous queries can share the same `DepNode`, we aggregate
+    /// them -- as opposed to regular queries where we assume that there is a
+    /// 1:1 relationship between query-key and `DepNode`.
+    pub fn store_diagnostics_for_anon_node(&self,
+                                           dep_node_index: DepNodeIndex,
+                                           mut diagnostics: Vec<Diagnostic>) {
+        let mut current_diagnostics = self.current_diagnostics.borrow_mut();
+
+        let x = current_diagnostics.entry(dep_node_index).or_insert_with(|| {
+            mem::replace(&mut diagnostics, Vec::new())
+        });
+
+        x.extend(diagnostics.into_iter());
+    }
+
+    fn load_indexed<'tcx, T>(&self,
+                             tcx: TyCtxt<'_, 'tcx, 'tcx>,
+                             dep_node_index: SerializedDepNodeIndex,
+                             index: &FxHashMap<SerializedDepNodeIndex,
+                                               AbsoluteBytePos>,
+                             debug_tag: &'static str)
+                             -> Option<T>
+        where T: Decodable
+    {
+        let pos = if let Some(&pos) = index.get(&dep_node_index) {
+            pos
+        } else {
+            return None
+        };
+
+        // Initialize the cnum_map using the value from the thread which finishes the closure first
+        self.cnum_map.init_nonlocking_same(|| {
+            Self::compute_cnum_map(tcx, &self.prev_cnums[..])
+        });
+
+        let mut decoder = CacheDecoder {
+            tcx,
+            opaque: opaque::Decoder::new(&self.serialized_data[..], pos.to_usize()),
+            codemap: self.codemap,
+            cnum_map: self.cnum_map.get(),
+            file_index_to_file: &self.file_index_to_file,
+            file_index_to_stable_id: &self.file_index_to_stable_id,
+            synthetic_expansion_infos: &self.synthetic_expansion_infos,
+            alloc_decoding_session: self.alloc_decoding_state.new_decoding_session(),
+        };
+
+        match decode_tagged(&mut decoder, dep_node_index) {
+            Ok(value) => {
+                Some(value)
+            }
+            Err(e) => {
+                bug!("Could not decode cached {}: {}", debug_tag, e)
+            }
+        }
+    }
+
+    // This function builds mapping from previous-session-CrateNum to
+    // current-session-CrateNum. There might be CrateNums from the previous
+    // Session that don't occur in the current one. For these, the mapping
+    // maps to None.
+    fn compute_cnum_map(tcx: TyCtxt,
+                        prev_cnums: &[(u32, String, CrateDisambiguator)])
+                        -> IndexVec<CrateNum, Option<CrateNum>>
+    {
+        tcx.dep_graph.with_ignore(|| {
+            let current_cnums = tcx.all_crate_nums(LOCAL_CRATE).iter().map(|&cnum| {
+                let crate_name = tcx.original_crate_name(cnum)
+                                    .as_str()
+                                    .to_string();
+                let crate_disambiguator = tcx.crate_disambiguator(cnum);
+                ((crate_name, crate_disambiguator), cnum)
+            }).collect::<FxHashMap<_,_>>();
+
+            let map_size = prev_cnums.iter()
+                                    .map(|&(cnum, ..)| cnum)
+                                    .max()
+                                    .unwrap_or(0) + 1;
+            let mut map = IndexVec::new();
+            map.resize(map_size as usize, None);
+
+            for &(prev_cnum, ref crate_name, crate_disambiguator) in prev_cnums {
+                let key = (crate_name.clone(), crate_disambiguator);
+                map[CrateNum::from_u32(prev_cnum)] = current_cnums.get(&key).cloned();
+            }
+
+            map[LOCAL_CRATE] = Some(LOCAL_CRATE);
+            map
+        })
+    }
+}
+
+
+//- DECODING -------------------------------------------------------------------
+
+/// A decoder that can read the incr. comp. cache. It is similar to the one
+/// we use for crate metadata decoding in that it can rebase spans and
+/// eventually will also handle things that contain `Ty` instances.
+struct CacheDecoder<'a, 'tcx: 'a, 'x> {
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    opaque: opaque::Decoder<'x>,
+    codemap: &'x CodeMap,
+    cnum_map: &'x IndexVec<CrateNum, Option<CrateNum>>,
+    synthetic_expansion_infos: &'x Lock<FxHashMap<AbsoluteBytePos, SyntaxContext>>,
+    file_index_to_file: &'x Lock<FxHashMap<FileMapIndex, Lrc<FileMap>>>,
+    file_index_to_stable_id: &'x FxHashMap<FileMapIndex, StableFilemapId>,
+    alloc_decoding_session: AllocDecodingSession<'x>,
+}
+
+impl<'a, 'tcx, 'x> CacheDecoder<'a, 'tcx, 'x> {
+    fn file_index_to_file(&self, index: FileMapIndex) -> Lrc<FileMap> {
+        let CacheDecoder {
+            ref file_index_to_file,
+            ref file_index_to_stable_id,
+            ref codemap,
+            ..
+        } = *self;
+
+        file_index_to_file.borrow_mut().entry(index).or_insert_with(|| {
+            let stable_id = file_index_to_stable_id[&index];
+            codemap.filemap_by_stable_id(stable_id)
+                   .expect("Failed to lookup FileMap in new context.")
+        }).clone()
+    }
+}
+
+trait DecoderWithPosition: Decoder {
+    fn position(&self) -> usize;
+}
+
+impl<'enc> DecoderWithPosition for opaque::Decoder<'enc> {
+    fn position(&self) -> usize {
+        self.position()
+    }
+}
+
+impl<'a, 'tcx, 'x> DecoderWithPosition for CacheDecoder<'a, 'tcx, 'x> {
+    fn position(&self) -> usize {
+        self.opaque.position()
+    }
+}
+
+// Decode something that was encoded with encode_tagged() and verify that the
+// tag matches and the correct amount of bytes was read.
+fn decode_tagged<'a, 'tcx, D, T, V>(decoder: &mut D,
+                                    expected_tag: T)
+                                    -> Result<V, D::Error>
+    where T: Decodable + Eq + ::std::fmt::Debug,
+          V: Decodable,
+          D: DecoderWithPosition,
+          'tcx: 'a,
+{
+    let start_pos = decoder.position();
+
+    let actual_tag = T::decode(decoder)?;
+    assert_eq!(actual_tag, expected_tag);
+    let value = V::decode(decoder)?;
+    let end_pos = decoder.position();
+
+    let expected_len: u64 = Decodable::decode(decoder)?;
+    assert_eq!((end_pos - start_pos) as u64, expected_len);
+
+    Ok(value)
+}
+
+
+impl<'a, 'tcx: 'a, 'x> ty_codec::TyDecoder<'a, 'tcx> for CacheDecoder<'a, 'tcx, 'x> {
+
+    #[inline]
+    fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> {
+        self.tcx
+    }
+
+    #[inline]
+    fn position(&self) -> usize {
+        self.opaque.position()
+    }
+
+    #[inline]
+    fn peek_byte(&self) -> u8 {
+        self.opaque.data[self.opaque.position()]
+    }
+
+    fn cached_ty_for_shorthand<F>(&mut self,
+                                  shorthand: usize,
+                                  or_insert_with: F)
+                                  -> Result<ty::Ty<'tcx>, Self::Error>
+        where F: FnOnce(&mut Self) -> Result<ty::Ty<'tcx>, Self::Error>
+    {
+        let tcx = self.tcx();
+
+        let cache_key = ty::CReaderCacheKey {
+            cnum: RESERVED_FOR_INCR_COMP_CACHE,
+            pos: shorthand,
+        };
+
+        if let Some(&ty) = tcx.rcache.borrow().get(&cache_key) {
+            return Ok(ty);
+        }
+
+        let ty = or_insert_with(self)?;
+        // This may overwrite the entry, but it should overwrite with the same value
+        tcx.rcache.borrow_mut().insert_same(cache_key, ty);
+        Ok(ty)
+    }
+
+    fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
+        where F: FnOnce(&mut Self) -> R
+    {
+        debug_assert!(pos < self.opaque.data.len());
+
+        let new_opaque = opaque::Decoder::new(self.opaque.data, pos);
+        let old_opaque = mem::replace(&mut self.opaque, new_opaque);
+        let r = f(self);
+        self.opaque = old_opaque;
+        r
+    }
+
+    fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum {
+        self.cnum_map[cnum].unwrap_or_else(|| {
+            bug!("Could not find new CrateNum for {:?}", cnum)
+        })
+    }
+}
+
+implement_ty_decoder!( CacheDecoder<'a, 'tcx, 'x> );
+
+impl<'a, 'tcx, 'x> SpecializedDecoder<interpret::AllocId> for CacheDecoder<'a, 'tcx, 'x> {
+    fn specialized_decode(&mut self) -> Result<interpret::AllocId, Self::Error> {
+        let alloc_decoding_session = self.alloc_decoding_session;
+        alloc_decoding_session.decode_alloc_id(self)
+    }
+}
+impl<'a, 'tcx, 'x> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx, 'x> {
+    fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
+        let tag: u8 = Decodable::decode(self)?;
+
+        if tag == TAG_INVALID_SPAN {
+            return Ok(DUMMY_SP);
+        } else {
+            debug_assert_eq!(tag, TAG_VALID_SPAN);
+        }
+
+        let file_lo_index = FileMapIndex::decode(self)?;
+        let line_lo = usize::decode(self)?;
+        let col_lo = BytePos::decode(self)?;
+        let len = BytePos::decode(self)?;
+
+        let file_lo = self.file_index_to_file(file_lo_index);
+        let lo = file_lo.lines.borrow()[line_lo - 1] + col_lo;
+        let hi = lo + len;
+
+        let expn_info_tag = u8::decode(self)?;
+
+        let ctxt = match expn_info_tag {
+            TAG_NO_EXPANSION_INFO => {
+                SyntaxContext::empty()
+            }
+            TAG_EXPANSION_INFO_INLINE => {
+                let pos = AbsoluteBytePos::new(self.opaque.position());
+                let expn_info: ExpnInfo = Decodable::decode(self)?;
+                let ctxt = SyntaxContext::allocate_directly(expn_info);
+                self.synthetic_expansion_infos.borrow_mut().insert(pos, ctxt);
+                ctxt
+            }
+            TAG_EXPANSION_INFO_SHORTHAND => {
+                let pos = AbsoluteBytePos::decode(self)?;
+                let cached_ctxt = self.synthetic_expansion_infos
+                                      .borrow()
+                                      .get(&pos)
+                                      .cloned();
+
+                if let Some(ctxt) = cached_ctxt {
+                    ctxt
+                } else {
+                    let expn_info = self.with_position(pos.to_usize(), |this| {
+                         ExpnInfo::decode(this)
+                    })?;
+                    let ctxt = SyntaxContext::allocate_directly(expn_info);
+                    self.synthetic_expansion_infos.borrow_mut().insert(pos, ctxt);
+                    ctxt
+                }
+            }
+            _ => {
+                unreachable!()
+            }
+        };
+
+        Ok(Span::new(lo, hi, ctxt))
+    }
+}
+
+// This impl makes sure that we get a runtime error when we try decode a
+// DefIndex that is not contained in a DefId. Such a case would be problematic
+// because we would not know how to transform the DefIndex to the current
+// context.
+impl<'a, 'tcx, 'x> SpecializedDecoder<DefIndex> for CacheDecoder<'a, 'tcx, 'x> {
+    fn specialized_decode(&mut self) -> Result<DefIndex, Self::Error> {
+        bug!("Trying to decode DefIndex outside the context of a DefId")
+    }
+}
+
+// Both the CrateNum and the DefIndex of a DefId can change in between two
+// compilation sessions. We use the DefPathHash, which is stable across
+// sessions, to map the old DefId to the new one.
+impl<'a, 'tcx, 'x> SpecializedDecoder<DefId> for CacheDecoder<'a, 'tcx, 'x> {
+    #[inline]
+    fn specialized_decode(&mut self) -> Result<DefId, Self::Error> {
+        // Load the DefPathHash which is was we encoded the DefId as.
+        let def_path_hash = DefPathHash::decode(self)?;
+
+        // Using the DefPathHash, we can lookup the new DefId
+        Ok(self.tcx().def_path_hash_to_def_id.as_ref().unwrap()[&def_path_hash])
+    }
+}
+
+impl<'a, 'tcx, 'x> SpecializedDecoder<LocalDefId> for CacheDecoder<'a, 'tcx, 'x> {
+    #[inline]
+    fn specialized_decode(&mut self) -> Result<LocalDefId, Self::Error> {
+        Ok(LocalDefId::from_def_id(DefId::decode(self)?))
+    }
+}
+
+impl<'a, 'tcx, 'x> SpecializedDecoder<hir::HirId> for CacheDecoder<'a, 'tcx, 'x> {
+    fn specialized_decode(&mut self) -> Result<hir::HirId, Self::Error> {
+        // Load the DefPathHash which is was we encoded the DefIndex as.
+        let def_path_hash = DefPathHash::decode(self)?;
+
+        // Use the DefPathHash to map to the current DefId.
+        let def_id = self.tcx()
+                         .def_path_hash_to_def_id
+                         .as_ref()
+                         .unwrap()[&def_path_hash];
+
+        debug_assert!(def_id.is_local());
+
+        // The ItemLocalId needs no remapping.
+        let local_id = hir::ItemLocalId::decode(self)?;
+
+        // Reconstruct the HirId and look up the corresponding NodeId in the
+        // context of the current session.
+        Ok(hir::HirId {
+            owner: def_id.index,
+            local_id
+        })
+    }
+}
+
+// NodeIds are not stable across compilation sessions, so we store them in their
+// HirId representation. This allows use to map them to the current NodeId.
+impl<'a, 'tcx, 'x> SpecializedDecoder<NodeId> for CacheDecoder<'a, 'tcx, 'x> {
+    #[inline]
+    fn specialized_decode(&mut self) -> Result<NodeId, Self::Error> {
+        let hir_id = hir::HirId::decode(self)?;
+        Ok(self.tcx().hir.hir_to_node_id(hir_id))
+    }
+}
+
+impl<'a, 'tcx, 'x> SpecializedDecoder<Fingerprint> for CacheDecoder<'a, 'tcx, 'x> {
+    fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
+        Fingerprint::decode_opaque(&mut self.opaque)
+    }
+}
+
+impl<'a, 'tcx, 'x, T: Decodable> SpecializedDecoder<mir::ClearCrossCrate<T>>
+for CacheDecoder<'a, 'tcx, 'x> {
+    #[inline]
+    fn specialized_decode(&mut self) -> Result<mir::ClearCrossCrate<T>, Self::Error> {
+        let discr = u8::decode(self)?;
+
+        match discr {
+            TAG_CLEAR_CROSS_CRATE_CLEAR => Ok(mir::ClearCrossCrate::Clear),
+            TAG_CLEAR_CROSS_CRATE_SET => {
+                let val = T::decode(self)?;
+                Ok(mir::ClearCrossCrate::Set(val))
+            }
+            _ => {
+                unreachable!()
+            }
+        }
+    }
+}
+
+//- ENCODING -------------------------------------------------------------------
+
+struct CacheEncoder<'enc, 'a, 'tcx, E>
+    where E: 'enc + ty_codec::TyEncoder,
+          'tcx: 'a,
+{
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    encoder: &'enc mut E,
+    type_shorthands: FxHashMap<ty::Ty<'tcx>, usize>,
+    predicate_shorthands: FxHashMap<ty::Predicate<'tcx>, usize>,
+    expn_info_shorthands: FxHashMap<Mark, AbsoluteBytePos>,
+    interpret_allocs: FxHashMap<interpret::AllocId, usize>,
+    interpret_allocs_inverse: Vec<interpret::AllocId>,
+    codemap: CachingCodemapView<'tcx>,
+    file_to_file_index: FxHashMap<*const FileMap, FileMapIndex>,
+}
+
+impl<'enc, 'a, 'tcx, E> CacheEncoder<'enc, 'a, 'tcx, E>
+    where E: 'enc + ty_codec::TyEncoder
+{
+    fn filemap_index(&mut self, filemap: Lrc<FileMap>) -> FileMapIndex {
+        self.file_to_file_index[&(&*filemap as *const FileMap)]
+    }
+
+    /// Encode something with additional information that allows to do some
+    /// sanity checks when decoding the data again. This method will first
+    /// encode the specified tag, then the given value, then the number of
+    /// bytes taken up by tag and value. On decoding, we can then verify that
+    /// we get the expected tag and read the expected number of bytes.
+    fn encode_tagged<T: Encodable, V: Encodable>(&mut self,
+                                                 tag: T,
+                                                 value: &V)
+                                                 -> Result<(), E::Error>
+    {
+        use ty::codec::TyEncoder;
+        let start_pos = self.position();
+
+        tag.encode(self)?;
+        value.encode(self)?;
+
+        let end_pos = self.position();
+        ((end_pos - start_pos) as u64).encode(self)
+    }
+}
+
+impl<'enc, 'a, 'tcx, E> SpecializedEncoder<interpret::AllocId> for CacheEncoder<'enc, 'a, 'tcx, E>
+    where E: 'enc + ty_codec::TyEncoder
+{
+    fn specialized_encode(&mut self, alloc_id: &interpret::AllocId) -> Result<(), Self::Error> {
+        use std::collections::hash_map::Entry;
+        let index = match self.interpret_allocs.entry(*alloc_id) {
+            Entry::Occupied(e) => *e.get(),
+            Entry::Vacant(e) => {
+                let idx = self.interpret_allocs_inverse.len();
+                self.interpret_allocs_inverse.push(*alloc_id);
+                e.insert(idx);
+                idx
+            },
+        };
+
+        index.encode(self)
+    }
+}
+
+impl<'enc, 'a, 'tcx, E> SpecializedEncoder<Span> for CacheEncoder<'enc, 'a, 'tcx, E>
+    where E: 'enc + ty_codec::TyEncoder
+{
+    fn specialized_encode(&mut self, span: &Span) -> Result<(), Self::Error> {
+
+        if *span == DUMMY_SP {
+            return TAG_INVALID_SPAN.encode(self);
+        }
+
+        let span_data = span.data();
+
+        if span_data.hi < span_data.lo {
+            return TAG_INVALID_SPAN.encode(self);
+        }
+
+        let (file_lo, line_lo, col_lo) = match self.codemap
+                                                   .byte_pos_to_line_and_col(span_data.lo) {
+            Some(pos) => pos,
+            None => {
+                return TAG_INVALID_SPAN.encode(self);
+            }
+        };
+
+        if !file_lo.contains(span_data.hi) {
+            return TAG_INVALID_SPAN.encode(self);
+        }
+
+        let len = span_data.hi - span_data.lo;
+
+        let filemap_index = self.filemap_index(file_lo);
+
+        TAG_VALID_SPAN.encode(self)?;
+        filemap_index.encode(self)?;
+        line_lo.encode(self)?;
+        col_lo.encode(self)?;
+        len.encode(self)?;
+
+        if span_data.ctxt == SyntaxContext::empty() {
+            TAG_NO_EXPANSION_INFO.encode(self)
+        } else {
+            let mark = span_data.ctxt.outer();
+
+            if let Some(expn_info) = mark.expn_info() {
+                if let Some(pos) = self.expn_info_shorthands.get(&mark).cloned() {
+                    TAG_EXPANSION_INFO_SHORTHAND.encode(self)?;
+                    pos.encode(self)
+                } else {
+                    TAG_EXPANSION_INFO_INLINE.encode(self)?;
+                    let pos = AbsoluteBytePos::new(self.position());
+                    self.expn_info_shorthands.insert(mark, pos);
+                    expn_info.encode(self)
+                }
+            } else {
+                TAG_NO_EXPANSION_INFO.encode(self)
+            }
+        }
+    }
+}
+
+impl<'enc, 'a, 'tcx, E> ty_codec::TyEncoder for CacheEncoder<'enc, 'a, 'tcx, E>
+    where E: 'enc + ty_codec::TyEncoder
+{
+    #[inline]
+    fn position(&self) -> usize {
+        self.encoder.position()
+    }
+}
+
+impl<'enc, 'a, 'tcx, E> SpecializedEncoder<CrateNum> for CacheEncoder<'enc, 'a, 'tcx, E>
+    where E: 'enc + ty_codec::TyEncoder
+{
+    #[inline]
+    fn specialized_encode(&mut self, cnum: &CrateNum) -> Result<(), Self::Error> {
+        self.emit_u32(cnum.as_u32())
+    }
+}
+
+impl<'enc, 'a, 'tcx, E> SpecializedEncoder<ty::Ty<'tcx>> for CacheEncoder<'enc, 'a, 'tcx, E>
+    where E: 'enc + ty_codec::TyEncoder
+{
+    #[inline]
+    fn specialized_encode(&mut self, ty: &ty::Ty<'tcx>) -> Result<(), Self::Error> {
+        ty_codec::encode_with_shorthand(self, ty,
+            |encoder| &mut encoder.type_shorthands)
+    }
+}
+
+impl<'enc, 'a, 'tcx, E> SpecializedEncoder<ty::GenericPredicates<'tcx>>
+    for CacheEncoder<'enc, 'a, 'tcx, E>
+    where E: 'enc + ty_codec::TyEncoder
+{
+    #[inline]
+    fn specialized_encode(&mut self,
+                          predicates: &ty::GenericPredicates<'tcx>)
+                          -> Result<(), Self::Error> {
+        ty_codec::encode_predicates(self, predicates,
+            |encoder| &mut encoder.predicate_shorthands)
+    }
+}
+
+impl<'enc, 'a, 'tcx, E> SpecializedEncoder<hir::HirId> for CacheEncoder<'enc, 'a, 'tcx, E>
+    where E: 'enc + ty_codec::TyEncoder
+{
+    #[inline]
+    fn specialized_encode(&mut self, id: &hir::HirId) -> Result<(), Self::Error> {
+        let hir::HirId {
+            owner,
+            local_id,
+        } = *id;
+
+        let def_path_hash = self.tcx.hir.definitions().def_path_hash(owner);
+
+        def_path_hash.encode(self)?;
+        local_id.encode(self)
+    }
+}
+
+
+impl<'enc, 'a, 'tcx, E> SpecializedEncoder<DefId> for CacheEncoder<'enc, 'a, 'tcx, E>
+    where E: 'enc + ty_codec::TyEncoder
+{
+    #[inline]
+    fn specialized_encode(&mut self, id: &DefId) -> Result<(), Self::Error> {
+        let def_path_hash = self.tcx.def_path_hash(*id);
+        def_path_hash.encode(self)
+    }
+}
+
+impl<'enc, 'a, 'tcx, E> SpecializedEncoder<LocalDefId> for CacheEncoder<'enc, 'a, 'tcx, E>
+    where E: 'enc + ty_codec::TyEncoder
+{
+    #[inline]
+    fn specialized_encode(&mut self, id: &LocalDefId) -> Result<(), Self::Error> {
+        id.to_def_id().encode(self)
+    }
+}
+
+impl<'enc, 'a, 'tcx, E> SpecializedEncoder<DefIndex> for CacheEncoder<'enc, 'a, 'tcx, E>
+    where E: 'enc + ty_codec::TyEncoder
+{
+    fn specialized_encode(&mut self, _: &DefIndex) -> Result<(), Self::Error> {
+        bug!("Encoding DefIndex without context.")
+    }
+}
+
+// NodeIds are not stable across compilation sessions, so we store them in their
+// HirId representation. This allows use to map them to the current NodeId.
+impl<'enc, 'a, 'tcx, E> SpecializedEncoder<NodeId> for CacheEncoder<'enc, 'a, 'tcx, E>
+    where E: 'enc + ty_codec::TyEncoder
+{
+    #[inline]
+    fn specialized_encode(&mut self, node_id: &NodeId) -> Result<(), Self::Error> {
+        let hir_id = self.tcx.hir.node_to_hir_id(*node_id);
+        hir_id.encode(self)
+    }
+}
+
+impl<'enc, 'a, 'tcx> SpecializedEncoder<Fingerprint>
+for CacheEncoder<'enc, 'a, 'tcx, opaque::Encoder<'enc>>
+{
+    fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
+        f.encode_opaque(&mut self.encoder)
+    }
+}
+
+impl<'enc, 'a, 'tcx, E, T> SpecializedEncoder<mir::ClearCrossCrate<T>>
+for CacheEncoder<'enc, 'a, 'tcx, E>
+    where E: 'enc + ty_codec::TyEncoder,
+          T: Encodable,
+{
+    #[inline]
+    fn specialized_encode(&mut self,
+                          val: &mir::ClearCrossCrate<T>)
+                          -> Result<(), Self::Error> {
+        match *val {
+            mir::ClearCrossCrate::Clear => {
+                TAG_CLEAR_CROSS_CRATE_CLEAR.encode(self)
+            }
+            mir::ClearCrossCrate::Set(ref val) => {
+                TAG_CLEAR_CROSS_CRATE_SET.encode(self)?;
+                val.encode(self)
+            }
+        }
+    }
+}
+
+macro_rules! encoder_methods {
+    ($($name:ident($ty:ty);)*) => {
+        $(fn $name(&mut self, value: $ty) -> Result<(), Self::Error> {
+            self.encoder.$name(value)
+        })*
+    }
+}
+
+impl<'enc, 'a, 'tcx, E> Encoder for CacheEncoder<'enc, 'a, 'tcx, E>
+    where E: 'enc + ty_codec::TyEncoder
+{
+    type Error = E::Error;
+
+    fn emit_nil(&mut self) -> Result<(), Self::Error> {
+        Ok(())
+    }
+
+    encoder_methods! {
+        emit_usize(usize);
+        emit_u128(u128);
+        emit_u64(u64);
+        emit_u32(u32);
+        emit_u16(u16);
+        emit_u8(u8);
+
+        emit_isize(isize);
+        emit_i128(i128);
+        emit_i64(i64);
+        emit_i32(i32);
+        emit_i16(i16);
+        emit_i8(i8);
+
+        emit_bool(bool);
+        emit_f64(f64);
+        emit_f32(f32);
+        emit_char(char);
+        emit_str(&str);
+    }
+}
+
+// An integer that will always encode to 8 bytes.
+struct IntEncodedWithFixedSize(u64);
+
+impl IntEncodedWithFixedSize {
+    pub const ENCODED_SIZE: usize = 8;
+}
+
+impl UseSpecializedEncodable for IntEncodedWithFixedSize {}
+impl UseSpecializedDecodable for IntEncodedWithFixedSize {}
+
+impl<'enc> SpecializedEncoder<IntEncodedWithFixedSize> for opaque::Encoder<'enc> {
+    fn specialized_encode(&mut self, x: &IntEncodedWithFixedSize) -> Result<(), Self::Error> {
+        let start_pos = self.position();
+        for i in 0 .. IntEncodedWithFixedSize::ENCODED_SIZE {
+            ((x.0 >> i * 8) as u8).encode(self)?;
+        }
+        let end_pos = self.position();
+        assert_eq!((end_pos - start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
+        Ok(())
+    }
+}
+
+impl<'enc> SpecializedDecoder<IntEncodedWithFixedSize> for opaque::Decoder<'enc> {
+    fn specialized_decode(&mut self) -> Result<IntEncodedWithFixedSize, Self::Error> {
+        let mut value: u64 = 0;
+        let start_pos = self.position();
+
+        for i in 0 .. IntEncodedWithFixedSize::ENCODED_SIZE {
+            let byte: u8 = Decodable::decode(self)?;
+            value |= (byte as u64) << (i * 8);
+        }
+
+        let end_pos = self.position();
+        assert_eq!((end_pos - start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
+
+        Ok(IntEncodedWithFixedSize(value))
+    }
+}
+
+fn encode_query_results<'enc, 'a, 'tcx, Q, E>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                              encoder: &mut CacheEncoder<'enc, 'a, 'tcx, E>,
+                                              query_result_index: &mut EncodedQueryResultIndex)
+                                              -> Result<(), E::Error>
+    where Q: super::config::QueryDescription<'tcx>,
+          E: 'enc + TyEncoder,
+          Q::Value: Encodable,
+{
+    let desc = &format!("encode_query_results for {}",
+        unsafe { ::std::intrinsics::type_name::<Q>() });
+
+    time(tcx.sess, desc, || {
+
+    let map = Q::query_cache(tcx).borrow();
+    assert!(map.active.is_empty());
+    for (key, entry) in map.results.iter() {
+        if Q::cache_on_disk(key.clone()) {
+            let dep_node = SerializedDepNodeIndex::new(entry.index.index());
+
+            // Record position of the cache entry
+            query_result_index.push((dep_node, AbsoluteBytePos::new(encoder.position())));
+
+            // Encode the type check tables with the SerializedDepNodeIndex
+            // as tag.
+            encoder.encode_tagged(dep_node, &entry.value)?;
+        }
+    }
+
+    Ok(())
+    })
+}
diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs
new file mode 100644 (file)
index 0000000..4679c26
--- /dev/null
@@ -0,0 +1,1280 @@
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The implementation of the query system itself. Defines the macros
+//! that generate the actual methods on tcx which find and execute the
+//! provider, manage the caches, and so forth.
+
+use dep_graph::{DepNodeIndex, DepNode, DepKind, DepNodeColor};
+use errors::DiagnosticBuilder;
+use errors::Level;
+use errors::Diagnostic;
+use errors::FatalError;
+use ty::tls;
+use ty::{TyCtxt};
+use ty::query::Query;
+use ty::query::config::{QueryConfig, QueryDescription};
+use ty::query::job::{QueryJob, QueryResult, QueryInfo};
+use ty::item_path;
+
+use util::common::{profq_msg, ProfileQueriesMsg, QueryMsg};
+
+use rustc_data_structures::fx::{FxHashMap};
+use rustc_data_structures::sync::{Lrc, Lock};
+use std::mem;
+use std::ptr;
+use std::collections::hash_map::Entry;
+use syntax_pos::Span;
+use syntax::codemap::DUMMY_SP;
+
+pub struct QueryCache<'tcx, D: QueryConfig<'tcx> + ?Sized> {
+    pub(super) results: FxHashMap<D::Key, QueryValue<D::Value>>,
+    pub(super) active: FxHashMap<D::Key, QueryResult<'tcx>>,
+}
+
+pub(super) struct QueryValue<T> {
+    pub(super) value: T,
+    pub(super) index: DepNodeIndex,
+}
+
+impl<T> QueryValue<T> {
+    pub(super) fn new(value: T,
+                      dep_node_index: DepNodeIndex)
+                      -> QueryValue<T> {
+        QueryValue {
+            value,
+            index: dep_node_index,
+        }
+    }
+}
+
+impl<'tcx, M: QueryConfig<'tcx>> QueryCache<'tcx, M> {
+    pub(super) fn new() -> QueryCache<'tcx, M> {
+        QueryCache {
+            results: FxHashMap(),
+            active: FxHashMap(),
+        }
+    }
+}
+
+// If enabled, send a message to the profile-queries thread
+macro_rules! profq_msg {
+    ($tcx:expr, $msg:expr) => {
+        if cfg!(debug_assertions) {
+            if $tcx.sess.profile_queries() {
+                profq_msg($tcx.sess, $msg)
+            }
+        }
+    }
+}
+
+// If enabled, format a key using its debug string, which can be
+// expensive to compute (in terms of time).
+macro_rules! profq_query_msg {
+    ($query:expr, $tcx:expr, $key:expr) => {{
+        let msg = if cfg!(debug_assertions) {
+            if $tcx.sess.profile_queries_and_keys() {
+                Some(format!("{:?}", $key))
+            } else { None }
+        } else { None };
+        QueryMsg {
+            query: $query,
+            msg,
+        }
+    }}
+}
+
+/// A type representing the responsibility to execute the job in the `job` field.
+/// This will poison the relevant query if dropped.
+pub(super) struct JobOwner<'a, 'tcx: 'a, Q: QueryDescription<'tcx> + 'a> {
+    cache: &'a Lock<QueryCache<'tcx, Q>>,
+    key: Q::Key,
+    job: Lrc<QueryJob<'tcx>>,
+}
+
+impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
+    /// Either gets a JobOwner corresponding the the query, allowing us to
+    /// start executing the query, or it returns with the result of the query.
+    /// If the query is executing elsewhere, this will wait for it.
+    /// If the query panicked, this will silently panic.
+    ///
+    /// This function is inlined because that results in a noticeable speedup
+    /// for some compile-time benchmarks.
+    #[inline(always)]
+    pub(super) fn try_get(
+        tcx: TyCtxt<'a, 'tcx, '_>,
+        span: Span,
+        key: &Q::Key,
+    ) -> TryGetJob<'a, 'tcx, Q> {
+        let cache = Q::query_cache(tcx);
+        loop {
+            let mut lock = cache.borrow_mut();
+            if let Some(value) = lock.results.get(key) {
+                profq_msg!(tcx, ProfileQueriesMsg::CacheHit);
+                let result = Ok((value.value.clone(), value.index));
+                return TryGetJob::JobCompleted(result);
+            }
+            let job = match lock.active.entry((*key).clone()) {
+                Entry::Occupied(entry) => {
+                    match *entry.get() {
+                        QueryResult::Started(ref job) => job.clone(),
+                        QueryResult::Poisoned => FatalError.raise(),
+                    }
+                }
+                Entry::Vacant(entry) => {
+                    // No job entry for this query. Return a new one to be started later
+                    return tls::with_related_context(tcx, |icx| {
+                        let info = QueryInfo {
+                            span,
+                            query: Q::query(key.clone()),
+                        };
+                        let job = Lrc::new(QueryJob::new(info, icx.query.clone()));
+                        let owner = JobOwner {
+                            cache,
+                            job: job.clone(),
+                            key: (*key).clone(),
+                        };
+                        entry.insert(QueryResult::Started(job));
+                        TryGetJob::NotYetStarted(owner)
+                    })
+                }
+            };
+            mem::drop(lock);
+
+            if let Err(cycle) = job.await(tcx, span) {
+                return TryGetJob::JobCompleted(Err(cycle));
+            }
+        }
+    }
+
+    /// Completes the query by updating the query cache with the `result`,
+    /// signals the waiter and forgets the JobOwner, so it won't poison the query
+    pub(super) fn complete(self, result: &Q::Value, dep_node_index: DepNodeIndex) {
+        // We can move out of `self` here because we `mem::forget` it below
+        let key = unsafe { ptr::read(&self.key) };
+        let job = unsafe { ptr::read(&self.job) };
+        let cache = self.cache;
+
+        // Forget ourself so our destructor won't poison the query
+        mem::forget(self);
+
+        let value = QueryValue::new(result.clone(), dep_node_index);
+        {
+            let mut lock = cache.borrow_mut();
+            lock.active.remove(&key);
+            lock.results.insert(key, value);
+        }
+
+        job.signal_complete();
+    }
+
+    /// Executes a job by changing the ImplicitCtxt to point to the
+    /// new query job while it executes. It returns the diagnostics
+    /// captured during execution and the actual result.
+    pub(super) fn start<'lcx, F, R>(
+        &self,
+        tcx: TyCtxt<'_, 'tcx, 'lcx>,
+        compute: F)
+    -> (R, Vec<Diagnostic>)
+    where
+        F: for<'b> FnOnce(TyCtxt<'b, 'tcx, 'lcx>) -> R
+    {
+        // The TyCtxt stored in TLS has the same global interner lifetime
+        // as `tcx`, so we use `with_related_context` to relate the 'gcx lifetimes
+        // when accessing the ImplicitCtxt
+        let r = tls::with_related_context(tcx, move |current_icx| {
+            // Update the ImplicitCtxt to point to our new query job
+            let new_icx = tls::ImplicitCtxt {
+                tcx,
+                query: Some(self.job.clone()),
+                layout_depth: current_icx.layout_depth,
+                task: current_icx.task,
+            };
+
+            // Use the ImplicitCtxt while we execute the query
+            tls::enter_context(&new_icx, |_| {
+                compute(tcx)
+            })
+        });
+
+        // Extract the diagnostic from the job
+        let diagnostics = mem::replace(&mut *self.job.diagnostics.lock(), Vec::new());
+
+        (r, diagnostics)
+    }
+}
+
+impl<'a, 'tcx, Q: QueryDescription<'tcx>> Drop for JobOwner<'a, 'tcx, Q> {
+    fn drop(&mut self) {
+        // Poison the query so jobs waiting on it panic
+        self.cache.borrow_mut().active.insert(self.key.clone(), QueryResult::Poisoned);
+        // Also signal the completion of the job, so waiters
+        // will continue execution
+        self.job.signal_complete();
+    }
+}
+
+#[derive(Clone)]
+pub struct CycleError<'tcx> {
+    /// The query and related span which uses the cycle
+    pub(super) usage: Option<(Span, Query<'tcx>)>,
+    pub(super) cycle: Vec<QueryInfo<'tcx>>,
+}
+
+/// The result of `try_get_lock`
+pub(super) enum TryGetJob<'a, 'tcx: 'a, D: QueryDescription<'tcx> + 'a> {
+    /// The query is not yet started. Contains a guard to the cache eventually used to start it.
+    NotYetStarted(JobOwner<'a, 'tcx, D>),
+
+    /// The query was already completed.
+    /// Returns the result of the query and its dep node index
+    /// if it succeeded or a cycle error if it failed
+    JobCompleted(Result<(D::Value, DepNodeIndex), CycleError<'tcx>>),
+}
+
+impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
+    pub(super) fn report_cycle(self, CycleError { usage, cycle: stack }: CycleError<'gcx>)
+        -> DiagnosticBuilder<'a>
+    {
+        assert!(!stack.is_empty());
+
+        let fix_span = |span: Span, query: &Query<'gcx>| {
+            self.sess.codemap().def_span(query.default_span(self, span))
+        };
+
+        // Disable naming impls with types in this path, since that
+        // sometimes cycles itself, leading to extra cycle errors.
+        // (And cycle errors around impls tend to occur during the
+        // collect/coherence phases anyhow.)
+        item_path::with_forced_impl_filename_line(|| {
+            let span = fix_span(stack[1 % stack.len()].span, &stack[0].query);
+            let mut err = struct_span_err!(self.sess,
+                                           span,
+                                           E0391,
+                                           "cycle detected when {}",
+                                           stack[0].query.describe(self));
+
+            for i in 1..stack.len() {
+                let query = &stack[i].query;
+                let span = fix_span(stack[(i + 1) % stack.len()].span, query);
+                err.span_note(span, &format!("...which requires {}...", query.describe(self)));
+            }
+
+            err.note(&format!("...which again requires {}, completing the cycle",
+                              stack[0].query.describe(self)));
+
+            if let Some((span, query)) = usage {
+                err.span_note(fix_span(span, &query),
+                              &format!("cycle used when {}", query.describe(self)));
+            }
+
+            return err
+        })
+    }
+
+    pub fn try_print_query_stack() {
+        eprintln!("query stack during panic:");
+
+        tls::with_context_opt(|icx| {
+            if let Some(icx) = icx {
+                let mut current_query = icx.query.clone();
+                let mut i = 0;
+
+                while let Some(query) = current_query {
+                    let mut db = DiagnosticBuilder::new(icx.tcx.sess.diagnostic(),
+                        Level::FailureNote,
+                        &format!("#{} [{}] {}",
+                                 i,
+                                 query.info.query.name(),
+                                 query.info.query.describe(icx.tcx)));
+                    db.set_span(icx.tcx.sess.codemap().def_span(query.info.span));
+                    icx.tcx.sess.diagnostic().force_print_db(db);
+
+                    current_query = query.parent.clone();
+                    i += 1;
+                }
+            }
+        });
+
+        eprintln!("end of query stack");
+    }
+
+    /// Try to read a node index for the node dep_node.
+    /// A node will have an index, when it's already been marked green, or when we can mark it
+    /// green. This function will mark the current task as a reader of the specified node, when
+    /// the a node index can be found for that node.
+    pub(super) fn try_mark_green_and_read(self, dep_node: &DepNode) -> Option<DepNodeIndex> {
+        match self.dep_graph.node_color(dep_node) {
+            Some(DepNodeColor::Green(dep_node_index)) => {
+                self.dep_graph.read_index(dep_node_index);
+                Some(dep_node_index)
+            }
+            Some(DepNodeColor::Red) => {
+                None
+            }
+            None => {
+                // try_mark_green (called below) will panic when full incremental
+                // compilation is disabled. If that's the case, we can't try to mark nodes
+                // as green anyway, so we can safely return None here.
+                if !self.dep_graph.is_fully_enabled() {
+                    return None;
+                }
+                match self.dep_graph.try_mark_green(self.global_tcx(), &dep_node) {
+                    Some(dep_node_index) => {
+                        debug_assert!(self.dep_graph.is_green(&dep_node));
+                        self.dep_graph.read_index(dep_node_index);
+                        Some(dep_node_index)
+                    }
+                    None => {
+                        None
+                    }
+                }
+            }
+        }
+    }
+
+    fn try_get_with<Q: QueryDescription<'gcx>>(
+        self,
+        span: Span,
+        key: Q::Key)
+    -> Result<Q::Value, CycleError<'gcx>>
+    {
+        debug!("ty::queries::{}::try_get_with(key={:?}, span={:?})",
+               Q::NAME,
+               key,
+               span);
+
+        profq_msg!(self,
+            ProfileQueriesMsg::QueryBegin(
+                span.data(),
+                profq_query_msg!(Q::NAME, self, key),
+            )
+        );
+
+        let job = match JobOwner::try_get(self, span, &key) {
+            TryGetJob::NotYetStarted(job) => job,
+            TryGetJob::JobCompleted(result) => {
+                return result.map(|(v, index)| {
+                    self.dep_graph.read_index(index);
+                    v
+                })
+            }
+        };
+
+        // Fast path for when incr. comp. is off. `to_dep_node` is
+        // expensive for some DepKinds.
+        if !self.dep_graph.is_fully_enabled() {
+            let null_dep_node = DepNode::new_no_params(::dep_graph::DepKind::Null);
+            return self.force_query_with_job::<Q>(key, job, null_dep_node).map(|(v, _)| v);
+        }
+
+        let dep_node = Q::to_dep_node(self, &key);
+
+        if dep_node.kind.is_anon() {
+            profq_msg!(self, ProfileQueriesMsg::ProviderBegin);
+
+            let res = job.start(self, |tcx| {
+                tcx.dep_graph.with_anon_task(dep_node.kind, || {
+                    Q::compute(tcx.global_tcx(), key)
+                })
+            });
+
+            profq_msg!(self, ProfileQueriesMsg::ProviderEnd);
+            let ((result, dep_node_index), diagnostics) = res;
+
+            self.dep_graph.read_index(dep_node_index);
+
+            self.queries.on_disk_cache
+                .store_diagnostics_for_anon_node(dep_node_index, diagnostics);
+
+            job.complete(&result, dep_node_index);
+
+            return Ok(result);
+        }
+
+        if !dep_node.kind.is_input() {
+            if let Some(dep_node_index) = self.try_mark_green_and_read(&dep_node) {
+                profq_msg!(self, ProfileQueriesMsg::CacheHit);
+                return self.load_from_disk_and_cache_in_memory::<Q>(key,
+                                                                    job,
+                                                                    dep_node_index,
+                                                                    &dep_node)
+            }
+        }
+
+        match self.force_query_with_job::<Q>(key, job, dep_node) {
+            Ok((result, dep_node_index)) => {
+                self.dep_graph.read_index(dep_node_index);
+                Ok(result)
+            }
+            Err(e) => Err(e)
+        }
+    }
+
+    fn load_from_disk_and_cache_in_memory<Q: QueryDescription<'gcx>>(
+        self,
+        key: Q::Key,
+        job: JobOwner<'a, 'gcx, Q>,
+        dep_node_index: DepNodeIndex,
+        dep_node: &DepNode
+    ) -> Result<Q::Value, CycleError<'gcx>>
+    {
+        // Note this function can be called concurrently from the same query
+        // We must ensure that this is handled correctly
+
+        debug_assert!(self.dep_graph.is_green(dep_node));
+
+        // First we try to load the result from the on-disk cache
+        let result = if Q::cache_on_disk(key.clone()) &&
+                        self.sess.opts.debugging_opts.incremental_queries {
+            let prev_dep_node_index =
+                self.dep_graph.prev_dep_node_index_of(dep_node);
+            let result = Q::try_load_from_disk(self.global_tcx(),
+                                                    prev_dep_node_index);
+
+            // We always expect to find a cached result for things that
+            // can be forced from DepNode.
+            debug_assert!(!dep_node.kind.can_reconstruct_query_key() ||
+                            result.is_some(),
+                            "Missing on-disk cache entry for {:?}",
+                            dep_node);
+            result
+        } else {
+            // Some things are never cached on disk.
+            None
+        };
+
+        let result = if let Some(result) = result {
+            result
+        } else {
+            // We could not load a result from the on-disk cache, so
+            // recompute.
+
+            // The diagnostics for this query have already been
+            // promoted to the current session during
+            // try_mark_green(), so we can ignore them here.
+            let (result, _) = job.start(self, |tcx| {
+                // The dep-graph for this computation is already in
+                // place
+                tcx.dep_graph.with_ignore(|| {
+                    Q::compute(tcx, key)
+                })
+            });
+            result
+        };
+
+        // If -Zincremental-verify-ich is specified, re-hash results from
+        // the cache and make sure that they have the expected fingerprint.
+        if self.sess.opts.debugging_opts.incremental_verify_ich {
+            use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
+            use ich::Fingerprint;
+
+            assert!(Some(self.dep_graph.fingerprint_of(dep_node_index)) ==
+                    self.dep_graph.prev_fingerprint_of(dep_node),
+                    "Fingerprint for green query instance not loaded \
+                        from cache: {:?}", dep_node);
+
+            debug!("BEGIN verify_ich({:?})", dep_node);
+            let mut hcx = self.create_stable_hashing_context();
+            let mut hasher = StableHasher::new();
+
+            result.hash_stable(&mut hcx, &mut hasher);
+
+            let new_hash: Fingerprint = hasher.finish();
+            debug!("END verify_ich({:?})", dep_node);
+
+            let old_hash = self.dep_graph.fingerprint_of(dep_node_index);
+
+            assert!(new_hash == old_hash, "Found unstable fingerprints \
+                for {:?}", dep_node);
+        }
+
+        if self.sess.opts.debugging_opts.query_dep_graph {
+            self.dep_graph.mark_loaded_from_cache(dep_node_index, true);
+        }
+
+        job.complete(&result, dep_node_index);
+
+        Ok(result)
+    }
+
+    fn force_query_with_job<Q: QueryDescription<'gcx>>(
+        self,
+        key: Q::Key,
+        job: JobOwner<'_, 'gcx, Q>,
+        dep_node: DepNode)
+    -> Result<(Q::Value, DepNodeIndex), CycleError<'gcx>> {
+        // If the following assertion triggers, it can have two reasons:
+        // 1. Something is wrong with DepNode creation, either here or
+        //    in DepGraph::try_mark_green()
+        // 2. Two distinct query keys get mapped to the same DepNode
+        //    (see for example #48923)
+        assert!(!self.dep_graph.dep_node_exists(&dep_node),
+                "Forcing query with already existing DepNode.\n\
+                    - query-key: {:?}\n\
+                    - dep-node: {:?}",
+                key, dep_node);
+
+        profq_msg!(self, ProfileQueriesMsg::ProviderBegin);
+        let res = job.start(self, |tcx| {
+            if dep_node.kind.is_eval_always() {
+                tcx.dep_graph.with_eval_always_task(dep_node,
+                                                    tcx,
+                                                    key,
+                                                    Q::compute)
+            } else {
+                tcx.dep_graph.with_task(dep_node,
+                                        tcx,
+                                        key,
+                                        Q::compute)
+            }
+        });
+        profq_msg!(self, ProfileQueriesMsg::ProviderEnd);
+
+        let ((result, dep_node_index), diagnostics) = res;
+
+        if self.sess.opts.debugging_opts.query_dep_graph {
+            self.dep_graph.mark_loaded_from_cache(dep_node_index, false);
+        }
+
+        if dep_node.kind != ::dep_graph::DepKind::Null {
+            self.queries.on_disk_cache
+                .store_diagnostics(dep_node_index, diagnostics);
+        }
+
+        job.complete(&result, dep_node_index);
+
+        Ok((result, dep_node_index))
+    }
+
+    /// Ensure that either this query has all green inputs or been executed.
+    /// Executing query::ensure(D) is considered a read of the dep-node D.
+    ///
+    /// This function is particularly useful when executing passes for their
+    /// side-effects -- e.g., in order to report errors for erroneous programs.
+    ///
+    /// Note: The optimization is only available during incr. comp.
+    pub(super) fn ensure_query<Q: QueryDescription<'gcx>>(self, key: Q::Key) -> () {
+        let dep_node = Q::to_dep_node(self, &key);
+
+        // Ensuring an "input" or anonymous query makes no sense
+        assert!(!dep_node.kind.is_anon());
+        assert!(!dep_node.kind.is_input());
+        if self.try_mark_green_and_read(&dep_node).is_none() {
+            // A None return from `try_mark_green_and_read` means that this is either
+            // a new dep node or that the dep node has already been marked red.
+            // Either way, we can't call `dep_graph.read()` as we don't have the
+            // DepNodeIndex. We must invoke the query itself. The performance cost
+            // this introduces should be negligible as we'll immediately hit the
+            // in-memory cache, or another query down the line will.
+            let _ = self.get_query::<Q>(DUMMY_SP, key);
+        }
+    }
+
+    #[allow(dead_code)]
+    fn force_query<Q: QueryDescription<'gcx>>(
+        self,
+        key: Q::Key,
+        span: Span,
+        dep_node: DepNode
+    ) -> Result<(Q::Value, DepNodeIndex), CycleError<'gcx>> {
+        // We may be concurrently trying both execute and force a query
+        // Ensure that only one of them runs the query
+        let job = match JobOwner::try_get(self, span, &key) {
+            TryGetJob::NotYetStarted(job) => job,
+            TryGetJob::JobCompleted(result) => return result,
+        };
+        self.force_query_with_job::<Q>(key, job, dep_node)
+    }
+
+    pub(super) fn try_get_query<Q: QueryDescription<'gcx>>(
+        self,
+        span: Span,
+        key: Q::Key,
+    ) -> Result<Q::Value, DiagnosticBuilder<'a>> {
+        match self.try_get_with::<Q>(span, key) {
+            Ok(e) => Ok(e),
+            Err(e) => Err(self.report_cycle(e)),
+        }
+    }
+
+    pub(super) fn get_query<Q: QueryDescription<'gcx>>(
+        self,
+        span: Span,
+        key: Q::Key,
+    ) -> Q::Value {
+        self.try_get_query::<Q>(span, key).unwrap_or_else(|mut e| {
+            e.emit();
+            Q::handle_cycle_error(self)
+        })
+    }
+}
+
+macro_rules! handle_cycle_error {
+    ([][$this: expr]) => {{
+        Value::from_cycle_error($this.global_tcx())
+    }};
+    ([fatal_cycle$(, $modifiers:ident)*][$this:expr]) => {{
+        $this.sess.abort_if_errors();
+        unreachable!();
+    }};
+    ([$other:ident$(, $modifiers:ident)*][$($args:tt)*]) => {
+        handle_cycle_error!([$($modifiers),*][$($args)*])
+    };
+}
+
+macro_rules! define_queries {
+    (<$tcx:tt>
+     $($(#[$attr:meta])*
+       [$($modifiers:tt)*] fn $name:ident: $node:ident($K:ty) -> $V:ty,)*) => {
+
+        use std::mem;
+        #[cfg(parallel_queries)]
+        use ty::query::job::QueryResult;
+        use rustc_data_structures::sync::Lock;
+        use {
+            rustc_data_structures::stable_hasher::HashStable,
+            rustc_data_structures::stable_hasher::StableHasherResult,
+            rustc_data_structures::stable_hasher::StableHasher,
+            ich::StableHashingContext
+        };
+
+        define_queries_struct! {
+            tcx: $tcx,
+            input: ($(([$($modifiers)*] [$($attr)*] [$name]))*)
+        }
+
+        impl<$tcx> Queries<$tcx> {
+            pub fn new(
+                providers: IndexVec<CrateNum, Providers<$tcx>>,
+                on_disk_cache: OnDiskCache<'tcx>,
+            ) -> Self {
+                Queries {
+                    providers,
+                    on_disk_cache,
+                    $($name: Lock::new(QueryCache::new())),*
+                }
+            }
+
+            #[cfg(parallel_queries)]
+            pub fn collect_active_jobs(&self) -> Vec<Lrc<QueryJob<$tcx>>> {
+                let mut jobs = Vec::new();
+
+                // We use try_lock here since we are only called from the
+                // deadlock handler, and this shouldn't be locked
+                $(for v in self.$name.try_lock().unwrap().active.values() {
+                    match *v {
+                        QueryResult::Started(ref job) => jobs.push(job.clone()),
+                        _ => (),
+                    }
+                })*
+
+                return jobs;
+            }
+        }
+
+        #[allow(bad_style)]
+        #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+        pub enum Query<$tcx> {
+            $($(#[$attr])* $name($K)),*
+        }
+
+        impl<$tcx> Query<$tcx> {
+            pub fn name(&self) -> &'static str {
+                match *self {
+                    $(Query::$name(_) => stringify!($name),)*
+                }
+            }
+
+            pub fn describe(&self, tcx: TyCtxt) -> String {
+                let (r, name) = match *self {
+                    $(Query::$name(key) => {
+                        (queries::$name::describe(tcx, key), stringify!($name))
+                    })*
+                };
+                if tcx.sess.verbose() {
+                    format!("{} [{}]", r, name)
+                } else {
+                    r
+                }
+            }
+
+            // FIXME(eddyb) Get more valid Span's on queries.
+            pub fn default_span(&self, tcx: TyCtxt<'_, $tcx, '_>, span: Span) -> Span {
+                if span != DUMMY_SP {
+                    return span;
+                }
+                // The def_span query is used to calculate default_span,
+                // so exit to avoid infinite recursion
+                match *self {
+                    Query::def_span(..) => return span,
+                    _ => ()
+                }
+                match *self {
+                    $(Query::$name(key) => key.default_span(tcx),)*
+                }
+            }
+        }
+
+        impl<'a, $tcx> HashStable<StableHashingContext<'a>> for Query<$tcx> {
+            fn hash_stable<W: StableHasherResult>(&self,
+                                                hcx: &mut StableHashingContext<'a>,
+                                                hasher: &mut StableHasher<W>) {
+                mem::discriminant(self).hash_stable(hcx, hasher);
+                match *self {
+                    $(Query::$name(key) => key.hash_stable(hcx, hasher),)*
+                }
+            }
+        }
+
+        pub mod queries {
+            use std::marker::PhantomData;
+
+            $(#[allow(bad_style)]
+            pub struct $name<$tcx> {
+                data: PhantomData<&$tcx ()>
+            })*
+        }
+
+        // This module and the functions in it exist only to provide a
+        // predictable symbol name prefix for query providers. This is helpful
+        // for analyzing queries in profilers.
+        pub(super) mod __query_compute {
+            $(#[inline(never)]
+            pub fn $name<F: FnOnce() -> R, R>(f: F) -> R {
+                f()
+            })*
+        }
+
+        $(impl<$tcx> QueryConfig<$tcx> for queries::$name<$tcx> {
+            type Key = $K;
+            type Value = $V;
+
+            const NAME: &'static str = stringify!($name);
+        }
+
+        impl<$tcx> QueryAccessors<$tcx> for queries::$name<$tcx> {
+            fn query(key: Self::Key) -> Query<'tcx> {
+                Query::$name(key)
+            }
+
+            fn query_cache<'a>(tcx: TyCtxt<'a, $tcx, '_>) -> &'a Lock<QueryCache<$tcx, Self>> {
+                &tcx.queries.$name
+            }
+
+            #[allow(unused)]
+            fn to_dep_node(tcx: TyCtxt<'_, $tcx, '_>, key: &Self::Key) -> DepNode {
+                use dep_graph::DepConstructor::*;
+
+                DepNode::new(tcx, $node(*key))
+            }
+
+            #[inline]
+            fn compute(tcx: TyCtxt<'_, 'tcx, '_>, key: Self::Key) -> Self::Value {
+                __query_compute::$name(move || {
+                    let provider = tcx.queries.providers[key.query_crate()].$name;
+                    provider(tcx.global_tcx(), key)
+                })
+            }
+
+            fn handle_cycle_error(tcx: TyCtxt<'_, 'tcx, '_>) -> Self::Value {
+                handle_cycle_error!([$($modifiers)*][tcx])
+            }
+        }
+
+        impl<'a, $tcx, 'lcx> queries::$name<$tcx> {
+            /// Ensure that either this query has all green inputs or been executed.
+            /// Executing query::ensure(D) is considered a read of the dep-node D.
+            ///
+            /// This function is particularly useful when executing passes for their
+            /// side-effects -- e.g., in order to report errors for erroneous programs.
+            ///
+            /// Note: The optimization is only available during incr. comp.
+            pub fn ensure(tcx: TyCtxt<'a, $tcx, 'lcx>, key: $K) -> () {
+                tcx.ensure_query::<queries::$name>(key);
+            }
+        })*
+
+        #[derive(Copy, Clone)]
+        pub struct TyCtxtAt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
+            pub tcx: TyCtxt<'a, 'gcx, 'tcx>,
+            pub span: Span,
+        }
+
+        impl<'a, 'gcx, 'tcx> Deref for TyCtxtAt<'a, 'gcx, 'tcx> {
+            type Target = TyCtxt<'a, 'gcx, 'tcx>;
+            fn deref(&self) -> &Self::Target {
+                &self.tcx
+            }
+        }
+
+        impl<'a, $tcx, 'lcx> TyCtxt<'a, $tcx, 'lcx> {
+            /// Return a transparent wrapper for `TyCtxt` which uses
+            /// `span` as the location of queries performed through it.
+            pub fn at(self, span: Span) -> TyCtxtAt<'a, $tcx, 'lcx> {
+                TyCtxtAt {
+                    tcx: self,
+                    span
+                }
+            }
+
+            $($(#[$attr])*
+            pub fn $name(self, key: $K) -> $V {
+                self.at(DUMMY_SP).$name(key)
+            })*
+        }
+
+        impl<'a, $tcx, 'lcx> TyCtxtAt<'a, $tcx, 'lcx> {
+            $($(#[$attr])*
+            pub fn $name(self, key: $K) -> $V {
+                self.tcx.get_query::<queries::$name>(self.span, key)
+            })*
+        }
+
+        define_provider_struct! {
+            tcx: $tcx,
+            input: ($(([$($modifiers)*] [$name] [$K] [$V]))*)
+        }
+
+        impl<$tcx> Copy for Providers<$tcx> {}
+        impl<$tcx> Clone for Providers<$tcx> {
+            fn clone(&self) -> Self { *self }
+        }
+    }
+}
+
+macro_rules! define_queries_struct {
+    (tcx: $tcx:tt,
+     input: ($(([$($modifiers:tt)*] [$($attr:tt)*] [$name:ident]))*)) => {
+        pub(crate) struct Queries<$tcx> {
+            /// This provides access to the incr. comp. on-disk cache for query results.
+            /// Do not access this directly. It is only meant to be used by
+            /// `DepGraph::try_mark_green()` and the query infrastructure.
+            pub(crate) on_disk_cache: OnDiskCache<'tcx>,
+
+            providers: IndexVec<CrateNum, Providers<$tcx>>,
+
+            $($(#[$attr])*  $name: Lock<QueryCache<$tcx, queries::$name<$tcx>>>,)*
+        }
+    };
+}
+
+macro_rules! define_provider_struct {
+    (tcx: $tcx:tt,
+     input: ($(([$($modifiers:tt)*] [$name:ident] [$K:ty] [$R:ty]))*)) => {
+        pub struct Providers<$tcx> {
+            $(pub $name: for<'a> fn(TyCtxt<'a, $tcx, $tcx>, $K) -> $R,)*
+        }
+
+        impl<$tcx> Default for Providers<$tcx> {
+            fn default() -> Self {
+                $(fn $name<'a, $tcx>(_: TyCtxt<'a, $tcx, $tcx>, key: $K) -> $R {
+                    bug!("tcx.{}({:?}) unsupported by its crate",
+                         stringify!($name), key);
+                })*
+                Providers { $($name),* }
+            }
+        }
+    };
+}
+
+
+/// The red/green evaluation system will try to mark a specific DepNode in the
+/// dependency graph as green by recursively trying to mark the dependencies of
+/// that DepNode as green. While doing so, it will sometimes encounter a DepNode
+/// where we don't know if it is red or green and we therefore actually have
+/// to recompute its value in order to find out. Since the only piece of
+/// information that we have at that point is the DepNode we are trying to
+/// re-evaluate, we need some way to re-run a query from just that. This is what
+/// `force_from_dep_node()` implements.
+///
+/// In the general case, a DepNode consists of a DepKind and an opaque
+/// GUID/fingerprint that will uniquely identify the node. This GUID/fingerprint
+/// is usually constructed by computing a stable hash of the query-key that the
+/// DepNode corresponds to. Consequently, it is not in general possible to go
+/// back from hash to query-key (since hash functions are not reversible). For
+/// this reason `force_from_dep_node()` is expected to fail from time to time
+/// because we just cannot find out, from the DepNode alone, what the
+/// corresponding query-key is and therefore cannot re-run the query.
+///
+/// The system deals with this case letting `try_mark_green` fail which forces
+/// the root query to be re-evaluated.
+///
+/// Now, if force_from_dep_node() would always fail, it would be pretty useless.
+/// Fortunately, we can use some contextual information that will allow us to
+/// reconstruct query-keys for certain kinds of DepNodes. In particular, we
+/// enforce by construction that the GUID/fingerprint of certain DepNodes is a
+/// valid DefPathHash. Since we also always build a huge table that maps every
+/// DefPathHash in the current codebase to the corresponding DefId, we have
+/// everything we need to re-run the query.
+///
+/// Take the `mir_validated` query as an example. Like many other queries, it
+/// just has a single parameter: the DefId of the item it will compute the
+/// validated MIR for. Now, when we call `force_from_dep_node()` on a dep-node
+/// with kind `MirValidated`, we know that the GUID/fingerprint of the dep-node
+/// is actually a DefPathHash, and can therefore just look up the corresponding
+/// DefId in `tcx.def_path_hash_to_def_id`.
+///
+/// When you implement a new query, it will likely have a corresponding new
+/// DepKind, and you'll have to support it here in `force_from_dep_node()`. As
+/// a rule of thumb, if your query takes a DefId or DefIndex as sole parameter,
+/// then `force_from_dep_node()` should not fail for it. Otherwise, you can just
+/// add it to the "We don't have enough information to reconstruct..." group in
+/// the match below.
+pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
+                                           dep_node: &DepNode)
+                                           -> bool {
+    use hir::def_id::LOCAL_CRATE;
+
+    // We must avoid ever having to call force_from_dep_node() for a
+    // DepNode::CodegenUnit:
+    // Since we cannot reconstruct the query key of a DepNode::CodegenUnit, we
+    // would always end up having to evaluate the first caller of the
+    // `codegen_unit` query that *is* reconstructible. This might very well be
+    // the `compile_codegen_unit` query, thus re-codegenning the whole CGU just
+    // to re-trigger calling the `codegen_unit` query with the right key. At
+    // that point we would already have re-done all the work we are trying to
+    // avoid doing in the first place.
+    // The solution is simple: Just explicitly call the `codegen_unit` query for
+    // each CGU, right after partitioning. This way `try_mark_green` will always
+    // hit the cache instead of having to go through `force_from_dep_node`.
+    // This assertion makes sure, we actually keep applying the solution above.
+    debug_assert!(dep_node.kind != DepKind::CodegenUnit,
+                  "calling force_from_dep_node() on DepKind::CodegenUnit");
+
+    if !dep_node.kind.can_reconstruct_query_key() {
+        return false
+    }
+
+    macro_rules! def_id {
+        () => {
+            if let Some(def_id) = dep_node.extract_def_id(tcx) {
+                def_id
+            } else {
+                // return from the whole function
+                return false
+            }
+        }
+    };
+
+    macro_rules! krate {
+        () => { (def_id!()).krate }
+    };
+
+    macro_rules! force {
+        ($query:ident, $key:expr) => {
+            {
+                use $crate::util::common::{ProfileQueriesMsg, profq_msg};
+
+                profq_msg!(tcx,
+                    ProfileQueriesMsg::QueryBegin(
+                        DUMMY_SP.data(),
+                        profq_query_msg!(::ty::query::queries::$query::NAME, tcx, $key),
+                    )
+                );
+
+                match tcx.force_query::<::ty::query::queries::$query>($key, DUMMY_SP, *dep_node) {
+                    Ok(_) => {},
+                    Err(e) => {
+                        tcx.report_cycle(e).emit();
+                    }
+                }
+            }
+        }
+    };
+
+    // FIXME(#45015): We should try move this boilerplate code into a macro
+    //                somehow.
+    match dep_node.kind {
+        // These are inputs that are expected to be pre-allocated and that
+        // should therefore always be red or green already
+        DepKind::AllLocalTraitImpls |
+        DepKind::Krate |
+        DepKind::CrateMetadata |
+        DepKind::HirBody |
+        DepKind::Hir |
+
+        // This are anonymous nodes
+        DepKind::TraitSelect |
+
+        // We don't have enough information to reconstruct the query key of
+        // these
+        DepKind::IsCopy |
+        DepKind::IsSized |
+        DepKind::IsFreeze |
+        DepKind::NeedsDrop |
+        DepKind::Layout |
+        DepKind::ConstEval |
+        DepKind::InstanceSymbolName |
+        DepKind::MirShim |
+        DepKind::BorrowCheckKrate |
+        DepKind::Specializes |
+        DepKind::ImplementationsOfTrait |
+        DepKind::TypeParamPredicates |
+        DepKind::CodegenUnit |
+        DepKind::CompileCodegenUnit |
+        DepKind::FulfillObligation |
+        DepKind::VtableMethods |
+        DepKind::EraseRegionsTy |
+        DepKind::ConstValueToAllocation |
+        DepKind::NormalizeProjectionTy |
+        DepKind::NormalizeTyAfterErasingRegions |
+        DepKind::DropckOutlives |
+        DepKind::EvaluateObligation |
+        DepKind::SubstituteNormalizeAndTestPredicates |
+        DepKind::InstanceDefSizeEstimate |
+        DepKind::ProgramClausesForEnv |
+
+        // This one should never occur in this context
+        DepKind::Null => {
+            bug!("force_from_dep_node() - Encountered {:?}", dep_node)
+        }
+
+        // These are not queries
+        DepKind::CoherenceCheckTrait |
+        DepKind::ItemVarianceConstraints => {
+            return false
+        }
+
+        DepKind::RegionScopeTree => { force!(region_scope_tree, def_id!()); }
+
+        DepKind::Coherence => { force!(crate_inherent_impls, LOCAL_CRATE); }
+        DepKind::CoherenceInherentImplOverlapCheck => {
+            force!(crate_inherent_impls_overlap_check, LOCAL_CRATE)
+        },
+        DepKind::PrivacyAccessLevels => { force!(privacy_access_levels, LOCAL_CRATE); }
+        DepKind::MirBuilt => { force!(mir_built, def_id!()); }
+        DepKind::MirConstQualif => { force!(mir_const_qualif, def_id!()); }
+        DepKind::MirConst => { force!(mir_const, def_id!()); }
+        DepKind::MirValidated => { force!(mir_validated, def_id!()); }
+        DepKind::MirOptimized => { force!(optimized_mir, def_id!()); }
+
+        DepKind::BorrowCheck => { force!(borrowck, def_id!()); }
+        DepKind::MirBorrowCheck => { force!(mir_borrowck, def_id!()); }
+        DepKind::UnsafetyCheckResult => { force!(unsafety_check_result, def_id!()); }
+        DepKind::UnsafeDeriveOnReprPacked => { force!(unsafe_derive_on_repr_packed, def_id!()); }
+        DepKind::Reachability => { force!(reachable_set, LOCAL_CRATE); }
+        DepKind::MirKeys => { force!(mir_keys, LOCAL_CRATE); }
+        DepKind::CrateVariances => { force!(crate_variances, LOCAL_CRATE); }
+        DepKind::AssociatedItems => { force!(associated_item, def_id!()); }
+        DepKind::TypeOfItem => { force!(type_of, def_id!()); }
+        DepKind::GenericsOfItem => { force!(generics_of, def_id!()); }
+        DepKind::PredicatesOfItem => { force!(predicates_of, def_id!()); }
+        DepKind::ExplicitPredicatesOfItem => { force!(explicit_predicates_of, def_id!()); }
+        DepKind::InferredOutlivesOf => { force!(inferred_outlives_of, def_id!()); }
+        DepKind::InferredOutlivesCrate => { force!(inferred_outlives_crate, LOCAL_CRATE); }
+        DepKind::SuperPredicatesOfItem => { force!(super_predicates_of, def_id!()); }
+        DepKind::TraitDefOfItem => { force!(trait_def, def_id!()); }
+        DepKind::AdtDefOfItem => { force!(adt_def, def_id!()); }
+        DepKind::ImplTraitRef => { force!(impl_trait_ref, def_id!()); }
+        DepKind::ImplPolarity => { force!(impl_polarity, def_id!()); }
+        DepKind::FnSignature => { force!(fn_sig, def_id!()); }
+        DepKind::CoerceUnsizedInfo => { force!(coerce_unsized_info, def_id!()); }
+        DepKind::ItemVariances => { force!(variances_of, def_id!()); }
+        DepKind::IsConstFn => { force!(is_const_fn, def_id!()); }
+        DepKind::IsForeignItem => { force!(is_foreign_item, def_id!()); }
+        DepKind::SizedConstraint => { force!(adt_sized_constraint, def_id!()); }
+        DepKind::DtorckConstraint => { force!(adt_dtorck_constraint, def_id!()); }
+        DepKind::AdtDestructor => { force!(adt_destructor, def_id!()); }
+        DepKind::AssociatedItemDefIds => { force!(associated_item_def_ids, def_id!()); }
+        DepKind::InherentImpls => { force!(inherent_impls, def_id!()); }
+        DepKind::TypeckBodiesKrate => { force!(typeck_item_bodies, LOCAL_CRATE); }
+        DepKind::TypeckTables => { force!(typeck_tables_of, def_id!()); }
+        DepKind::UsedTraitImports => { force!(used_trait_imports, def_id!()); }
+        DepKind::HasTypeckTables => { force!(has_typeck_tables, def_id!()); }
+        DepKind::SymbolName => { force!(def_symbol_name, def_id!()); }
+        DepKind::SpecializationGraph => { force!(specialization_graph_of, def_id!()); }
+        DepKind::ObjectSafety => { force!(is_object_safe, def_id!()); }
+        DepKind::TraitImpls => { force!(trait_impls_of, def_id!()); }
+        DepKind::CheckMatch => { force!(check_match, def_id!()); }
+
+        DepKind::ParamEnv => { force!(param_env, def_id!()); }
+        DepKind::DescribeDef => { force!(describe_def, def_id!()); }
+        DepKind::DefSpan => { force!(def_span, def_id!()); }
+        DepKind::LookupStability => { force!(lookup_stability, def_id!()); }
+        DepKind::LookupDeprecationEntry => {
+            force!(lookup_deprecation_entry, def_id!());
+        }
+        DepKind::ConstIsRvaluePromotableToStatic => {
+            force!(const_is_rvalue_promotable_to_static, def_id!());
+        }
+        DepKind::RvaluePromotableMap => { force!(rvalue_promotable_map, def_id!()); }
+        DepKind::ImplParent => { force!(impl_parent, def_id!()); }
+        DepKind::TraitOfItem => { force!(trait_of_item, def_id!()); }
+        DepKind::IsReachableNonGeneric => { force!(is_reachable_non_generic, def_id!()); }
+        DepKind::IsUnreachableLocalDefinition => {
+            force!(is_unreachable_local_definition, def_id!());
+        }
+        DepKind::IsMirAvailable => { force!(is_mir_available, def_id!()); }
+        DepKind::ItemAttrs => { force!(item_attrs, def_id!()); }
+        DepKind::CodegenFnAttrs => { force!(codegen_fn_attrs, def_id!()); }
+        DepKind::FnArgNames => { force!(fn_arg_names, def_id!()); }
+        DepKind::RenderedConst => { force!(rendered_const, def_id!()); }
+        DepKind::DylibDepFormats => { force!(dylib_dependency_formats, krate!()); }
+        DepKind::IsPanicRuntime => { force!(is_panic_runtime, krate!()); }
+        DepKind::IsCompilerBuiltins => { force!(is_compiler_builtins, krate!()); }
+        DepKind::HasGlobalAllocator => { force!(has_global_allocator, krate!()); }
+        DepKind::ExternCrate => { force!(extern_crate, def_id!()); }
+        DepKind::LintLevels => { force!(lint_levels, LOCAL_CRATE); }
+        DepKind::InScopeTraits => { force!(in_scope_traits_map, def_id!().index); }
+        DepKind::ModuleExports => { force!(module_exports, def_id!()); }
+        DepKind::IsSanitizerRuntime => { force!(is_sanitizer_runtime, krate!()); }
+        DepKind::IsProfilerRuntime => { force!(is_profiler_runtime, krate!()); }
+        DepKind::GetPanicStrategy => { force!(panic_strategy, krate!()); }
+        DepKind::IsNoBuiltins => { force!(is_no_builtins, krate!()); }
+        DepKind::ImplDefaultness => { force!(impl_defaultness, def_id!()); }
+        DepKind::CheckItemWellFormed => { force!(check_item_well_formed, def_id!()); }
+        DepKind::CheckTraitItemWellFormed => { force!(check_trait_item_well_formed, def_id!()); }
+        DepKind::CheckImplItemWellFormed => { force!(check_impl_item_well_formed, def_id!()); }
+        DepKind::ReachableNonGenerics => { force!(reachable_non_generics, krate!()); }
+        DepKind::NativeLibraries => { force!(native_libraries, krate!()); }
+        DepKind::PluginRegistrarFn => { force!(plugin_registrar_fn, krate!()); }
+        DepKind::DeriveRegistrarFn => { force!(derive_registrar_fn, krate!()); }
+        DepKind::CrateDisambiguator => { force!(crate_disambiguator, krate!()); }
+        DepKind::CrateHash => { force!(crate_hash, krate!()); }
+        DepKind::OriginalCrateName => { force!(original_crate_name, krate!()); }
+        DepKind::ExtraFileName => { force!(extra_filename, krate!()); }
+
+        DepKind::AllTraitImplementations => {
+            force!(all_trait_implementations, krate!());
+        }
+
+        DepKind::DllimportForeignItems => {
+            force!(dllimport_foreign_items, krate!());
+        }
+        DepKind::IsDllimportForeignItem => {
+            force!(is_dllimport_foreign_item, def_id!());
+        }
+        DepKind::IsStaticallyIncludedForeignItem => {
+            force!(is_statically_included_foreign_item, def_id!());
+        }
+        DepKind::NativeLibraryKind => { force!(native_library_kind, def_id!()); }
+        DepKind::LinkArgs => { force!(link_args, LOCAL_CRATE); }
+
+        DepKind::ResolveLifetimes => { force!(resolve_lifetimes, krate!()); }
+        DepKind::NamedRegion => { force!(named_region_map, def_id!().index); }
+        DepKind::IsLateBound => { force!(is_late_bound_map, def_id!().index); }
+        DepKind::ObjectLifetimeDefaults => {
+            force!(object_lifetime_defaults_map, def_id!().index);
+        }
+
+        DepKind::Visibility => { force!(visibility, def_id!()); }
+        DepKind::DepKind => { force!(dep_kind, krate!()); }
+        DepKind::CrateName => { force!(crate_name, krate!()); }
+        DepKind::ItemChildren => { force!(item_children, def_id!()); }
+        DepKind::ExternModStmtCnum => { force!(extern_mod_stmt_cnum, def_id!()); }
+        DepKind::GetLangItems => { force!(get_lang_items, LOCAL_CRATE); }
+        DepKind::DefinedLangItems => { force!(defined_lang_items, krate!()); }
+        DepKind::MissingLangItems => { force!(missing_lang_items, krate!()); }
+        DepKind::VisibleParentMap => { force!(visible_parent_map, LOCAL_CRATE); }
+        DepKind::MissingExternCrateItem => {
+            force!(missing_extern_crate_item, krate!());
+        }
+        DepKind::UsedCrateSource => { force!(used_crate_source, krate!()); }
+        DepKind::PostorderCnums => { force!(postorder_cnums, LOCAL_CRATE); }
+
+        DepKind::Freevars => { force!(freevars, def_id!()); }
+        DepKind::MaybeUnusedTraitImport => {
+            force!(maybe_unused_trait_import, def_id!());
+        }
+        DepKind::MaybeUnusedExternCrates => { force!(maybe_unused_extern_crates, LOCAL_CRATE); }
+        DepKind::StabilityIndex => { force!(stability_index, LOCAL_CRATE); }
+        DepKind::AllTraits => { force!(all_traits, LOCAL_CRATE); }
+        DepKind::AllCrateNums => { force!(all_crate_nums, LOCAL_CRATE); }
+        DepKind::ExportedSymbols => { force!(exported_symbols, krate!()); }
+        DepKind::CollectAndPartitionMonoItems => {
+            force!(collect_and_partition_mono_items, LOCAL_CRATE);
+        }
+        DepKind::IsCodegenedItem => { force!(is_codegened_item, def_id!()); }
+        DepKind::OutputFilenames => { force!(output_filenames, LOCAL_CRATE); }
+
+        DepKind::TargetFeaturesWhitelist => { force!(target_features_whitelist, LOCAL_CRATE); }
+
+        DepKind::Features => { force!(features_query, LOCAL_CRATE); }
+
+        DepKind::ProgramClausesFor => { force!(program_clauses_for, def_id!()); }
+        DepKind::WasmCustomSections => { force!(wasm_custom_sections, krate!()); }
+        DepKind::WasmImportModuleMap => { force!(wasm_import_module_map, krate!()); }
+        DepKind::ForeignModules => { force!(foreign_modules, krate!()); }
+
+        DepKind::UpstreamMonomorphizations => {
+            force!(upstream_monomorphizations, krate!());
+        }
+        DepKind::UpstreamMonomorphizationsFor => {
+            force!(upstream_monomorphizations_for, def_id!());
+        }
+    }
+
+    true
+}
+
+
+// FIXME(#45015): Another piece of boilerplate code that could be generated in
+//                a combined define_dep_nodes!()/define_queries!() macro.
+macro_rules! impl_load_from_cache {
+    ($($dep_kind:ident => $query_name:ident,)*) => {
+        impl DepNode {
+            // Check whether the query invocation corresponding to the given
+            // DepNode is eligible for on-disk-caching.
+            pub fn cache_on_disk(&self, tcx: TyCtxt) -> bool {
+                use ty::query::queries;
+                use ty::query::QueryDescription;
+
+                match self.kind {
+                    $(DepKind::$dep_kind => {
+                        let def_id = self.extract_def_id(tcx).unwrap();
+                        queries::$query_name::cache_on_disk(def_id)
+                    })*
+                    _ => false
+                }
+            }
+
+            // This is method will execute the query corresponding to the given
+            // DepNode. It is only expected to work for DepNodes where the
+            // above `cache_on_disk` methods returns true.
+            // Also, as a sanity check, it expects that the corresponding query
+            // invocation has been marked as green already.
+            pub fn load_from_on_disk_cache(&self, tcx: TyCtxt) {
+                match self.kind {
+                    $(DepKind::$dep_kind => {
+                        debug_assert!(tcx.dep_graph
+                                         .node_color(self)
+                                         .map(|c| c.is_green())
+                                         .unwrap_or(false));
+
+                        let def_id = self.extract_def_id(tcx).unwrap();
+                        let _ = tcx.$query_name(def_id);
+                    })*
+                    _ => {
+                        bug!()
+                    }
+                }
+            }
+        }
+    }
+}
+
+impl_load_from_cache!(
+    TypeckTables => typeck_tables_of,
+    MirOptimized => optimized_mir,
+    UnsafetyCheckResult => unsafety_check_result,
+    BorrowCheck => borrowck,
+    MirBorrowCheck => mir_borrowck,
+    MirConstQualif => mir_const_qualif,
+    SymbolName => def_symbol_name,
+    ConstIsRvaluePromotableToStatic => const_is_rvalue_promotable_to_static,
+    CheckMatch => check_match,
+    TypeOfItem => type_of,
+    GenericsOfItem => generics_of,
+    PredicatesOfItem => predicates_of,
+    UsedTraitImports => used_trait_imports,
+    CodegenFnAttrs => codegen_fn_attrs,
+    SpecializationGraph => specialization_graph_of,
+);
diff --git a/src/librustc/ty/query/values.rs b/src/librustc/ty/query/values.rs
new file mode 100644 (file)
index 0000000..d3d0624
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use ty::{self, Ty, TyCtxt};
+
+use syntax::symbol::Symbol;
+
+pub(super) trait Value<'tcx>: Sized {
+    fn from_cycle_error<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self;
+}
+
+impl<'tcx, T> Value<'tcx> for T {
+    default fn from_cycle_error<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> T {
+        tcx.sess.abort_if_errors();
+        bug!("Value::from_cycle_error called without errors");
+    }
+}
+
+impl<'tcx, T: Default> Value<'tcx> for T {
+    default fn from_cycle_error<'a>(_: TyCtxt<'a, 'tcx, 'tcx>) -> T {
+        T::default()
+    }
+}
+
+impl<'tcx> Value<'tcx> for Ty<'tcx> {
+    fn from_cycle_error<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
+        tcx.types.err
+    }
+}
+
+impl<'tcx> Value<'tcx> for ty::SymbolName {
+    fn from_cycle_error<'a>(_: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
+        ty::SymbolName { name: Symbol::intern("<error>").as_interned_str() }
+    }
+}
+
index 9ef3308efe6d98fda0643e986d21af1db7d42be0..20ebd6206259660c2fa3d90ebb3212ed369240fc 100644 (file)
@@ -18,7 +18,7 @@
 use traits::{self, ObligationCause};
 use ty::{self, Ty, TyCtxt, GenericParamDefKind, TypeFoldable};
 use ty::subst::{Substs, UnpackedKind};
-use ty::maps::TyCtxtAt;
+use ty::query::TyCtxtAt;
 use ty::TypeVariants::*;
 use ty::layout::{Integer, IntegerExt};
 use util::common::ErrorReported;
@@ -415,7 +415,7 @@ pub fn calculate_dtor(
             return None;
         };
 
-        ty::maps::queries::coherent_trait::ensure(self, drop_trait);
+        ty::query::queries::coherent_trait::ensure(self, drop_trait);
 
         let mut dtor_did = None;
         let ty = self.type_of(adt_did);
@@ -883,7 +883,7 @@ fn needs_drop_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let (param_env, ty) = query.into_parts();
 
     let needs_drop = |ty: Ty<'tcx>| -> bool {
-        match tcx.try_get_query::<ty::queries::needs_drop_raw>(DUMMY_SP, param_env.and(ty)) {
+        match tcx.try_needs_drop_raw(DUMMY_SP, param_env.and(ty)) {
             Ok(v) => v,
             Err(mut bug) => {
                 // Cycles should be reported as an error by `check_representable`.
@@ -1014,8 +1014,8 @@ pub fn determine<P>(
     }
 }
 
-pub fn provide(providers: &mut ty::maps::Providers) {
-    *providers = ty::maps::Providers {
+pub fn provide(providers: &mut ty::query::Providers) {
+    *providers = ty::query::Providers {
         is_copy_raw,
         is_sized_raw,
         is_freeze_raw,
index e063880028fc9a1c4d3b6069f4f3853adb94cc63..11d35def007747f5493adfcab2b22b0f006f79d0 100644 (file)
@@ -37,7 +37,7 @@
 use rustc::middle::region;
 use rustc::middle::free_region::RegionRelations;
 use rustc::ty::{self, Ty, TyCtxt};
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc_mir::util::borrowck_errors::{BorrowckErrors, Origin};
 use rustc::util::nodemap::FxHashSet;
 
@@ -128,7 +128,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId)
     // Note that `mir_validated` is a "stealable" result; the
     // thief, `optimized_mir()`, forces borrowck, so we know that
     // is not yet stolen.
-    ty::maps::queries::mir_validated::ensure(tcx, owner_def_id);
+    ty::query::queries::mir_validated::ensure(tcx, owner_def_id);
 
     // option dance because you can't capture an uninitialized variable
     // by mut-ref.
index d6806e7afd306ef2ede905df3a5d6725f803b71f..a5d04c5c576b22e3c2d89e0c611ec58da7f88372 100644 (file)
@@ -17,7 +17,7 @@
 use rustc::session::Session;
 use rustc::session::config::Sanitizer;
 use rustc::ty::TyCtxt;
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_target::spec::PanicStrategy;
index 81ac684aee245b222dd89e7b21abc7f6bea65c45..28e76a80513f034cac14e80dc73c03859ff4c572 100644 (file)
@@ -19,7 +19,7 @@
 use rustc::middle::exported_symbols::{SymbolExportLevel, ExportedSymbol, metadata_symbol_name};
 use rustc::session::config;
 use rustc::ty::{TyCtxt, SymbolName};
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::ty::subst::Substs;
 use rustc::util::nodemap::{FxHashMap, DefIdMap};
 use rustc_allocator::ALLOCATOR_METHODS;
index 8660c0bcc6c3f079225f58a911b4a5c8665c28fe..322924535d1f72baeb5588eecad1f606043e09e3 100644 (file)
@@ -41,7 +41,7 @@
 use rustc::middle::cstore::{EncodedMetadata};
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::layout::{self, Align, TyLayout, LayoutOf};
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::dep_graph::{DepNode, DepConstructor};
 use rustc::middle::cstore::{self, LinkMeta, LinkagePreference};
 use rustc::middle::exported_symbols;
index 0b0bab96dfdfd94f018ed1c22088046305524a13..8732e115fd2fd967cc51ffc52a681de11f6db060 100644 (file)
@@ -183,14 +183,14 @@ fn metadata_loader(&self) -> Box<MetadataLoader + Sync> {
         box metadata::LlvmMetadataLoader
     }
 
-    fn provide(&self, providers: &mut ty::maps::Providers) {
+    fn provide(&self, providers: &mut ty::query::Providers) {
         back::symbol_names::provide(providers);
         back::symbol_export::provide(providers);
         base::provide(providers);
         attributes::provide(providers);
     }
 
-    fn provide_extern(&self, providers: &mut ty::maps::Providers) {
+    fn provide_extern(&self, providers: &mut ty::query::Providers) {
         back::symbol_export::provide_extern(providers);
         base::provide_extern(providers);
         attributes::provide_extern(providers);
index 15aab680289eb87163eb3c24676bc1e0aa1bdd1a..8ba6f30cf16e587b7cb8441f0af808cde34c9699 100644 (file)
@@ -39,7 +39,7 @@
 use rustc::session::{Session, CompileIncomplete};
 use rustc::session::config::{CrateType, OutputFilenames, PrintRequest};
 use rustc::ty::TyCtxt;
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::middle::cstore::EncodedMetadata;
 use rustc::middle::cstore::MetadataLoader;
 use rustc::dep_graph::DepGraph;
index 123816c1f97dfc8ef9fa000ee81a23ff19d40dfd..dcb82e5c424e5305770d3faee1eaebe7916e5a8a 100644 (file)
 use rustc::ich::NodeIdHashingMode;
 use rustc::middle::weak_lang_items;
 use rustc::ty::item_path::{self, ItemPathBuffer, RootMode};
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::ty::subst::Substs;
 use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc::util::common::record_time;
index 37f8bff964f5b1e880ae08684b17e67c133f9453..5d5baf765497ef8b883af96482fbf97e07059eab 100644 (file)
@@ -87,7 +87,7 @@ pub fn spawn_thread_pool<F: FnOnce(config::Options) -> R + sync::Send, R: sync::
 
     let config = ThreadPoolBuilder::new()
         .num_threads(Session::query_threads_from_opts(&opts))
-        .deadlock_handler(|| unsafe { ty::maps::handle_deadlock() })
+        .deadlock_handler(|| unsafe { ty::query::handle_deadlock() })
         .stack_size(16 * 1024 * 1024);
 
     let with_pool = move |pool: &ThreadPool| {
@@ -399,10 +399,10 @@ pub struct CompileController<'a> {
 
     /// Allows overriding default rustc query providers,
     /// after `default_provide` has installed them.
-    pub provide: Box<Fn(&mut ty::maps::Providers) + 'a>,
+    pub provide: Box<Fn(&mut ty::query::Providers) + 'a>,
     /// Same as `provide`, but only for non-local crates,
     /// applied after `default_provide_extern`.
-    pub provide_extern: Box<Fn(&mut ty::maps::Providers) + 'a>,
+    pub provide_extern: Box<Fn(&mut ty::query::Providers) + 'a>,
 }
 
 impl<'a> CompileController<'a> {
@@ -1140,7 +1140,7 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(
     })
 }
 
-pub fn default_provide(providers: &mut ty::maps::Providers) {
+pub fn default_provide(providers: &mut ty::query::Providers) {
     hir::provide(providers);
     borrowck::provide(providers);
     mir::provide(providers);
@@ -1158,7 +1158,7 @@ pub fn default_provide(providers: &mut ty::maps::Providers) {
     lint::provide(providers);
 }
 
-pub fn default_provide_extern(providers: &mut ty::maps::Providers) {
+pub fn default_provide_extern(providers: &mut ty::query::Providers) {
     cstore::provide_extern(providers);
 }
 
@@ -1203,7 +1203,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(
 
     time(sess, "loop checking", || loops::check_crate(sess, &hir_map));
 
-    let mut local_providers = ty::maps::Providers::default();
+    let mut local_providers = ty::query::Providers::default();
     default_provide(&mut local_providers);
     codegen_backend.provide(&mut local_providers);
     (control.provide)(&mut local_providers);
index 206e58b3e2e2764df976c384e81874b55bffa30f..17e0472bda93fbdee39a201266349dba837e3304 100644 (file)
@@ -20,7 +20,7 @@
 use rustc::ty::subst::Subst;
 use rustc::traits::ObligationCause;
 use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
-use rustc::ty::maps::OnDiskCache;
+use rustc::ty::query::OnDiskCache;
 use rustc::infer::{self, InferOk, InferResult};
 use rustc::infer::outlives::env::OutlivesEnvironment;
 use rustc::infer::type_variable::TypeVariableOrigin;
@@ -157,8 +157,8 @@ fn test_env_with_pool<F>(
     };
     TyCtxt::create_and_enter(&sess,
                              &cstore,
-                             ty::maps::Providers::default(),
-                             ty::maps::Providers::default(),
+                             ty::query::Providers::default(),
+                             ty::query::Providers::default(),
                              &arenas,
                              resolutions,
                              hir_map,
index 1549ef5e928c7ef4c581ce77d3890b04d69e2463..eeb87e4175704904b07a2c6c309106633246e596 100644 (file)
@@ -385,7 +385,7 @@ fn auto_labels(&mut self, item_id: ast::NodeId, attr: &Attribute) -> (&'static s
                     // michaelwoerister and vitiral came up with a possible solution,
                     // to just do this before every query
                     // ```
-                    // ::rustc::ty::maps::plumbing::force_from_dep_node(tcx, dep_node)
+                    // ::rustc::ty::query::plumbing::force_from_dep_node(tcx, dep_node)
                     // ```
                     //
                     // However, this did not seem to work effectively and more bugs were hit.
index f846759545eb949fbf82cf122be625c2325b7cad..9ee3b216dcf404ca364b07306c6632ad454ddedc 100644 (file)
@@ -14,7 +14,7 @@
 use rustc::dep_graph::{PreviousDepGraph, SerializedDepGraph, WorkProduct, WorkProductId};
 use rustc::session::Session;
 use rustc::ty::TyCtxt;
-use rustc::ty::maps::OnDiskCache;
+use rustc::ty::query::OnDiskCache;
 use rustc::util::common::time_ext;
 use rustc_serialize::Decodable as RustcDecodable;
 use rustc_serialize::opaque::Decoder;
index 4691027e3b1d2ac15c2107bb36d7e2e6e055776b..b33d97cb1ee9f7988d17e99bd8bf72f71ba75e64 100644 (file)
@@ -15,7 +15,7 @@
 use foreign_modules;
 use schema;
 
-use rustc::ty::maps::QueryConfig;
+use rustc::ty::query::QueryConfig;
 use rustc::middle::cstore::{CrateStore, DepKind,
                             MetadataLoader, LinkMeta,
                             LoadedMacro, EncodedMetadata, NativeLibraryKind};
@@ -24,7 +24,7 @@
 use rustc::hir::def;
 use rustc::session::{CrateDisambiguator, Session};
 use rustc::ty::{self, TyCtxt};
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE, CRATE_DEF_INDEX};
 use rustc::hir::map::{DefKey, DefPath, DefPathHash};
 use rustc::hir::map::blocks::FnLikeNode;
index ba0557d062f2427d8a633e8697ee2165db92c6b1..c43ea0360ee1394101d923fbe5d9aab4b42eba44 100644 (file)
@@ -16,7 +16,7 @@
 use rustc::hir::map::definitions::DefPathData;
 use rustc::infer::InferCtxt;
 use rustc::ty::{self, ParamEnv, TyCtxt};
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::lint::builtin::UNUSED_MUT;
 use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
 use rustc::mir::{ClearCrossCrate, Local, Location, Place, Mir, Mutability, Operand};
index 3e91fa72cae58c0903f7b4f90c283a260c98ee61..ea667273ecead0b3fc066d528d8fa9502055a244 100644 (file)
@@ -8,7 +8,7 @@
 use rustc::ty::layout::{self, Size, Align, HasDataLayout, IntegerExt, LayoutOf, TyLayout};
 use rustc::ty::subst::{Subst, Substs};
 use rustc::ty::{self, Ty, TyCtxt, TypeAndMut};
-use rustc::ty::maps::TyCtxtAt;
+use rustc::ty::query::TyCtxtAt;
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
 use rustc::middle::const_val::FrameInfo;
 use syntax::codemap::{self, Span};
index ec308c2193d567bcecc937af5a7f3fd24084850a..ad571fbe90d5d0918a585da04bd817a35fa2dfa9 100644 (file)
@@ -4,7 +4,7 @@
 use rustc::hir::def_id::DefId;
 use rustc::ty::Instance;
 use rustc::ty::ParamEnv;
-use rustc::ty::maps::TyCtxtAt;
+use rustc::ty::query::TyCtxtAt;
 use rustc::ty::layout::{self, Align, TargetDataLayout, Size};
 use syntax::ast::Mutability;
 use rustc::middle::const_val::ConstVal;
index 34eb444fdc0cbf59a0ec1d32df22a1247214ce11..d815d4a7dba917ef1477acfe307616acc3852f06 100644 (file)
@@ -67,7 +67,7 @@
 pub mod monomorphize;
 
 pub use hair::pattern::check_crate as matchck_crate;
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 
 pub fn provide(providers: &mut Providers) {
     borrow_check::provide(providers);
index d4a9b2cdd1fbf4022b819540a16387dca7211e8a..f11d80201c28b4653351704eb6ee4216c4668e10 100644 (file)
@@ -14,7 +14,7 @@
 use rustc::mir::*;
 use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind};
 use rustc::ty::subst::{Subst, Substs};
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
 
index 4c282f037a5cc9c663168c78bdab4ff1333b70c5..5f8f9acae838515a45f81ffdef12ef3579a130aa 100644 (file)
@@ -12,7 +12,7 @@
 use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_data_structures::sync::Lrc;
 
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::ty::{self, TyCtxt};
 use rustc::hir;
 use rustc::hir::def_id::DefId;
index a1845f7ef268cd15a0b304c1ca67d1ad5cd092af..cb57dc572fa240e7f7c73ba7b0f7504050fb7bb5 100644 (file)
@@ -126,9 +126,8 @@ fn run_pass(&self, caller_mir: &mut Mir<'tcx>) {
                     continue;
                 }
 
-                let callee_mir = match self.tcx.try_get_query::<ty::queries::optimized_mir>(
-                                                                           callsite.location.span,
-                                                                           callsite.callee) {
+                let callee_mir = match self.tcx.try_optimized_mir(callsite.location.span,
+                                                                  callsite.callee) {
                     Ok(callee_mir) if self.should_inline(callsite, callee_mir) => {
                         self.tcx.subst_and_normalize_erasing_regions(
                             &callsite.substs,
index e2f2312dbd204a79a346ad1dd01d2dec85b528f4..06be2bb3734f438e8defeb49c3148e2db83f2c7a 100644 (file)
@@ -13,7 +13,7 @@
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc::mir::{Mir, Promoted};
 use rustc::ty::TyCtxt;
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::ty::steal::Steal;
 use rustc::hir;
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
index f3fba5b47be14080d99de722ae123fc29a3ba1b8..6448ba17e3464480eb8d2c478dead103c1a5e1d0 100644 (file)
@@ -24,7 +24,7 @@
 use rustc::traits::{self, TraitEngine};
 use rustc::ty::{self, TyCtxt, Ty, TypeFoldable};
 use rustc::ty::cast::CastTy;
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::mir::*;
 use rustc::mir::traversal::ReversePostorder;
 use rustc::mir::visit::{PlaceContext, Visitor};
index b6b5edc094003c2215a26cf031804c650bf865d5..41f1e7829658ab097353ca1a3fa7b26061d9226b 100644 (file)
@@ -32,7 +32,7 @@
 extern crate syntax_pos;
 extern crate rustc_errors as errors;
 
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 
 mod diagnostics;
 
index 82ac112b534e9f5dd317633a0209cf903de0866a..51b2988023b4a08b0dfecbd932ee69ff291ede52 100644 (file)
@@ -32,7 +32,7 @@
 use rustc::middle::mem_categorization as mc;
 use rustc::middle::mem_categorization::Categorization;
 use rustc::ty::{self, Ty, TyCtxt};
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::ty::subst::Substs;
 use rustc::util::nodemap::{ItemLocalSet, NodeSet};
 use rustc::hir;
index f32f6eda8ff59c077970e9b120e1b8b319b906cb..308c5b9f201562b397d1a1ceff4e77db18c39f61 100644 (file)
@@ -31,7 +31,7 @@
 use rustc::middle::privacy::{AccessLevel, AccessLevels};
 use rustc::ty::{self, TyCtxt, Ty, TypeFoldable, GenericParamDefKind};
 use rustc::ty::fold::TypeVisitor;
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::ty::subst::UnpackedKind;
 use rustc::util::nodemap::NodeSet;
 use syntax::ast::{self, CRATE_NODE_ID, Ident};
index 7fa69cb98338dbee5b6d44acf56f515158fbae17..c3135439204e7c69456fe2243d9d207cbfb4875e 100644 (file)
@@ -36,7 +36,7 @@
 mod util;
 pub mod lowering;
 
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 
 pub fn provide(p: &mut Providers) {
     *p = Providers {
index 169caf1f672667e7c064f3ce8e17d5b6b57fdc0d..a51876d7960b0bd46ba575d7ab0980007779452b 100644 (file)
@@ -40,7 +40,7 @@
 
 use self::probe::{IsSuggestion, ProbeScope};
 
-pub fn provide(providers: &mut ty::maps::Providers) {
+pub fn provide(providers: &mut ty::query::Providers) {
     suggest::provide(providers);
 }
 
index 86cd8d0fb2c5207c0cdd5846ad235bb29e4583a7..90680b4156e7a825693bc6399eb9ebd360e2de21 100644 (file)
@@ -741,7 +741,7 @@ fn handle_external_def(tcx: TyCtxt,
     traits
 }
 
-pub fn provide(providers: &mut ty::maps::Providers) {
+pub fn provide(providers: &mut ty::query::Providers) {
     providers.all_traits = |tcx, cnum| {
         assert_eq!(cnum, LOCAL_CRATE);
         Lrc::new(compute_all_traits(tcx))
index 533faadc3a45dce50cbcc6d5157b53d95ce6b514..7dcd6d1a3b350061713bda5ca6743578c475ba2c 100644 (file)
@@ -99,7 +99,7 @@
 use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind, Visibility, ToPredicate, RegionKind};
 use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
 use rustc::ty::fold::TypeFoldable;
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::ty::util::{Representability, IntTypeExt, Discr};
 use errors::{DiagnosticBuilder, DiagnosticId};
 
@@ -703,7 +703,7 @@ fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum
     debug_assert!(crate_num == LOCAL_CRATE);
     Ok(tcx.sess.track_errors(|| {
         for body_owner_def_id in tcx.body_owners() {
-            ty::maps::queries::typeck_tables_of::ensure(tcx, body_owner_def_id);
+            ty::query::queries::typeck_tables_of::ensure(tcx, body_owner_def_id);
         }
     })?)
 }
index 65725bfb95d0e281bbcc4e5a8647f0ae80647cef..7a2c38468e0448735811240adf0cbe4dc2ee2fe1 100644 (file)
@@ -749,21 +749,21 @@ fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> {
     fn visit_item(&mut self, i: &hir::Item) {
         debug!("visit_item: {:?}", i);
         let def_id = self.tcx.hir.local_def_id(i.id);
-        ty::maps::queries::check_item_well_formed::ensure(self.tcx, def_id);
+        ty::query::queries::check_item_well_formed::ensure(self.tcx, def_id);
         intravisit::walk_item(self, i);
     }
 
     fn visit_trait_item(&mut self, trait_item: &'v hir::TraitItem) {
         debug!("visit_trait_item: {:?}", trait_item);
         let def_id = self.tcx.hir.local_def_id(trait_item.id);
-        ty::maps::queries::check_trait_item_well_formed::ensure(self.tcx, def_id);
+        ty::query::queries::check_trait_item_well_formed::ensure(self.tcx, def_id);
         intravisit::walk_trait_item(self, trait_item)
     }
 
     fn visit_impl_item(&mut self, impl_item: &'v hir::ImplItem) {
         debug!("visit_impl_item: {:?}", impl_item);
         let def_id = self.tcx.hir.local_def_id(impl_item.id);
-        ty::maps::queries::check_impl_item_well_formed::ensure(self.tcx, def_id);
+        ty::query::queries::check_impl_item_well_formed::ensure(self.tcx, def_id);
         intravisit::walk_impl_item(self, impl_item)
     }
 }
index 07b7c600b9f308b61a6873622c03d73a0dc7cf96..e92349040e89efdb5acf68c4029b1be5a3b1fa2c 100644 (file)
@@ -18,7 +18,7 @@
 use hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::traits;
 use rustc::ty::{self, TyCtxt, TypeFoldable};
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 
 use syntax::ast;
 
@@ -127,15 +127,15 @@ fn coherent_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
 
 pub fn check_coherence<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     for &trait_def_id in tcx.hir.krate().trait_impls.keys() {
-        ty::maps::queries::coherent_trait::ensure(tcx, trait_def_id);
+        ty::query::queries::coherent_trait::ensure(tcx, trait_def_id);
     }
 
     unsafety::check(tcx);
     orphan::check(tcx);
 
     // these queries are executed for side-effects (error reporting):
-    ty::maps::queries::crate_inherent_impls::ensure(tcx, LOCAL_CRATE);
-    ty::maps::queries::crate_inherent_impls_overlap_check::ensure(tcx, LOCAL_CRATE);
+    ty::query::queries::crate_inherent_impls::ensure(tcx, LOCAL_CRATE);
+    ty::query::queries::crate_inherent_impls_overlap_check::ensure(tcx, LOCAL_CRATE);
 }
 
 /// Overlap: No two impls for the same trait are implemented for the
index a982724f957e9b88cc5881d483b184224515c324..05256be6ec91008461179625d457e6b28ae059f2 100644 (file)
@@ -33,7 +33,7 @@
 use rustc::ty::subst::Substs;
 use rustc::ty::{ToPredicate, ReprOptions};
 use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt};
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::ty::util::IntTypeExt;
 use rustc::ty::util::Discr;
 use rustc::util::captures::Captures;
index 5b7d92944edf23cc1eeb925de2601cc7d7069451..ce7249bd7b5b719d32ae985d828953168d7bc5f1 100644 (file)
 use rustc::infer::InferOk;
 use rustc::ty::subst::Substs;
 use rustc::ty::{self, Ty, TyCtxt};
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::traits::{ObligationCause, ObligationCauseCode, TraitEngine};
 use session::{CompileIncomplete, config};
 use util::common::time;
index b5ba59d64cdc45d099549ace529532d9ad40e4a5..c6c7e8f931f8b0bbf14270beccab1164d5d79208 100644 (file)
@@ -11,7 +11,7 @@
 use hir::map as hir_map;
 use rustc::hir;
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::ty::subst::UnpackedKind;
 use rustc::ty::{self, CratePredicatesMap, TyCtxt};
 use rustc_data_structures::sync::Lrc;
index fd2b964103a3026a3c957b8f05f58b2e52ca6a58..adea9788b3c5408257a754516d4f3d849922da2f 100644 (file)
@@ -17,7 +17,7 @@
 use rustc::hir;
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc::ty::{self, CrateVariancesMap, TyCtxt};
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc_data_structures::sync::Lrc;
 
 /// Defines the `TermsContext` basically houses an arena where we can
index 251fb78a98588160459802a01f4704329a72481b..439bc017fee618ce357141a56618f8f07f2c47b3 100644 (file)
@@ -20,7 +20,7 @@
 use rustc::session::{Session, CompileIncomplete};
 use rustc::session::config::OutputFilenames;
 use rustc::ty::TyCtxt;
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::middle::cstore::MetadataLoader;
 use rustc::dep_graph::DepGraph;
 use rustc_codegen_utils::codegen_backend::{CodegenBackend, MetadataOnlyCodegenBackend};