]> git.lizzy.rs Git - rust.git/blob - src/librustc/ty/query/plumbing.rs
Fix more missed query data
[rust.git] / src / librustc / ty / query / plumbing.rs
1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! The implementation of the query system itself. Defines the macros
12 //! that generate the actual methods on tcx which find and execute the
13 //! provider, manage the caches, and so forth.
14
15 use dep_graph::{DepNodeIndex, DepNode, DepKind, DepNodeColor};
16 use errors::DiagnosticBuilder;
17 use errors::Level;
18 use errors::Diagnostic;
19 use errors::FatalError;
20 use ty::tls;
21 use ty::{TyCtxt};
22 use ty::query::Query;
23 use ty::query::config::{QueryConfig, QueryDescription};
24 use ty::query::job::{QueryJob, QueryResult, QueryInfo};
25 use ty::item_path;
26
27 use util::common::{profq_msg, ProfileQueriesMsg, QueryMsg};
28
29 use rustc_data_structures::fx::{FxHashMap};
30 use rustc_data_structures::sync::{Lrc, Lock};
31 use std::mem;
32 use std::ptr;
33 use std::collections::hash_map::Entry;
34 use syntax_pos::Span;
35 use syntax::codemap::DUMMY_SP;
36
37 pub struct QueryCache<'tcx, D: QueryConfig<'tcx> + ?Sized> {
38     pub(super) results: FxHashMap<D::Key, QueryValue<D::Value>>,
39     pub(super) active: FxHashMap<D::Key, QueryResult<'tcx>>,
40 }
41
42 pub(super) struct QueryValue<T> {
43     pub(super) value: T,
44     pub(super) index: DepNodeIndex,
45 }
46
47 impl<T> QueryValue<T> {
48     pub(super) fn new(value: T,
49                       dep_node_index: DepNodeIndex)
50                       -> QueryValue<T> {
51         QueryValue {
52             value,
53             index: dep_node_index,
54         }
55     }
56 }
57
58 impl<'tcx, M: QueryConfig<'tcx>> QueryCache<'tcx, M> {
59     pub(super) fn new() -> QueryCache<'tcx, M> {
60         QueryCache {
61             results: FxHashMap(),
62             active: FxHashMap(),
63         }
64     }
65 }
66
67 // If enabled, send a message to the profile-queries thread
68 macro_rules! profq_msg {
69     ($tcx:expr, $msg:expr) => {
70         if cfg!(debug_assertions) {
71             if $tcx.sess.profile_queries() {
72                 profq_msg($tcx.sess, $msg)
73             }
74         }
75     }
76 }
77
78 // If enabled, format a key using its debug string, which can be
79 // expensive to compute (in terms of time).
80 macro_rules! profq_query_msg {
81     ($query:expr, $tcx:expr, $key:expr) => {{
82         let msg = if cfg!(debug_assertions) {
83             if $tcx.sess.profile_queries_and_keys() {
84                 Some(format!("{:?}", $key))
85             } else { None }
86         } else { None };
87         QueryMsg {
88             query: $query,
89             msg,
90         }
91     }}
92 }
93
94 /// A type representing the responsibility to execute the job in the `job` field.
95 /// This will poison the relevant query if dropped.
96 pub(super) struct JobOwner<'a, 'tcx: 'a, Q: QueryDescription<'tcx> + 'a> {
97     cache: &'a Lock<QueryCache<'tcx, Q>>,
98     key: Q::Key,
99     job: Lrc<QueryJob<'tcx>>,
100 }
101
102 impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
103     /// Either gets a JobOwner corresponding the the query, allowing us to
104     /// start executing the query, or it returns with the result of the query.
105     /// If the query is executing elsewhere, this will wait for it.
106     /// If the query panicked, this will silently panic.
107     ///
108     /// This function is inlined because that results in a noticeable speedup
109     /// for some compile-time benchmarks.
110     #[inline(always)]
111     pub(super) fn try_get(
112         tcx: TyCtxt<'a, 'tcx, '_>,
113         span: Span,
114         key: &Q::Key,
115     ) -> TryGetJob<'a, 'tcx, Q> {
116         let cache = Q::query_cache(tcx);
117         loop {
118             let mut lock = cache.borrow_mut();
119             if let Some(value) = lock.results.get(key) {
120                 profq_msg!(tcx, ProfileQueriesMsg::CacheHit);
121                 tcx.sess.profiler(|p| {
122                     p.record_query(Q::CATEGORY);
123                     p.record_query_hit(Q::CATEGORY);
124                 });
125
126                 let result = Ok((value.value.clone(), value.index));
127                 return TryGetJob::JobCompleted(result);
128             }
129             let job = match lock.active.entry((*key).clone()) {
130                 Entry::Occupied(entry) => {
131                     match *entry.get() {
132                         QueryResult::Started(ref job) => job.clone(),
133                         QueryResult::Poisoned => FatalError.raise(),
134                     }
135                 }
136                 Entry::Vacant(entry) => {
137                     // No job entry for this query. Return a new one to be started later
138                     return tls::with_related_context(tcx, |icx| {
139                         let info = QueryInfo {
140                             span,
141                             query: Q::query(key.clone()),
142                         };
143                         let job = Lrc::new(QueryJob::new(info, icx.query.clone()));
144                         let owner = JobOwner {
145                             cache,
146                             job: job.clone(),
147                             key: (*key).clone(),
148                         };
149                         entry.insert(QueryResult::Started(job));
150                         TryGetJob::NotYetStarted(owner)
151                     })
152                 }
153             };
154             mem::drop(lock);
155
156             if let Err(cycle) = job.await(tcx, span) {
157                 return TryGetJob::JobCompleted(Err(cycle));
158             }
159         }
160     }
161
162     /// Completes the query by updating the query cache with the `result`,
163     /// signals the waiter and forgets the JobOwner, so it won't poison the query
164     pub(super) fn complete(self, result: &Q::Value, dep_node_index: DepNodeIndex) {
165         // We can move out of `self` here because we `mem::forget` it below
166         let key = unsafe { ptr::read(&self.key) };
167         let job = unsafe { ptr::read(&self.job) };
168         let cache = self.cache;
169
170         // Forget ourself so our destructor won't poison the query
171         mem::forget(self);
172
173         let value = QueryValue::new(result.clone(), dep_node_index);
174         {
175             let mut lock = cache.borrow_mut();
176             lock.active.remove(&key);
177             lock.results.insert(key, value);
178         }
179
180         job.signal_complete();
181     }
182
183     /// Executes a job by changing the ImplicitCtxt to point to the
184     /// new query job while it executes. It returns the diagnostics
185     /// captured during execution and the actual result.
186     pub(super) fn start<'lcx, F, R>(
187         &self,
188         tcx: TyCtxt<'_, 'tcx, 'lcx>,
189         compute: F)
190     -> (R, Vec<Diagnostic>)
191     where
192         F: for<'b> FnOnce(TyCtxt<'b, 'tcx, 'lcx>) -> R
193     {
194         // The TyCtxt stored in TLS has the same global interner lifetime
195         // as `tcx`, so we use `with_related_context` to relate the 'gcx lifetimes
196         // when accessing the ImplicitCtxt
197         let r = tls::with_related_context(tcx, move |current_icx| {
198             // Update the ImplicitCtxt to point to our new query job
199             let new_icx = tls::ImplicitCtxt {
200                 tcx,
201                 query: Some(self.job.clone()),
202                 layout_depth: current_icx.layout_depth,
203                 task: current_icx.task,
204             };
205
206             // Use the ImplicitCtxt while we execute the query
207             tls::enter_context(&new_icx, |_| {
208                 compute(tcx)
209             })
210         });
211
212         // Extract the diagnostic from the job
213         let diagnostics = mem::replace(&mut *self.job.diagnostics.lock(), Vec::new());
214
215         (r, diagnostics)
216     }
217 }
218
219 impl<'a, 'tcx, Q: QueryDescription<'tcx>> Drop for JobOwner<'a, 'tcx, Q> {
220     fn drop(&mut self) {
221         // Poison the query so jobs waiting on it panic
222         self.cache.borrow_mut().active.insert(self.key.clone(), QueryResult::Poisoned);
223         // Also signal the completion of the job, so waiters
224         // will continue execution
225         self.job.signal_complete();
226     }
227 }
228
229 #[derive(Clone)]
230 pub struct CycleError<'tcx> {
231     /// The query and related span which uses the cycle
232     pub(super) usage: Option<(Span, Query<'tcx>)>,
233     pub(super) cycle: Vec<QueryInfo<'tcx>>,
234 }
235
236 /// The result of `try_get_lock`
237 pub(super) enum TryGetJob<'a, 'tcx: 'a, D: QueryDescription<'tcx> + 'a> {
238     /// The query is not yet started. Contains a guard to the cache eventually used to start it.
239     NotYetStarted(JobOwner<'a, 'tcx, D>),
240
241     /// The query was already completed.
242     /// Returns the result of the query and its dep node index
243     /// if it succeeded or a cycle error if it failed
244     JobCompleted(Result<(D::Value, DepNodeIndex), CycleError<'tcx>>),
245 }
246
247 impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
248     pub(super) fn report_cycle(self, CycleError { usage, cycle: stack }: CycleError<'gcx>)
249         -> DiagnosticBuilder<'a>
250     {
251         assert!(!stack.is_empty());
252
253         let fix_span = |span: Span, query: &Query<'gcx>| {
254             self.sess.codemap().def_span(query.default_span(self, span))
255         };
256
257         // Disable naming impls with types in this path, since that
258         // sometimes cycles itself, leading to extra cycle errors.
259         // (And cycle errors around impls tend to occur during the
260         // collect/coherence phases anyhow.)
261         item_path::with_forced_impl_filename_line(|| {
262             let span = fix_span(stack[1 % stack.len()].span, &stack[0].query);
263             let mut err = struct_span_err!(self.sess,
264                                            span,
265                                            E0391,
266                                            "cycle detected when {}",
267                                            stack[0].query.describe(self));
268
269             for i in 1..stack.len() {
270                 let query = &stack[i].query;
271                 let span = fix_span(stack[(i + 1) % stack.len()].span, query);
272                 err.span_note(span, &format!("...which requires {}...", query.describe(self)));
273             }
274
275             err.note(&format!("...which again requires {}, completing the cycle",
276                               stack[0].query.describe(self)));
277
278             if let Some((span, query)) = usage {
279                 err.span_note(fix_span(span, &query),
280                               &format!("cycle used when {}", query.describe(self)));
281             }
282
283             return err
284         })
285     }
286
287     pub fn try_print_query_stack() {
288         eprintln!("query stack during panic:");
289
290         tls::with_context_opt(|icx| {
291             if let Some(icx) = icx {
292                 let mut current_query = icx.query.clone();
293                 let mut i = 0;
294
295                 while let Some(query) = current_query {
296                     let mut db = DiagnosticBuilder::new(icx.tcx.sess.diagnostic(),
297                         Level::FailureNote,
298                         &format!("#{} [{}] {}",
299                                  i,
300                                  query.info.query.name(),
301                                  query.info.query.describe(icx.tcx)));
302                     db.set_span(icx.tcx.sess.codemap().def_span(query.info.span));
303                     icx.tcx.sess.diagnostic().force_print_db(db);
304
305                     current_query = query.parent.clone();
306                     i += 1;
307                 }
308             }
309         });
310
311         eprintln!("end of query stack");
312     }
313
314     /// Try to read a node index for the node dep_node.
315     /// A node will have an index, when it's already been marked green, or when we can mark it
316     /// green. This function will mark the current task as a reader of the specified node, when
317     /// the a node index can be found for that node.
318     pub(super) fn try_mark_green_and_read(self, dep_node: &DepNode) -> Option<DepNodeIndex> {
319         match self.dep_graph.node_color(dep_node) {
320             Some(DepNodeColor::Green(dep_node_index)) => {
321                 self.dep_graph.read_index(dep_node_index);
322                 Some(dep_node_index)
323             }
324             Some(DepNodeColor::Red) => {
325                 None
326             }
327             None => {
328                 // try_mark_green (called below) will panic when full incremental
329                 // compilation is disabled. If that's the case, we can't try to mark nodes
330                 // as green anyway, so we can safely return None here.
331                 if !self.dep_graph.is_fully_enabled() {
332                     return None;
333                 }
334                 match self.dep_graph.try_mark_green(self.global_tcx(), &dep_node) {
335                     Some(dep_node_index) => {
336                         debug_assert!(self.dep_graph.is_green(&dep_node));
337                         self.dep_graph.read_index(dep_node_index);
338                         Some(dep_node_index)
339                     }
340                     None => {
341                         None
342                     }
343                 }
344             }
345         }
346     }
347
348     fn try_get_with<Q: QueryDescription<'gcx>>(
349         self,
350         span: Span,
351         key: Q::Key)
352     -> Result<Q::Value, CycleError<'gcx>>
353     {
354         debug!("ty::queries::{}::try_get_with(key={:?}, span={:?})",
355                Q::NAME,
356                key,
357                span);
358
359         profq_msg!(self,
360             ProfileQueriesMsg::QueryBegin(
361                 span.data(),
362                 profq_query_msg!(Q::NAME, self, key),
363             )
364         );
365
366         self.sess.profiler(|p| p.record_query(Q::CATEGORY));
367
368         let job = match JobOwner::try_get(self, span, &key) {
369             TryGetJob::NotYetStarted(job) => job,
370             TryGetJob::JobCompleted(result) => {
371                 return result.map(|(v, index)| {
372                     self.sess.profiler(|p| p.record_query_hit(Q::CATEGORY));
373                     self.dep_graph.read_index(index);
374                     v
375                 })
376             }
377         };
378
379         // Fast path for when incr. comp. is off. `to_dep_node` is
380         // expensive for some DepKinds.
381         if !self.dep_graph.is_fully_enabled() {
382             let null_dep_node = DepNode::new_no_params(::dep_graph::DepKind::Null);
383             return self.force_query_with_job::<Q>(key, job, null_dep_node).map(|(v, _)| v);
384         }
385
386         let dep_node = Q::to_dep_node(self, &key);
387
388         if dep_node.kind.is_anon() {
389             profq_msg!(self, ProfileQueriesMsg::ProviderBegin);
390             self.sess.profiler(|p| p.start_activity(Q::CATEGORY));
391
392             let res = job.start(self, |tcx| {
393                 tcx.dep_graph.with_anon_task(dep_node.kind, || {
394                     Q::compute(tcx.global_tcx(), key)
395                 })
396             });
397
398             self.sess.profiler(|p| p.end_activity(Q::CATEGORY));
399             profq_msg!(self, ProfileQueriesMsg::ProviderEnd);
400             let ((result, dep_node_index), diagnostics) = res;
401
402             self.dep_graph.read_index(dep_node_index);
403
404             self.queries.on_disk_cache
405                 .store_diagnostics_for_anon_node(dep_node_index, diagnostics);
406
407             job.complete(&result, dep_node_index);
408
409             return Ok(result);
410         }
411
412         if !dep_node.kind.is_input() {
413             if let Some(dep_node_index) = self.try_mark_green_and_read(&dep_node) {
414                 profq_msg!(self, ProfileQueriesMsg::CacheHit);
415                 self.sess.profiler(|p| p.record_query_hit(Q::CATEGORY));
416
417                 return self.load_from_disk_and_cache_in_memory::<Q>(key,
418                                                                     job,
419                                                                     dep_node_index,
420                                                                     &dep_node)
421             }
422         }
423
424         match self.force_query_with_job::<Q>(key, job, dep_node) {
425             Ok((result, dep_node_index)) => {
426                 self.dep_graph.read_index(dep_node_index);
427                 Ok(result)
428             }
429             Err(e) => Err(e)
430         }
431     }
432
433     fn load_from_disk_and_cache_in_memory<Q: QueryDescription<'gcx>>(
434         self,
435         key: Q::Key,
436         job: JobOwner<'a, 'gcx, Q>,
437         dep_node_index: DepNodeIndex,
438         dep_node: &DepNode
439     ) -> Result<Q::Value, CycleError<'gcx>>
440     {
441         // Note this function can be called concurrently from the same query
442         // We must ensure that this is handled correctly
443
444         debug_assert!(self.dep_graph.is_green(dep_node));
445
446         // First we try to load the result from the on-disk cache
447         let result = if Q::cache_on_disk(key.clone()) &&
448                         self.sess.opts.debugging_opts.incremental_queries {
449             let prev_dep_node_index =
450                 self.dep_graph.prev_dep_node_index_of(dep_node);
451             let result = Q::try_load_from_disk(self.global_tcx(),
452                                                     prev_dep_node_index);
453
454             // We always expect to find a cached result for things that
455             // can be forced from DepNode.
456             debug_assert!(!dep_node.kind.can_reconstruct_query_key() ||
457                             result.is_some(),
458                             "Missing on-disk cache entry for {:?}",
459                             dep_node);
460             result
461         } else {
462             // Some things are never cached on disk.
463             None
464         };
465
466         let result = if let Some(result) = result {
467             result
468         } else {
469             // We could not load a result from the on-disk cache, so
470             // recompute.
471
472             // The diagnostics for this query have already been
473             // promoted to the current session during
474             // try_mark_green(), so we can ignore them here.
475             let (result, _) = job.start(self, |tcx| {
476                 // The dep-graph for this computation is already in
477                 // place
478                 tcx.dep_graph.with_ignore(|| {
479                     Q::compute(tcx, key)
480                 })
481             });
482             result
483         };
484
485         // If -Zincremental-verify-ich is specified, re-hash results from
486         // the cache and make sure that they have the expected fingerprint.
487         if self.sess.opts.debugging_opts.incremental_verify_ich {
488             use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
489             use ich::Fingerprint;
490
491             assert!(Some(self.dep_graph.fingerprint_of(dep_node_index)) ==
492                     self.dep_graph.prev_fingerprint_of(dep_node),
493                     "Fingerprint for green query instance not loaded \
494                         from cache: {:?}", dep_node);
495
496             debug!("BEGIN verify_ich({:?})", dep_node);
497             let mut hcx = self.create_stable_hashing_context();
498             let mut hasher = StableHasher::new();
499
500             result.hash_stable(&mut hcx, &mut hasher);
501
502             let new_hash: Fingerprint = hasher.finish();
503             debug!("END verify_ich({:?})", dep_node);
504
505             let old_hash = self.dep_graph.fingerprint_of(dep_node_index);
506
507             assert!(new_hash == old_hash, "Found unstable fingerprints \
508                 for {:?}", dep_node);
509         }
510
511         if self.sess.opts.debugging_opts.query_dep_graph {
512             self.dep_graph.mark_loaded_from_cache(dep_node_index, true);
513         }
514
515         job.complete(&result, dep_node_index);
516
517         Ok(result)
518     }
519
520     fn force_query_with_job<Q: QueryDescription<'gcx>>(
521         self,
522         key: Q::Key,
523         job: JobOwner<'_, 'gcx, Q>,
524         dep_node: DepNode)
525     -> Result<(Q::Value, DepNodeIndex), CycleError<'gcx>> {
526         // If the following assertion triggers, it can have two reasons:
527         // 1. Something is wrong with DepNode creation, either here or
528         //    in DepGraph::try_mark_green()
529         // 2. Two distinct query keys get mapped to the same DepNode
530         //    (see for example #48923)
531         assert!(!self.dep_graph.dep_node_exists(&dep_node),
532                 "Forcing query with already existing DepNode.\n\
533                     - query-key: {:?}\n\
534                     - dep-node: {:?}",
535                 key, dep_node);
536
537         profq_msg!(self, ProfileQueriesMsg::ProviderBegin);
538         self.sess.profiler(|p| {
539             p.start_activity(Q::CATEGORY);
540             p.record_query(Q::CATEGORY);
541         });
542
543         let res = job.start(self, |tcx| {
544             if dep_node.kind.is_eval_always() {
545                 tcx.dep_graph.with_eval_always_task(dep_node,
546                                                     tcx,
547                                                     key,
548                                                     Q::compute)
549             } else {
550                 tcx.dep_graph.with_task(dep_node,
551                                         tcx,
552                                         key,
553                                         Q::compute)
554             }
555         });
556
557         self.sess.profiler(|p| p.end_activity(Q::CATEGORY));
558         profq_msg!(self, ProfileQueriesMsg::ProviderEnd);
559
560         let ((result, dep_node_index), diagnostics) = res;
561
562         if self.sess.opts.debugging_opts.query_dep_graph {
563             self.dep_graph.mark_loaded_from_cache(dep_node_index, false);
564         }
565
566         if dep_node.kind != ::dep_graph::DepKind::Null {
567             self.queries.on_disk_cache
568                 .store_diagnostics(dep_node_index, diagnostics);
569         }
570
571         job.complete(&result, dep_node_index);
572
573         Ok((result, dep_node_index))
574     }
575
576     /// Ensure that either this query has all green inputs or been executed.
577     /// Executing query::ensure(D) is considered a read of the dep-node D.
578     ///
579     /// This function is particularly useful when executing passes for their
580     /// side-effects -- e.g., in order to report errors for erroneous programs.
581     ///
582     /// Note: The optimization is only available during incr. comp.
583     pub(super) fn ensure_query<Q: QueryDescription<'gcx>>(self, key: Q::Key) -> () {
584         let dep_node = Q::to_dep_node(self, &key);
585
586         // Ensuring an "input" or anonymous query makes no sense
587         assert!(!dep_node.kind.is_anon());
588         assert!(!dep_node.kind.is_input());
589         if self.try_mark_green_and_read(&dep_node).is_none() {
590             // A None return from `try_mark_green_and_read` means that this is either
591             // a new dep node or that the dep node has already been marked red.
592             // Either way, we can't call `dep_graph.read()` as we don't have the
593             // DepNodeIndex. We must invoke the query itself. The performance cost
594             // this introduces should be negligible as we'll immediately hit the
595             // in-memory cache, or another query down the line will.
596
597             self.sess.profiler(|p| {
598                 p.start_activity(Q::CATEGORY);
599                 p.record_query(Q::CATEGORY);
600             });
601
602             let _ = self.get_query::<Q>(DUMMY_SP, key);
603
604             self.sess.profiler(|p| p.end_activity(Q::CATEGORY));
605         }
606     }
607
608     #[allow(dead_code)]
609     fn force_query<Q: QueryDescription<'gcx>>(
610         self,
611         key: Q::Key,
612         span: Span,
613         dep_node: DepNode
614     ) -> Result<(Q::Value, DepNodeIndex), CycleError<'gcx>> {
615         // We may be concurrently trying both execute and force a query
616         // Ensure that only one of them runs the query
617         let job = match JobOwner::try_get(self, span, &key) {
618             TryGetJob::NotYetStarted(job) => job,
619             TryGetJob::JobCompleted(result) => return result,
620         };
621         self.force_query_with_job::<Q>(key, job, dep_node)
622     }
623
624     pub(super) fn try_get_query<Q: QueryDescription<'gcx>>(
625         self,
626         span: Span,
627         key: Q::Key,
628     ) -> Result<Q::Value, DiagnosticBuilder<'a>> {
629         match self.try_get_with::<Q>(span, key) {
630             Ok(e) => Ok(e),
631             Err(e) => Err(self.report_cycle(e)),
632         }
633     }
634
635     pub(super) fn get_query<Q: QueryDescription<'gcx>>(
636         self,
637         span: Span,
638         key: Q::Key,
639     ) -> Q::Value {
640         self.try_get_query::<Q>(span, key).unwrap_or_else(|mut e| {
641             e.emit();
642             Q::handle_cycle_error(self)
643         })
644     }
645 }
646
647 macro_rules! handle_cycle_error {
648     ([][$this: expr]) => {{
649         Value::from_cycle_error($this.global_tcx())
650     }};
651     ([fatal_cycle$(, $modifiers:ident)*][$this:expr]) => {{
652         $this.sess.abort_if_errors();
653         unreachable!();
654     }};
655     ([$other:ident$(, $modifiers:ident)*][$($args:tt)*]) => {
656         handle_cycle_error!([$($modifiers),*][$($args)*])
657     };
658 }
659
660 macro_rules! define_queries {
661     (<$tcx:tt> $($category:tt {
662         $($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident: $node:ident($K:ty) -> $V:ty,)*
663     },)*) => {
664         define_queries_inner! { <$tcx>
665             $($( $(#[$attr])* category<$category> [$($modifiers)*] fn $name: $node($K) -> $V,)*)*
666         }
667     }
668 }
669
670 macro_rules! define_queries_inner {
671     (<$tcx:tt>
672      $($(#[$attr:meta])* category<$category:tt>
673         [$($modifiers:tt)*] fn $name:ident: $node:ident($K:ty) -> $V:ty,)*) => {
674
675         use std::mem;
676         #[cfg(parallel_queries)]
677         use ty::query::job::QueryResult;
678         use rustc_data_structures::sync::Lock;
679         use {
680             rustc_data_structures::stable_hasher::HashStable,
681             rustc_data_structures::stable_hasher::StableHasherResult,
682             rustc_data_structures::stable_hasher::StableHasher,
683             ich::StableHashingContext
684         };
685         use util::profiling::ProfileCategory;
686
687         define_queries_struct! {
688             tcx: $tcx,
689             input: ($(([$($modifiers)*] [$($attr)*] [$name]))*)
690         }
691
692         impl<$tcx> Queries<$tcx> {
693             pub fn new(
694                 providers: IndexVec<CrateNum, Providers<$tcx>>,
695                 on_disk_cache: OnDiskCache<'tcx>,
696             ) -> Self {
697                 Queries {
698                     providers,
699                     on_disk_cache,
700                     $($name: Lock::new(QueryCache::new())),*
701                 }
702             }
703
704             #[cfg(parallel_queries)]
705             pub fn collect_active_jobs(&self) -> Vec<Lrc<QueryJob<$tcx>>> {
706                 let mut jobs = Vec::new();
707
708                 // We use try_lock here since we are only called from the
709                 // deadlock handler, and this shouldn't be locked
710                 $(for v in self.$name.try_lock().unwrap().active.values() {
711                     match *v {
712                         QueryResult::Started(ref job) => jobs.push(job.clone()),
713                         _ => (),
714                     }
715                 })*
716
717                 return jobs;
718             }
719         }
720
721         #[allow(bad_style)]
722         #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
723         pub enum Query<$tcx> {
724             $($(#[$attr])* $name($K)),*
725         }
726
727         impl<$tcx> Query<$tcx> {
728             pub fn name(&self) -> &'static str {
729                 match *self {
730                     $(Query::$name(_) => stringify!($name),)*
731                 }
732             }
733
734             pub fn describe(&self, tcx: TyCtxt) -> String {
735                 let (r, name) = match *self {
736                     $(Query::$name(key) => {
737                         (queries::$name::describe(tcx, key), stringify!($name))
738                     })*
739                 };
740                 if tcx.sess.verbose() {
741                     format!("{} [{}]", r, name)
742                 } else {
743                     r
744                 }
745             }
746
747             // FIXME(eddyb) Get more valid Span's on queries.
748             pub fn default_span(&self, tcx: TyCtxt<'_, $tcx, '_>, span: Span) -> Span {
749                 if !span.is_dummy() {
750                     return span;
751                 }
752                 // The def_span query is used to calculate default_span,
753                 // so exit to avoid infinite recursion
754                 match *self {
755                     Query::def_span(..) => return span,
756                     _ => ()
757                 }
758                 match *self {
759                     $(Query::$name(key) => key.default_span(tcx),)*
760                 }
761             }
762         }
763
764         impl<'a, $tcx> HashStable<StableHashingContext<'a>> for Query<$tcx> {
765             fn hash_stable<W: StableHasherResult>(&self,
766                                                 hcx: &mut StableHashingContext<'a>,
767                                                 hasher: &mut StableHasher<W>) {
768                 mem::discriminant(self).hash_stable(hcx, hasher);
769                 match *self {
770                     $(Query::$name(key) => key.hash_stable(hcx, hasher),)*
771                 }
772             }
773         }
774
775         pub mod queries {
776             use std::marker::PhantomData;
777
778             $(#[allow(bad_style)]
779             pub struct $name<$tcx> {
780                 data: PhantomData<&$tcx ()>
781             })*
782         }
783
784         // This module and the functions in it exist only to provide a
785         // predictable symbol name prefix for query providers. This is helpful
786         // for analyzing queries in profilers.
787         pub(super) mod __query_compute {
788             $(#[inline(never)]
789             pub fn $name<F: FnOnce() -> R, R>(f: F) -> R {
790                 f()
791             })*
792         }
793
794         $(impl<$tcx> QueryConfig<$tcx> for queries::$name<$tcx> {
795             type Key = $K;
796             type Value = $V;
797
798             const NAME: &'static str = stringify!($name);
799             const CATEGORY: ProfileCategory = $category;
800         }
801
802         impl<$tcx> QueryAccessors<$tcx> for queries::$name<$tcx> {
803             fn query(key: Self::Key) -> Query<'tcx> {
804                 Query::$name(key)
805             }
806
807             fn query_cache<'a>(tcx: TyCtxt<'a, $tcx, '_>) -> &'a Lock<QueryCache<$tcx, Self>> {
808                 &tcx.queries.$name
809             }
810
811             #[allow(unused)]
812             fn to_dep_node(tcx: TyCtxt<'_, $tcx, '_>, key: &Self::Key) -> DepNode {
813                 use dep_graph::DepConstructor::*;
814
815                 DepNode::new(tcx, $node(*key))
816             }
817
818             #[inline]
819             fn compute(tcx: TyCtxt<'_, 'tcx, '_>, key: Self::Key) -> Self::Value {
820                 __query_compute::$name(move || {
821                     let provider = tcx.queries.providers[key.query_crate()].$name;
822                     provider(tcx.global_tcx(), key)
823                 })
824             }
825
826             fn handle_cycle_error(tcx: TyCtxt<'_, 'tcx, '_>) -> Self::Value {
827                 handle_cycle_error!([$($modifiers)*][tcx])
828             }
829         }
830
831         impl<'a, $tcx, 'lcx> queries::$name<$tcx> {
832             /// Ensure that either this query has all green inputs or been executed.
833             /// Executing query::ensure(D) is considered a read of the dep-node D.
834             ///
835             /// This function is particularly useful when executing passes for their
836             /// side-effects -- e.g., in order to report errors for erroneous programs.
837             ///
838             /// Note: The optimization is only available during incr. comp.
839             pub fn ensure(tcx: TyCtxt<'a, $tcx, 'lcx>, key: $K) -> () {
840                 tcx.ensure_query::<queries::$name>(key);
841             }
842         })*
843
844         #[derive(Copy, Clone)]
845         pub struct TyCtxtAt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
846             pub tcx: TyCtxt<'a, 'gcx, 'tcx>,
847             pub span: Span,
848         }
849
850         impl<'a, 'gcx, 'tcx> Deref for TyCtxtAt<'a, 'gcx, 'tcx> {
851             type Target = TyCtxt<'a, 'gcx, 'tcx>;
852             fn deref(&self) -> &Self::Target {
853                 &self.tcx
854             }
855         }
856
857         impl<'a, $tcx, 'lcx> TyCtxt<'a, $tcx, 'lcx> {
858             /// Return a transparent wrapper for `TyCtxt` which uses
859             /// `span` as the location of queries performed through it.
860             pub fn at(self, span: Span) -> TyCtxtAt<'a, $tcx, 'lcx> {
861                 TyCtxtAt {
862                     tcx: self,
863                     span
864                 }
865             }
866
867             $($(#[$attr])*
868             pub fn $name(self, key: $K) -> $V {
869                 self.at(DUMMY_SP).$name(key)
870             })*
871         }
872
873         impl<'a, $tcx, 'lcx> TyCtxtAt<'a, $tcx, 'lcx> {
874             $($(#[$attr])*
875             pub fn $name(self, key: $K) -> $V {
876                 self.tcx.get_query::<queries::$name>(self.span, key)
877             })*
878         }
879
880         define_provider_struct! {
881             tcx: $tcx,
882             input: ($(([$($modifiers)*] [$name] [$K] [$V]))*)
883         }
884
885         impl<$tcx> Copy for Providers<$tcx> {}
886         impl<$tcx> Clone for Providers<$tcx> {
887             fn clone(&self) -> Self { *self }
888         }
889     }
890 }
891
892 macro_rules! define_queries_struct {
893     (tcx: $tcx:tt,
894      input: ($(([$($modifiers:tt)*] [$($attr:tt)*] [$name:ident]))*)) => {
895         pub(crate) struct Queries<$tcx> {
896             /// This provides access to the incr. comp. on-disk cache for query results.
897             /// Do not access this directly. It is only meant to be used by
898             /// `DepGraph::try_mark_green()` and the query infrastructure.
899             pub(crate) on_disk_cache: OnDiskCache<'tcx>,
900
901             providers: IndexVec<CrateNum, Providers<$tcx>>,
902
903             $($(#[$attr])*  $name: Lock<QueryCache<$tcx, queries::$name<$tcx>>>,)*
904         }
905     };
906 }
907
908 macro_rules! define_provider_struct {
909     (tcx: $tcx:tt,
910      input: ($(([$($modifiers:tt)*] [$name:ident] [$K:ty] [$R:ty]))*)) => {
911         pub struct Providers<$tcx> {
912             $(pub $name: for<'a> fn(TyCtxt<'a, $tcx, $tcx>, $K) -> $R,)*
913         }
914
915         impl<$tcx> Default for Providers<$tcx> {
916             fn default() -> Self {
917                 $(fn $name<'a, $tcx>(_: TyCtxt<'a, $tcx, $tcx>, key: $K) -> $R {
918                     bug!("tcx.{}({:?}) unsupported by its crate",
919                          stringify!($name), key);
920                 })*
921                 Providers { $($name),* }
922             }
923         }
924     };
925 }
926
927
928 /// The red/green evaluation system will try to mark a specific DepNode in the
929 /// dependency graph as green by recursively trying to mark the dependencies of
930 /// that DepNode as green. While doing so, it will sometimes encounter a DepNode
931 /// where we don't know if it is red or green and we therefore actually have
932 /// to recompute its value in order to find out. Since the only piece of
933 /// information that we have at that point is the DepNode we are trying to
934 /// re-evaluate, we need some way to re-run a query from just that. This is what
935 /// `force_from_dep_node()` implements.
936 ///
937 /// In the general case, a DepNode consists of a DepKind and an opaque
938 /// GUID/fingerprint that will uniquely identify the node. This GUID/fingerprint
939 /// is usually constructed by computing a stable hash of the query-key that the
940 /// DepNode corresponds to. Consequently, it is not in general possible to go
941 /// back from hash to query-key (since hash functions are not reversible). For
942 /// this reason `force_from_dep_node()` is expected to fail from time to time
943 /// because we just cannot find out, from the DepNode alone, what the
944 /// corresponding query-key is and therefore cannot re-run the query.
945 ///
946 /// The system deals with this case letting `try_mark_green` fail which forces
947 /// the root query to be re-evaluated.
948 ///
949 /// Now, if force_from_dep_node() would always fail, it would be pretty useless.
950 /// Fortunately, we can use some contextual information that will allow us to
951 /// reconstruct query-keys for certain kinds of DepNodes. In particular, we
952 /// enforce by construction that the GUID/fingerprint of certain DepNodes is a
953 /// valid DefPathHash. Since we also always build a huge table that maps every
954 /// DefPathHash in the current codebase to the corresponding DefId, we have
955 /// everything we need to re-run the query.
956 ///
957 /// Take the `mir_validated` query as an example. Like many other queries, it
958 /// just has a single parameter: the DefId of the item it will compute the
959 /// validated MIR for. Now, when we call `force_from_dep_node()` on a dep-node
960 /// with kind `MirValidated`, we know that the GUID/fingerprint of the dep-node
961 /// is actually a DefPathHash, and can therefore just look up the corresponding
962 /// DefId in `tcx.def_path_hash_to_def_id`.
963 ///
964 /// When you implement a new query, it will likely have a corresponding new
965 /// DepKind, and you'll have to support it here in `force_from_dep_node()`. As
966 /// a rule of thumb, if your query takes a DefId or DefIndex as sole parameter,
967 /// then `force_from_dep_node()` should not fail for it. Otherwise, you can just
968 /// add it to the "We don't have enough information to reconstruct..." group in
969 /// the match below.
970 pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
971                                            dep_node: &DepNode)
972                                            -> bool {
973     use hir::def_id::LOCAL_CRATE;
974
975     // We must avoid ever having to call force_from_dep_node() for a
976     // DepNode::CodegenUnit:
977     // Since we cannot reconstruct the query key of a DepNode::CodegenUnit, we
978     // would always end up having to evaluate the first caller of the
979     // `codegen_unit` query that *is* reconstructible. This might very well be
980     // the `compile_codegen_unit` query, thus re-codegenning the whole CGU just
981     // to re-trigger calling the `codegen_unit` query with the right key. At
982     // that point we would already have re-done all the work we are trying to
983     // avoid doing in the first place.
984     // The solution is simple: Just explicitly call the `codegen_unit` query for
985     // each CGU, right after partitioning. This way `try_mark_green` will always
986     // hit the cache instead of having to go through `force_from_dep_node`.
987     // This assertion makes sure, we actually keep applying the solution above.
988     debug_assert!(dep_node.kind != DepKind::CodegenUnit,
989                   "calling force_from_dep_node() on DepKind::CodegenUnit");
990
991     if !dep_node.kind.can_reconstruct_query_key() {
992         return false
993     }
994
995     macro_rules! def_id {
996         () => {
997             if let Some(def_id) = dep_node.extract_def_id(tcx) {
998                 def_id
999             } else {
1000                 // return from the whole function
1001                 return false
1002             }
1003         }
1004     };
1005
1006     macro_rules! krate {
1007         () => { (def_id!()).krate }
1008     };
1009
1010     macro_rules! force {
1011         ($query:ident, $key:expr) => {
1012             {
1013                 use $crate::util::common::{ProfileQueriesMsg, profq_msg};
1014
1015                 profq_msg!(tcx,
1016                     ProfileQueriesMsg::QueryBegin(
1017                         DUMMY_SP.data(),
1018                         profq_query_msg!(::ty::query::queries::$query::NAME, tcx, $key),
1019                     )
1020                 );
1021
1022                 match tcx.force_query::<::ty::query::queries::$query>($key, DUMMY_SP, *dep_node) {
1023                     Ok(_) => {},
1024                     Err(e) => {
1025                         tcx.report_cycle(e).emit();
1026                     }
1027                 }
1028             }
1029         }
1030     };
1031
1032     // FIXME(#45015): We should try move this boilerplate code into a macro
1033     //                somehow.
1034     match dep_node.kind {
1035         // These are inputs that are expected to be pre-allocated and that
1036         // should therefore always be red or green already
1037         DepKind::AllLocalTraitImpls |
1038         DepKind::Krate |
1039         DepKind::CrateMetadata |
1040         DepKind::HirBody |
1041         DepKind::Hir |
1042
1043         // This are anonymous nodes
1044         DepKind::TraitSelect |
1045
1046         // We don't have enough information to reconstruct the query key of
1047         // these
1048         DepKind::IsCopy |
1049         DepKind::IsSized |
1050         DepKind::IsFreeze |
1051         DepKind::NeedsDrop |
1052         DepKind::Layout |
1053         DepKind::ConstEval |
1054         DepKind::InstanceSymbolName |
1055         DepKind::MirShim |
1056         DepKind::BorrowCheckKrate |
1057         DepKind::Specializes |
1058         DepKind::ImplementationsOfTrait |
1059         DepKind::TypeParamPredicates |
1060         DepKind::CodegenUnit |
1061         DepKind::CompileCodegenUnit |
1062         DepKind::FulfillObligation |
1063         DepKind::VtableMethods |
1064         DepKind::EraseRegionsTy |
1065         DepKind::ConstValueToAllocation |
1066         DepKind::NormalizeProjectionTy |
1067         DepKind::NormalizeTyAfterErasingRegions |
1068         DepKind::ImpliedOutlivesBounds |
1069         DepKind::DropckOutlives |
1070         DepKind::EvaluateObligation |
1071         DepKind::TypeOpEq |
1072         DepKind::TypeOpSubtype |
1073         DepKind::TypeOpProvePredicate |
1074         DepKind::TypeOpNormalizeTy |
1075         DepKind::TypeOpNormalizePredicate |
1076         DepKind::TypeOpNormalizePolyFnSig |
1077         DepKind::TypeOpNormalizeFnSig |
1078         DepKind::SubstituteNormalizeAndTestPredicates |
1079         DepKind::InstanceDefSizeEstimate |
1080         DepKind::ProgramClausesForEnv |
1081
1082         // This one should never occur in this context
1083         DepKind::Null => {
1084             bug!("force_from_dep_node() - Encountered {:?}", dep_node)
1085         }
1086
1087         // These are not queries
1088         DepKind::CoherenceCheckTrait |
1089         DepKind::ItemVarianceConstraints => {
1090             return false
1091         }
1092
1093         DepKind::RegionScopeTree => { force!(region_scope_tree, def_id!()); }
1094
1095         DepKind::Coherence => { force!(crate_inherent_impls, LOCAL_CRATE); }
1096         DepKind::CoherenceInherentImplOverlapCheck => {
1097             force!(crate_inherent_impls_overlap_check, LOCAL_CRATE)
1098         },
1099         DepKind::PrivacyAccessLevels => { force!(privacy_access_levels, LOCAL_CRATE); }
1100         DepKind::MirBuilt => { force!(mir_built, def_id!()); }
1101         DepKind::MirConstQualif => { force!(mir_const_qualif, def_id!()); }
1102         DepKind::MirConst => { force!(mir_const, def_id!()); }
1103         DepKind::MirValidated => { force!(mir_validated, def_id!()); }
1104         DepKind::MirOptimized => { force!(optimized_mir, def_id!()); }
1105
1106         DepKind::BorrowCheck => { force!(borrowck, def_id!()); }
1107         DepKind::MirBorrowCheck => { force!(mir_borrowck, def_id!()); }
1108         DepKind::UnsafetyCheckResult => { force!(unsafety_check_result, def_id!()); }
1109         DepKind::UnsafeDeriveOnReprPacked => { force!(unsafe_derive_on_repr_packed, def_id!()); }
1110         DepKind::Reachability => { force!(reachable_set, LOCAL_CRATE); }
1111         DepKind::MirKeys => { force!(mir_keys, LOCAL_CRATE); }
1112         DepKind::CrateVariances => { force!(crate_variances, LOCAL_CRATE); }
1113         DepKind::AssociatedItems => { force!(associated_item, def_id!()); }
1114         DepKind::TypeOfItem => { force!(type_of, def_id!()); }
1115         DepKind::GenericsOfItem => { force!(generics_of, def_id!()); }
1116         DepKind::PredicatesOfItem => { force!(predicates_of, def_id!()); }
1117         DepKind::PredicatesDefinedOnItem => { force!(predicates_defined_on, def_id!()); }
1118         DepKind::ExplicitPredicatesOfItem => { force!(explicit_predicates_of, def_id!()); }
1119         DepKind::InferredOutlivesOf => { force!(inferred_outlives_of, def_id!()); }
1120         DepKind::InferredOutlivesCrate => { force!(inferred_outlives_crate, LOCAL_CRATE); }
1121         DepKind::SuperPredicatesOfItem => { force!(super_predicates_of, def_id!()); }
1122         DepKind::TraitDefOfItem => { force!(trait_def, def_id!()); }
1123         DepKind::AdtDefOfItem => { force!(adt_def, def_id!()); }
1124         DepKind::ImplTraitRef => { force!(impl_trait_ref, def_id!()); }
1125         DepKind::ImplPolarity => { force!(impl_polarity, def_id!()); }
1126         DepKind::FnSignature => { force!(fn_sig, def_id!()); }
1127         DepKind::CoerceUnsizedInfo => { force!(coerce_unsized_info, def_id!()); }
1128         DepKind::ItemVariances => { force!(variances_of, def_id!()); }
1129         DepKind::IsConstFn => { force!(is_const_fn, def_id!()); }
1130         DepKind::IsForeignItem => { force!(is_foreign_item, def_id!()); }
1131         DepKind::SizedConstraint => { force!(adt_sized_constraint, def_id!()); }
1132         DepKind::DtorckConstraint => { force!(adt_dtorck_constraint, def_id!()); }
1133         DepKind::AdtDestructor => { force!(adt_destructor, def_id!()); }
1134         DepKind::AssociatedItemDefIds => { force!(associated_item_def_ids, def_id!()); }
1135         DepKind::InherentImpls => { force!(inherent_impls, def_id!()); }
1136         DepKind::TypeckBodiesKrate => { force!(typeck_item_bodies, LOCAL_CRATE); }
1137         DepKind::TypeckTables => { force!(typeck_tables_of, def_id!()); }
1138         DepKind::UsedTraitImports => { force!(used_trait_imports, def_id!()); }
1139         DepKind::HasTypeckTables => { force!(has_typeck_tables, def_id!()); }
1140         DepKind::SymbolName => { force!(def_symbol_name, def_id!()); }
1141         DepKind::SpecializationGraph => { force!(specialization_graph_of, def_id!()); }
1142         DepKind::ObjectSafety => { force!(is_object_safe, def_id!()); }
1143         DepKind::TraitImpls => { force!(trait_impls_of, def_id!()); }
1144         DepKind::CheckMatch => { force!(check_match, def_id!()); }
1145
1146         DepKind::ParamEnv => { force!(param_env, def_id!()); }
1147         DepKind::DescribeDef => { force!(describe_def, def_id!()); }
1148         DepKind::DefSpan => { force!(def_span, def_id!()); }
1149         DepKind::LookupStability => { force!(lookup_stability, def_id!()); }
1150         DepKind::LookupDeprecationEntry => {
1151             force!(lookup_deprecation_entry, def_id!());
1152         }
1153         DepKind::ConstIsRvaluePromotableToStatic => {
1154             force!(const_is_rvalue_promotable_to_static, def_id!());
1155         }
1156         DepKind::RvaluePromotableMap => { force!(rvalue_promotable_map, def_id!()); }
1157         DepKind::ImplParent => { force!(impl_parent, def_id!()); }
1158         DepKind::TraitOfItem => { force!(trait_of_item, def_id!()); }
1159         DepKind::IsReachableNonGeneric => { force!(is_reachable_non_generic, def_id!()); }
1160         DepKind::IsUnreachableLocalDefinition => {
1161             force!(is_unreachable_local_definition, def_id!());
1162         }
1163         DepKind::IsMirAvailable => { force!(is_mir_available, def_id!()); }
1164         DepKind::ItemAttrs => { force!(item_attrs, def_id!()); }
1165         DepKind::CodegenFnAttrs => { force!(codegen_fn_attrs, def_id!()); }
1166         DepKind::FnArgNames => { force!(fn_arg_names, def_id!()); }
1167         DepKind::RenderedConst => { force!(rendered_const, def_id!()); }
1168         DepKind::DylibDepFormats => { force!(dylib_dependency_formats, krate!()); }
1169         DepKind::IsPanicRuntime => { force!(is_panic_runtime, krate!()); }
1170         DepKind::IsCompilerBuiltins => { force!(is_compiler_builtins, krate!()); }
1171         DepKind::HasGlobalAllocator => { force!(has_global_allocator, krate!()); }
1172         DepKind::ExternCrate => { force!(extern_crate, def_id!()); }
1173         DepKind::LintLevels => { force!(lint_levels, LOCAL_CRATE); }
1174         DepKind::InScopeTraits => { force!(in_scope_traits_map, def_id!().index); }
1175         DepKind::ModuleExports => { force!(module_exports, def_id!()); }
1176         DepKind::IsSanitizerRuntime => { force!(is_sanitizer_runtime, krate!()); }
1177         DepKind::IsProfilerRuntime => { force!(is_profiler_runtime, krate!()); }
1178         DepKind::GetPanicStrategy => { force!(panic_strategy, krate!()); }
1179         DepKind::IsNoBuiltins => { force!(is_no_builtins, krate!()); }
1180         DepKind::ImplDefaultness => { force!(impl_defaultness, def_id!()); }
1181         DepKind::CheckItemWellFormed => { force!(check_item_well_formed, def_id!()); }
1182         DepKind::CheckTraitItemWellFormed => { force!(check_trait_item_well_formed, def_id!()); }
1183         DepKind::CheckImplItemWellFormed => { force!(check_impl_item_well_formed, def_id!()); }
1184         DepKind::ReachableNonGenerics => { force!(reachable_non_generics, krate!()); }
1185         DepKind::NativeLibraries => { force!(native_libraries, krate!()); }
1186         DepKind::PluginRegistrarFn => { force!(plugin_registrar_fn, krate!()); }
1187         DepKind::DeriveRegistrarFn => { force!(derive_registrar_fn, krate!()); }
1188         DepKind::CrateDisambiguator => { force!(crate_disambiguator, krate!()); }
1189         DepKind::CrateHash => { force!(crate_hash, krate!()); }
1190         DepKind::OriginalCrateName => { force!(original_crate_name, krate!()); }
1191         DepKind::ExtraFileName => { force!(extra_filename, krate!()); }
1192
1193         DepKind::AllTraitImplementations => {
1194             force!(all_trait_implementations, krate!());
1195         }
1196
1197         DepKind::DllimportForeignItems => {
1198             force!(dllimport_foreign_items, krate!());
1199         }
1200         DepKind::IsDllimportForeignItem => {
1201             force!(is_dllimport_foreign_item, def_id!());
1202         }
1203         DepKind::IsStaticallyIncludedForeignItem => {
1204             force!(is_statically_included_foreign_item, def_id!());
1205         }
1206         DepKind::NativeLibraryKind => { force!(native_library_kind, def_id!()); }
1207         DepKind::LinkArgs => { force!(link_args, LOCAL_CRATE); }
1208
1209         DepKind::ResolveLifetimes => { force!(resolve_lifetimes, krate!()); }
1210         DepKind::NamedRegion => { force!(named_region_map, def_id!().index); }
1211         DepKind::IsLateBound => { force!(is_late_bound_map, def_id!().index); }
1212         DepKind::ObjectLifetimeDefaults => {
1213             force!(object_lifetime_defaults_map, def_id!().index);
1214         }
1215
1216         DepKind::Visibility => { force!(visibility, def_id!()); }
1217         DepKind::DepKind => { force!(dep_kind, krate!()); }
1218         DepKind::CrateName => { force!(crate_name, krate!()); }
1219         DepKind::ItemChildren => { force!(item_children, def_id!()); }
1220         DepKind::ExternModStmtCnum => { force!(extern_mod_stmt_cnum, def_id!()); }
1221         DepKind::GetLangItems => { force!(get_lang_items, LOCAL_CRATE); }
1222         DepKind::DefinedLangItems => { force!(defined_lang_items, krate!()); }
1223         DepKind::MissingLangItems => { force!(missing_lang_items, krate!()); }
1224         DepKind::VisibleParentMap => { force!(visible_parent_map, LOCAL_CRATE); }
1225         DepKind::MissingExternCrateItem => {
1226             force!(missing_extern_crate_item, krate!());
1227         }
1228         DepKind::UsedCrateSource => { force!(used_crate_source, krate!()); }
1229         DepKind::PostorderCnums => { force!(postorder_cnums, LOCAL_CRATE); }
1230
1231         DepKind::Freevars => { force!(freevars, def_id!()); }
1232         DepKind::MaybeUnusedTraitImport => {
1233             force!(maybe_unused_trait_import, def_id!());
1234         }
1235         DepKind::MaybeUnusedExternCrates => { force!(maybe_unused_extern_crates, LOCAL_CRATE); }
1236         DepKind::StabilityIndex => { force!(stability_index, LOCAL_CRATE); }
1237         DepKind::AllTraits => { force!(all_traits, LOCAL_CRATE); }
1238         DepKind::AllCrateNums => { force!(all_crate_nums, LOCAL_CRATE); }
1239         DepKind::ExportedSymbols => { force!(exported_symbols, krate!()); }
1240         DepKind::CollectAndPartitionMonoItems => {
1241             force!(collect_and_partition_mono_items, LOCAL_CRATE);
1242         }
1243         DepKind::IsCodegenedItem => { force!(is_codegened_item, def_id!()); }
1244         DepKind::OutputFilenames => { force!(output_filenames, LOCAL_CRATE); }
1245
1246         DepKind::TargetFeaturesWhitelist => { force!(target_features_whitelist, LOCAL_CRATE); }
1247
1248         DepKind::Features => { force!(features_query, LOCAL_CRATE); }
1249
1250         DepKind::ProgramClausesFor => { force!(program_clauses_for, def_id!()); }
1251         DepKind::WasmImportModuleMap => { force!(wasm_import_module_map, krate!()); }
1252         DepKind::ForeignModules => { force!(foreign_modules, krate!()); }
1253
1254         DepKind::UpstreamMonomorphizations => {
1255             force!(upstream_monomorphizations, krate!());
1256         }
1257         DepKind::UpstreamMonomorphizationsFor => {
1258             force!(upstream_monomorphizations_for, def_id!());
1259         }
1260     }
1261
1262     true
1263 }
1264
1265
1266 // FIXME(#45015): Another piece of boilerplate code that could be generated in
1267 //                a combined define_dep_nodes!()/define_queries!() macro.
1268 macro_rules! impl_load_from_cache {
1269     ($($dep_kind:ident => $query_name:ident,)*) => {
1270         impl DepNode {
1271             // Check whether the query invocation corresponding to the given
1272             // DepNode is eligible for on-disk-caching.
1273             pub fn cache_on_disk(&self, tcx: TyCtxt) -> bool {
1274                 use ty::query::queries;
1275                 use ty::query::QueryDescription;
1276
1277                 match self.kind {
1278                     $(DepKind::$dep_kind => {
1279                         let def_id = self.extract_def_id(tcx).unwrap();
1280                         queries::$query_name::cache_on_disk(def_id)
1281                     })*
1282                     _ => false
1283                 }
1284             }
1285
1286             // This is method will execute the query corresponding to the given
1287             // DepNode. It is only expected to work for DepNodes where the
1288             // above `cache_on_disk` methods returns true.
1289             // Also, as a sanity check, it expects that the corresponding query
1290             // invocation has been marked as green already.
1291             pub fn load_from_on_disk_cache(&self, tcx: TyCtxt) {
1292                 match self.kind {
1293                     $(DepKind::$dep_kind => {
1294                         debug_assert!(tcx.dep_graph
1295                                          .node_color(self)
1296                                          .map(|c| c.is_green())
1297                                          .unwrap_or(false));
1298
1299                         let def_id = self.extract_def_id(tcx).unwrap();
1300                         let _ = tcx.$query_name(def_id);
1301                     })*
1302                     _ => {
1303                         bug!()
1304                     }
1305                 }
1306             }
1307         }
1308     }
1309 }
1310
1311 impl_load_from_cache!(
1312     TypeckTables => typeck_tables_of,
1313     MirOptimized => optimized_mir,
1314     UnsafetyCheckResult => unsafety_check_result,
1315     BorrowCheck => borrowck,
1316     MirBorrowCheck => mir_borrowck,
1317     MirConstQualif => mir_const_qualif,
1318     SymbolName => def_symbol_name,
1319     ConstIsRvaluePromotableToStatic => const_is_rvalue_promotable_to_static,
1320     CheckMatch => check_match,
1321     TypeOfItem => type_of,
1322     GenericsOfItem => generics_of,
1323     PredicatesOfItem => predicates_of,
1324     UsedTraitImports => used_trait_imports,
1325     CodegenFnAttrs => codegen_fn_attrs,
1326     SpecializationGraph => specialization_graph_of,
1327 );