]> git.lizzy.rs Git - rust.git/blob - src/librustc/ty/maps/plumbing.rs
Auto merge of #45353 - wesleywiser:untracked_queries, r=michaelwoerister
[rust.git] / src / librustc / ty / maps / 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::{Diagnostic, DiagnosticBuilder};
17 use ty::{TyCtxt};
18 use ty::maps::Query; // NB: actually generated by the macros in this file
19 use ty::maps::config::QueryDescription;
20 use ty::item_path;
21
22 use rustc_data_structures::fx::{FxHashMap};
23 use std::cell::{RefMut, Cell};
24 use std::marker::PhantomData;
25 use std::mem;
26 use syntax_pos::Span;
27
28 pub(super) struct QueryMap<D: QueryDescription> {
29     phantom: PhantomData<D>,
30     pub(super) map: FxHashMap<D::Key, QueryValue<D::Value>>,
31 }
32
33 pub(super) struct QueryValue<T> {
34     pub(super) value: T,
35     pub(super) index: DepNodeIndex,
36     pub(super) diagnostics: Option<Box<QueryDiagnostics>>,
37 }
38
39 impl<T> QueryValue<T> {
40     pub(super) fn new(value: T,
41                       dep_node_index: DepNodeIndex,
42                       diagnostics: Vec<Diagnostic>)
43                       -> QueryValue<T> {
44         QueryValue {
45             value,
46             index: dep_node_index,
47             diagnostics: if diagnostics.len() == 0 {
48                 None
49             } else {
50                 Some(Box::new(QueryDiagnostics {
51                     diagnostics,
52                     emitted_diagnostics: Cell::new(true),
53                 }))
54             },
55         }
56     }
57 }
58
59 pub(super) struct QueryDiagnostics {
60     pub(super) diagnostics: Vec<Diagnostic>,
61     pub(super) emitted_diagnostics: Cell<bool>,
62 }
63
64 impl<M: QueryDescription> QueryMap<M> {
65     pub(super) fn new() -> QueryMap<M> {
66         QueryMap {
67             phantom: PhantomData,
68             map: FxHashMap(),
69         }
70     }
71 }
72
73 pub(super) struct CycleError<'a, 'tcx: 'a> {
74     span: Span,
75     cycle: RefMut<'a, [(Span, Query<'tcx>)]>,
76 }
77
78 impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
79     pub(super) fn report_cycle(self, CycleError { span, cycle }: CycleError)
80         -> DiagnosticBuilder<'a>
81     {
82         // Subtle: release the refcell lock before invoking `describe()`
83         // below by dropping `cycle`.
84         let stack = cycle.to_vec();
85         mem::drop(cycle);
86
87         assert!(!stack.is_empty());
88
89         // Disable naming impls with types in this path, since that
90         // sometimes cycles itself, leading to extra cycle errors.
91         // (And cycle errors around impls tend to occur during the
92         // collect/coherence phases anyhow.)
93         item_path::with_forced_impl_filename_line(|| {
94             let mut err =
95                 struct_span_err!(self.sess, span, E0391,
96                                  "unsupported cyclic reference between types/traits detected");
97             err.span_label(span, "cyclic reference");
98
99             err.span_note(stack[0].0, &format!("the cycle begins when {}...",
100                                                stack[0].1.describe(self)));
101
102             for &(span, ref query) in &stack[1..] {
103                 err.span_note(span, &format!("...which then requires {}...",
104                                              query.describe(self)));
105             }
106
107             err.note(&format!("...which then again requires {}, completing the cycle.",
108                               stack[0].1.describe(self)));
109
110             return err
111         })
112     }
113
114     pub(super) fn cycle_check<F, R>(self, span: Span, query: Query<'gcx>, compute: F)
115                                     -> Result<R, CycleError<'a, 'gcx>>
116         where F: FnOnce() -> R
117     {
118         {
119             let mut stack = self.maps.query_stack.borrow_mut();
120             if let Some((i, _)) = stack.iter().enumerate().rev()
121                                        .find(|&(_, &(_, ref q))| *q == query) {
122                 return Err(CycleError {
123                     span,
124                     cycle: RefMut::map(stack, |stack| &mut stack[i..])
125                 });
126             }
127             stack.push((span, query));
128         }
129
130         let result = compute();
131
132         self.maps.query_stack.borrow_mut().pop();
133
134         Ok(result)
135     }
136
137     /// Try to read a node index for the node dep_node.
138     /// A node will have an index, when it's already been marked green, or when we can mark it
139     /// green. This function will mark the current task as a reader of the specified node, when
140     /// the a node index can be found for that node.
141     pub(super) fn try_mark_green_and_read(self, dep_node: &DepNode) -> Option<DepNodeIndex> {
142         match self.dep_graph.node_color(dep_node) {
143             Some(DepNodeColor::Green(dep_node_index)) => {
144                 self.dep_graph.read_index(dep_node_index);
145                 Some(dep_node_index)
146             }
147             Some(DepNodeColor::Red) => {
148                 None
149             }
150             None => {
151                 // try_mark_green (called below) will panic when full incremental
152                 // compilation is disabled. If that's the case, we can't try to mark nodes
153                 // as green anyway, so we can safely return None here.
154                 if !self.dep_graph.is_fully_enabled() {
155                     return None;
156                 }
157                 match self.dep_graph.try_mark_green(self, &dep_node) {
158                     Some(dep_node_index) => {
159                         debug_assert!(self.dep_graph.is_green(dep_node_index));
160                         self.dep_graph.read_index(dep_node_index);
161                         Some(dep_node_index)
162                     }
163                     None => {
164                         None
165                     }
166                 }
167             }
168         }
169     }
170 }
171
172 // If enabled, send a message to the profile-queries thread
173 macro_rules! profq_msg {
174     ($tcx:expr, $msg:expr) => {
175         if cfg!(debug_assertions) {
176             if  $tcx.sess.profile_queries() {
177                 profq_msg($msg)
178             }
179         }
180     }
181 }
182
183 // If enabled, format a key using its debug string, which can be
184 // expensive to compute (in terms of time).
185 macro_rules! profq_key {
186     ($tcx:expr, $key:expr) => {
187         if cfg!(debug_assertions) {
188             if $tcx.sess.profile_queries_and_keys() {
189                 Some(format!("{:?}", $key))
190             } else { None }
191         } else { None }
192     }
193 }
194
195 macro_rules! define_maps {
196     (<$tcx:tt>
197      $($(#[$attr:meta])*
198        [$($modifiers:tt)*] fn $name:ident: $node:ident($K:ty) -> $V:ty,)*) => {
199
200         use dep_graph::DepNodeIndex;
201         use std::cell::RefCell;
202
203         define_map_struct! {
204             tcx: $tcx,
205             input: ($(([$($modifiers)*] [$($attr)*] [$name]))*)
206         }
207
208         impl<$tcx> Maps<$tcx> {
209             pub fn new(providers: IndexVec<CrateNum, Providers<$tcx>>)
210                        -> Self {
211                 Maps {
212                     providers,
213                     query_stack: RefCell::new(vec![]),
214                     $($name: RefCell::new(QueryMap::new())),*
215                 }
216             }
217         }
218
219         #[allow(bad_style)]
220         #[derive(Copy, Clone, Debug, PartialEq, Eq)]
221         pub enum Query<$tcx> {
222             $($(#[$attr])* $name($K)),*
223         }
224
225         #[allow(bad_style)]
226         #[derive(Clone, Debug, PartialEq, Eq)]
227         pub enum QueryMsg {
228             $($name(Option<String>)),*
229         }
230
231         impl<$tcx> Query<$tcx> {
232             pub fn describe(&self, tcx: TyCtxt) -> String {
233                 let (r, name) = match *self {
234                     $(Query::$name(key) => {
235                         (queries::$name::describe(tcx, key), stringify!($name))
236                     })*
237                 };
238                 if tcx.sess.verbose() {
239                     format!("{} [{}]", r, name)
240                 } else {
241                     r
242                 }
243             }
244         }
245
246         pub mod queries {
247             use std::marker::PhantomData;
248
249             $(#[allow(bad_style)]
250             pub struct $name<$tcx> {
251                 data: PhantomData<&$tcx ()>
252             })*
253         }
254
255         $(impl<$tcx> QueryConfig for queries::$name<$tcx> {
256             type Key = $K;
257             type Value = $V;
258         }
259
260         impl<'a, $tcx, 'lcx> queries::$name<$tcx> {
261
262             #[allow(unused)]
263             fn to_dep_node(tcx: TyCtxt<'a, $tcx, 'lcx>, key: &$K) -> DepNode {
264                 use dep_graph::DepConstructor::*;
265
266                 DepNode::new(tcx, $node(*key))
267             }
268
269             fn try_get_with(tcx: TyCtxt<'a, $tcx, 'lcx>,
270                             mut span: Span,
271                             key: $K)
272                             -> Result<$V, CycleError<'a, $tcx>>
273             {
274                 debug!("ty::queries::{}::try_get_with(key={:?}, span={:?})",
275                        stringify!($name),
276                        key,
277                        span);
278
279                 profq_msg!(tcx,
280                     ProfileQueriesMsg::QueryBegin(
281                         span.data(),
282                         QueryMsg::$name(profq_key!(tcx, key))
283                     )
284                 );
285
286                 if let Some(value) = tcx.maps.$name.borrow().map.get(&key) {
287                     if let Some(ref d) = value.diagnostics {
288                         if !d.emitted_diagnostics.get() {
289                             d.emitted_diagnostics.set(true);
290                             let handle = tcx.sess.diagnostic();
291                             for diagnostic in d.diagnostics.iter() {
292                                 DiagnosticBuilder::new_diagnostic(handle, diagnostic.clone())
293                                     .emit();
294                             }
295                         }
296                     }
297                     profq_msg!(tcx, ProfileQueriesMsg::CacheHit);
298                     tcx.dep_graph.read_index(value.index);
299                     return Ok((&value.value).clone());
300                 }
301
302                 // FIXME(eddyb) Get more valid Span's on queries.
303                 // def_span guard is necessary to prevent a recursive loop,
304                 // default_span calls def_span query internally.
305                 if span == DUMMY_SP && stringify!($name) != "def_span" {
306                     span = key.default_span(tcx)
307                 }
308
309                 // Fast path for when incr. comp. is off. `to_dep_node` is
310                 // expensive for some DepKinds.
311                 if !tcx.dep_graph.is_fully_enabled() {
312                     let null_dep_node = DepNode::new_no_params(::dep_graph::DepKind::Null);
313                     return Self::force(tcx, key, span, null_dep_node)
314                                 .map(|(v, _)| v);
315                 }
316
317                 let dep_node = Self::to_dep_node(tcx, &key);
318
319                 if dep_node.kind.is_anon() {
320                     profq_msg!(tcx, ProfileQueriesMsg::ProviderBegin);
321
322                     let res = tcx.cycle_check(span, Query::$name(key), || {
323                         tcx.sess.diagnostic().track_diagnostics(|| {
324                             tcx.dep_graph.with_anon_task(dep_node.kind, || {
325                                 Self::compute_result(tcx.global_tcx(), key)
326                             })
327                         })
328                     })?;
329
330                     profq_msg!(tcx, ProfileQueriesMsg::ProviderEnd);
331                     let ((result, dep_node_index), diagnostics) = res;
332
333                     tcx.dep_graph.read_index(dep_node_index);
334                     let value = QueryValue::new(result, dep_node_index, diagnostics);
335
336                     return Ok((&tcx.maps
337                                     .$name
338                                     .borrow_mut()
339                                     .map
340                                     .entry(key)
341                                     .or_insert(value)
342                                     .value).clone());
343                 }
344
345                 if !dep_node.kind.is_input() {
346                     if let Some(dep_node_index) = tcx.try_mark_green_and_read(&dep_node) {
347                         profq_msg!(tcx, ProfileQueriesMsg::CacheHit);
348                         return Self::load_from_disk_and_cache_in_memory(tcx,
349                                                                         key,
350                                                                         span,
351                                                                         dep_node_index)
352                     }
353                 }
354
355                 match Self::force(tcx, key, span, dep_node) {
356                     Ok((result, dep_node_index)) => {
357                         tcx.dep_graph.read_index(dep_node_index);
358                         Ok(result)
359                     }
360                     Err(e) => Err(e)
361                 }
362             }
363
364             /// Ensure that either this query has all green inputs or been executed.
365             /// Executing query::ensure(D) is considered a read of the dep-node D.
366             ///
367             /// This function is particularly useful when executing passes for their
368             /// side-effects -- e.g., in order to report errors for erroneous programs.
369             ///
370             /// Note: The optimization is only available during incr. comp.
371             pub fn ensure(tcx: TyCtxt<'a, $tcx, 'lcx>, key: $K) -> () {
372                 let dep_node = Self::to_dep_node(tcx, &key);
373
374                 // Ensuring an "input" or anonymous query makes no sense
375                 assert!(!dep_node.kind.is_anon());
376                 assert!(!dep_node.kind.is_input());
377                 if tcx.try_mark_green_and_read(&dep_node).is_none() {
378                     // A None return from `try_mark_green_and_read` means that this is either
379                     // a new dep node or that the dep node has already been marked red.
380                     // Either way, we can't call `dep_graph.read()` as we don't have the
381                     // DepNodeIndex. We must invoke the query itself. The performance cost
382                     // this introduces should be negligible as we'll immediately hit the
383                     // in-memory cache, or another query down the line will.
384                     let _ = tcx.$name(key);
385                 }
386             }
387
388             fn compute_result(tcx: TyCtxt<'a, $tcx, 'lcx>, key: $K) -> $V {
389                 let provider = tcx.maps.providers[key.map_crate()].$name;
390                 provider(tcx.global_tcx(), key)
391             }
392
393             fn load_from_disk_and_cache_in_memory(tcx: TyCtxt<'a, $tcx, 'lcx>,
394                                                   key: $K,
395                                                   span: Span,
396                                                   dep_node_index: DepNodeIndex)
397                                                   -> Result<$V, CycleError<'a, $tcx>>
398             {
399                 debug_assert!(tcx.dep_graph.is_green(dep_node_index));
400
401                 // We don't do any caching yet, so recompute
402                 let (result, diagnostics) = tcx.cycle_check(span, Query::$name(key), || {
403                     tcx.sess.diagnostic().track_diagnostics(|| {
404                         // The dep-graph for this computation is already in place
405                         tcx.dep_graph.with_ignore(|| {
406                             Self::compute_result(tcx, key)
407                         })
408                     })
409                 })?;
410
411                 if tcx.sess.opts.debugging_opts.query_dep_graph {
412                     tcx.dep_graph.mark_loaded_from_cache(dep_node_index, true);
413                 }
414
415                 let value = QueryValue::new(result, dep_node_index, diagnostics);
416
417                 Ok((&tcx.maps
418                          .$name
419                          .borrow_mut()
420                          .map
421                          .entry(key)
422                          .or_insert(value)
423                          .value).clone())
424             }
425
426             fn force(tcx: TyCtxt<'a, $tcx, 'lcx>,
427                      key: $K,
428                      span: Span,
429                      dep_node: DepNode)
430                      -> Result<($V, DepNodeIndex), CycleError<'a, $tcx>> {
431                 debug_assert!(tcx.dep_graph.node_color(&dep_node).is_none());
432
433                 profq_msg!(tcx, ProfileQueriesMsg::ProviderBegin);
434                 let res = tcx.cycle_check(span, Query::$name(key), || {
435                     tcx.sess.diagnostic().track_diagnostics(|| {
436                         if dep_node.kind.is_eval_always() {
437                             tcx.dep_graph.with_eval_always_task(dep_node,
438                                                                 tcx,
439                                                                 key,
440                                                                 Self::compute_result)
441                         } else {
442                             tcx.dep_graph.with_task(dep_node,
443                                                     tcx,
444                                                     key,
445                                                     Self::compute_result)
446                         }
447                     })
448                 })?;
449                 profq_msg!(tcx, ProfileQueriesMsg::ProviderEnd);
450
451                 let ((result, dep_node_index), diagnostics) = res;
452
453                 if tcx.sess.opts.debugging_opts.query_dep_graph {
454                     tcx.dep_graph.mark_loaded_from_cache(dep_node_index, false);
455                 }
456
457                 let value = QueryValue::new(result, dep_node_index, diagnostics);
458
459                 Ok(((&tcx.maps
460                          .$name
461                          .borrow_mut()
462                          .map
463                          .entry(key)
464                          .or_insert(value)
465                          .value).clone(),
466                    dep_node_index))
467             }
468
469             pub fn try_get(tcx: TyCtxt<'a, $tcx, 'lcx>, span: Span, key: $K)
470                            -> Result<$V, DiagnosticBuilder<'a>> {
471                 match Self::try_get_with(tcx, span, key) {
472                     Ok(e) => Ok(e),
473                     Err(e) => Err(tcx.report_cycle(e)),
474                 }
475             }
476         })*
477
478         #[derive(Copy, Clone)]
479         pub struct TyCtxtAt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
480             pub tcx: TyCtxt<'a, 'gcx, 'tcx>,
481             pub span: Span,
482         }
483
484         impl<'a, 'gcx, 'tcx> Deref for TyCtxtAt<'a, 'gcx, 'tcx> {
485             type Target = TyCtxt<'a, 'gcx, 'tcx>;
486             fn deref(&self) -> &Self::Target {
487                 &self.tcx
488             }
489         }
490
491         impl<'a, $tcx, 'lcx> TyCtxt<'a, $tcx, 'lcx> {
492             /// Return a transparent wrapper for `TyCtxt` which uses
493             /// `span` as the location of queries performed through it.
494             pub fn at(self, span: Span) -> TyCtxtAt<'a, $tcx, 'lcx> {
495                 TyCtxtAt {
496                     tcx: self,
497                     span
498                 }
499             }
500
501             $($(#[$attr])*
502             pub fn $name(self, key: $K) -> $V {
503                 self.at(DUMMY_SP).$name(key)
504             })*
505         }
506
507         impl<'a, $tcx, 'lcx> TyCtxtAt<'a, $tcx, 'lcx> {
508             $($(#[$attr])*
509             pub fn $name(self, key: $K) -> $V {
510                 queries::$name::try_get(self.tcx, self.span, key).unwrap_or_else(|mut e| {
511                     e.emit();
512                     Value::from_cycle_error(self.global_tcx())
513                 })
514             })*
515         }
516
517         define_provider_struct! {
518             tcx: $tcx,
519             input: ($(([$($modifiers)*] [$name] [$K] [$V]))*)
520         }
521
522         impl<$tcx> Copy for Providers<$tcx> {}
523         impl<$tcx> Clone for Providers<$tcx> {
524             fn clone(&self) -> Self { *self }
525         }
526     }
527 }
528
529 macro_rules! define_map_struct {
530     (tcx: $tcx:tt,
531      input: ($(([$(modifiers:tt)*] [$($attr:tt)*] [$name:ident]))*)) => {
532         pub struct Maps<$tcx> {
533             providers: IndexVec<CrateNum, Providers<$tcx>>,
534             query_stack: RefCell<Vec<(Span, Query<$tcx>)>>,
535             $($(#[$attr])*  $name: RefCell<QueryMap<queries::$name<$tcx>>>,)*
536         }
537     };
538 }
539
540 macro_rules! define_provider_struct {
541     (tcx: $tcx:tt,
542      input: ($(([$($modifiers:tt)*] [$name:ident] [$K:ty] [$R:ty]))*)) => {
543         pub struct Providers<$tcx> {
544             $(pub $name: for<'a> fn(TyCtxt<'a, $tcx, $tcx>, $K) -> $R,)*
545         }
546
547         impl<$tcx> Default for Providers<$tcx> {
548             fn default() -> Self {
549                 $(fn $name<'a, $tcx>(_: TyCtxt<'a, $tcx, $tcx>, key: $K) -> $R {
550                     bug!("tcx.maps.{}({:?}) unsupported by its crate",
551                          stringify!($name), key);
552                 })*
553                 Providers { $($name),* }
554             }
555         }
556     };
557 }
558
559
560 /// The red/green evaluation system will try to mark a specific DepNode in the
561 /// dependency graph as green by recursively trying to mark the dependencies of
562 /// that DepNode as green. While doing so, it will sometimes encounter a DepNode
563 /// where we don't know if it is red or green and we therefore actually have
564 /// to recompute its value in order to find out. Since the only piece of
565 /// information that we have at that point is the DepNode we are trying to
566 /// re-evaluate, we need some way to re-run a query from just that. This is what
567 /// `force_from_dep_node()` implements.
568 ///
569 /// In the general case, a DepNode consists of a DepKind and an opaque
570 /// GUID/fingerprint that will uniquely identify the node. This GUID/fingerprint
571 /// is usually constructed by computing a stable hash of the query-key that the
572 /// DepNode corresponds to. Consequently, it is not in general possible to go
573 /// back from hash to query-key (since hash functions are not reversible). For
574 /// this reason `force_from_dep_node()` is expected to fail from time to time
575 /// because we just cannot find out, from the DepNode alone, what the
576 /// corresponding query-key is and therefore cannot re-run the query.
577 ///
578 /// The system deals with this case letting `try_mark_green` fail which forces
579 /// the root query to be re-evaluated.
580 ///
581 /// Now, if force_from_dep_node() would always fail, it would be pretty useless.
582 /// Fortunately, we can use some contextual information that will allow us to
583 /// reconstruct query-keys for certain kinds of DepNodes. In particular, we
584 /// enforce by construction that the GUID/fingerprint of certain DepNodes is a
585 /// valid DefPathHash. Since we also always build a huge table that maps every
586 /// DefPathHash in the current codebase to the corresponding DefId, we have
587 /// everything we need to re-run the query.
588 ///
589 /// Take the `mir_validated` query as an example. Like many other queries, it
590 /// just has a single parameter: the DefId of the item it will compute the
591 /// validated MIR for. Now, when we call `force_from_dep_node()` on a dep-node
592 /// with kind `MirValidated`, we know that the GUID/fingerprint of the dep-node
593 /// is actually a DefPathHash, and can therefore just look up the corresponding
594 /// DefId in `tcx.def_path_hash_to_def_id`.
595 ///
596 /// When you implement a new query, it will likely have a corresponding new
597 /// DepKind, and you'll have to support it here in `force_from_dep_node()`. As
598 /// a rule of thumb, if your query takes a DefId or DefIndex as sole parameter,
599 /// then `force_from_dep_node()` should not fail for it. Otherwise, you can just
600 /// add it to the "We don't have enough information to reconstruct..." group in
601 /// the match below.
602 pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
603                                            dep_node: &DepNode)
604                                            -> bool {
605     use ty::maps::keys::Key;
606     use hir::def_id::LOCAL_CRATE;
607
608     // We must avoid ever having to call force_from_dep_node() for a
609     // DepNode::CodegenUnit:
610     // Since we cannot reconstruct the query key of a DepNode::CodegenUnit, we
611     // would always end up having to evaluate the first caller of the
612     // `codegen_unit` query that *is* reconstructible. This might very well be
613     // the `compile_codegen_unit` query, thus re-translating the whole CGU just
614     // to re-trigger calling the `codegen_unit` query with the right key. At
615     // that point we would already have re-done all the work we are trying to
616     // avoid doing in the first place.
617     // The solution is simple: Just explicitly call the `codegen_unit` query for
618     // each CGU, right after partitioning. This way `try_mark_green` will always
619     // hit the cache instead of having to go through `force_from_dep_node`.
620     // This assertion makes sure, we actually keep applying the solution above.
621     debug_assert!(dep_node.kind != DepKind::CodegenUnit,
622                   "calling force_from_dep_node() on DepKind::CodegenUnit");
623
624     if !dep_node.kind.can_reconstruct_query_key() {
625         return false
626     }
627
628     macro_rules! def_id {
629         () => {
630             if let Some(def_id) = dep_node.extract_def_id(tcx) {
631                 def_id
632             } else {
633                 // return from the whole function
634                 return false
635             }
636         }
637     };
638
639     macro_rules! krate {
640         () => { (def_id!()).krate }
641     };
642
643     macro_rules! force {
644         ($query:ident, $key:expr) => {
645             {
646                 use $crate::util::common::{ProfileQueriesMsg, profq_msg};
647
648                 // FIXME(eddyb) Get more valid Span's on queries.
649                 // def_span guard is necessary to prevent a recursive loop,
650                 // default_span calls def_span query internally.
651                 let span = if stringify!($query) != "def_span" {
652                     $key.default_span(tcx)
653                 } else {
654                     ::syntax_pos::DUMMY_SP
655                 };
656
657                 profq_msg!(tcx,
658                     ProfileQueriesMsg::QueryBegin(
659                         span.data(),
660                         ::ty::maps::QueryMsg::$query(profq_key!(tcx, $key))
661                     )
662                 );
663
664                 match ::ty::maps::queries::$query::force(tcx, $key, span, *dep_node) {
665                     Ok(_) => {},
666                     Err(e) => {
667                         tcx.report_cycle(e).emit();
668                     }
669                 }
670             }
671         }
672     };
673
674     // FIXME(#45015): We should try move this boilerplate code into a macro
675     //                somehow.
676     match dep_node.kind {
677         // These are inputs that are expected to be pre-allocated and that
678         // should therefore always be red or green already
679         DepKind::AllLocalTraitImpls |
680         DepKind::Krate |
681         DepKind::CrateMetadata |
682         DepKind::HirBody |
683         DepKind::Hir |
684
685         // This are anonymous nodes
686         DepKind::TraitSelect |
687
688         // We don't have enough information to reconstruct the query key of
689         // these
690         DepKind::IsCopy |
691         DepKind::IsSized |
692         DepKind::IsFreeze |
693         DepKind::NeedsDrop |
694         DepKind::Layout |
695         DepKind::ConstEval |
696         DepKind::InstanceSymbolName |
697         DepKind::MirShim |
698         DepKind::BorrowCheckKrate |
699         DepKind::Specializes |
700         DepKind::ImplementationsOfTrait |
701         DepKind::TypeParamPredicates |
702         DepKind::CodegenUnit |
703         DepKind::CompileCodegenUnit |
704         DepKind::FulfillObligation |
705         DepKind::VtableMethods |
706         DepKind::EraseRegionsTy |
707         DepKind::NormalizeTy |
708
709         // These are just odd
710         DepKind::Null |
711         DepKind::WorkProduct => {
712             bug!("force_from_dep_node() - Encountered {:?}", dep_node.kind)
713         }
714
715         // These are not queries
716         DepKind::CoherenceCheckTrait |
717         DepKind::ItemVarianceConstraints => {
718             return false
719         }
720
721         DepKind::RegionScopeTree => { force!(region_scope_tree, def_id!()); }
722
723         DepKind::Coherence => { force!(crate_inherent_impls, LOCAL_CRATE); }
724         DepKind::CoherenceInherentImplOverlapCheck => {
725             force!(crate_inherent_impls_overlap_check, LOCAL_CRATE)
726         },
727         DepKind::PrivacyAccessLevels => { force!(privacy_access_levels, LOCAL_CRATE); }
728         DepKind::MirConstQualif => { force!(mir_const_qualif, def_id!()); }
729         DepKind::MirConst => { force!(mir_const, def_id!()); }
730         DepKind::MirValidated => { force!(mir_validated, def_id!()); }
731         DepKind::MirOptimized => { force!(optimized_mir, def_id!()); }
732
733         DepKind::BorrowCheck => { force!(borrowck, def_id!()); }
734         DepKind::MirBorrowCheck => { force!(mir_borrowck, def_id!()); }
735         DepKind::UnsafetyViolations => { force!(unsafety_violations, def_id!()); }
736         DepKind::Reachability => { force!(reachable_set, LOCAL_CRATE); }
737         DepKind::MirKeys => { force!(mir_keys, LOCAL_CRATE); }
738         DepKind::CrateVariances => { force!(crate_variances, LOCAL_CRATE); }
739         DepKind::AssociatedItems => { force!(associated_item, def_id!()); }
740         DepKind::TypeOfItem => { force!(type_of, def_id!()); }
741         DepKind::GenericsOfItem => { force!(generics_of, def_id!()); }
742         DepKind::PredicatesOfItem => { force!(predicates_of, def_id!()); }
743         DepKind::InferredOutlivesOf => { force!(inferred_outlives_of, def_id!()); }
744         DepKind::SuperPredicatesOfItem => { force!(super_predicates_of, def_id!()); }
745         DepKind::TraitDefOfItem => { force!(trait_def, def_id!()); }
746         DepKind::AdtDefOfItem => { force!(adt_def, def_id!()); }
747         DepKind::IsDefaultImpl => { force!(is_default_impl, def_id!()); }
748         DepKind::ImplTraitRef => { force!(impl_trait_ref, def_id!()); }
749         DepKind::ImplPolarity => { force!(impl_polarity, def_id!()); }
750         DepKind::ClosureKind => { force!(closure_kind, def_id!()); }
751         DepKind::FnSignature => { force!(fn_sig, def_id!()); }
752         DepKind::GenSignature => { force!(generator_sig, def_id!()); }
753         DepKind::CoerceUnsizedInfo => { force!(coerce_unsized_info, def_id!()); }
754         DepKind::ItemVariances => { force!(variances_of, def_id!()); }
755         DepKind::IsConstFn => { force!(is_const_fn, def_id!()); }
756         DepKind::IsForeignItem => { force!(is_foreign_item, def_id!()); }
757         DepKind::SizedConstraint => { force!(adt_sized_constraint, def_id!()); }
758         DepKind::DtorckConstraint => { force!(adt_dtorck_constraint, def_id!()); }
759         DepKind::AdtDestructor => { force!(adt_destructor, def_id!()); }
760         DepKind::AssociatedItemDefIds => { force!(associated_item_def_ids, def_id!()); }
761         DepKind::InherentImpls => { force!(inherent_impls, def_id!()); }
762         DepKind::TypeckBodiesKrate => { force!(typeck_item_bodies, LOCAL_CRATE); }
763         DepKind::TypeckTables => { force!(typeck_tables_of, def_id!()); }
764         DepKind::UsedTraitImports => { force!(used_trait_imports, def_id!()); }
765         DepKind::HasTypeckTables => { force!(has_typeck_tables, def_id!()); }
766         DepKind::SymbolName => { force!(def_symbol_name, def_id!()); }
767         DepKind::SpecializationGraph => { force!(specialization_graph_of, def_id!()); }
768         DepKind::ObjectSafety => { force!(is_object_safe, def_id!()); }
769         DepKind::TraitImpls => { force!(trait_impls_of, def_id!()); }
770
771         DepKind::ParamEnv => { force!(param_env, def_id!()); }
772         DepKind::DescribeDef => { force!(describe_def, def_id!()); }
773         DepKind::DefSpan => { force!(def_span, def_id!()); }
774         DepKind::LookupStability => { force!(lookup_stability, def_id!()); }
775         DepKind::LookupDeprecationEntry => {
776             force!(lookup_deprecation_entry, def_id!());
777         }
778         DepKind::ItemBodyNestedBodies => { force!(item_body_nested_bodies, def_id!()); }
779         DepKind::ConstIsRvaluePromotableToStatic => {
780             force!(const_is_rvalue_promotable_to_static, def_id!());
781         }
782         DepKind::RvaluePromotableMap => { force!(rvalue_promotable_map, def_id!()); }
783         DepKind::ImplParent => { force!(impl_parent, def_id!()); }
784         DepKind::TraitOfItem => { force!(trait_of_item, def_id!()); }
785         DepKind::IsExportedSymbol => { force!(is_exported_symbol, def_id!()); }
786         DepKind::IsMirAvailable => { force!(is_mir_available, def_id!()); }
787         DepKind::ItemAttrs => { force!(item_attrs, def_id!()); }
788         DepKind::FnArgNames => { force!(fn_arg_names, def_id!()); }
789         DepKind::DylibDepFormats => { force!(dylib_dependency_formats, krate!()); }
790         DepKind::IsPanicRuntime => { force!(is_panic_runtime, krate!()); }
791         DepKind::IsCompilerBuiltins => { force!(is_compiler_builtins, krate!()); }
792         DepKind::HasGlobalAllocator => { force!(has_global_allocator, krate!()); }
793         DepKind::ExternCrate => { force!(extern_crate, def_id!()); }
794         DepKind::LintLevels => { force!(lint_levels, LOCAL_CRATE); }
795         DepKind::InScopeTraits => { force!(in_scope_traits_map, def_id!().index); }
796         DepKind::ModuleExports => { force!(module_exports, def_id!()); }
797         DepKind::IsSanitizerRuntime => { force!(is_sanitizer_runtime, krate!()); }
798         DepKind::IsProfilerRuntime => { force!(is_profiler_runtime, krate!()); }
799         DepKind::GetPanicStrategy => { force!(panic_strategy, krate!()); }
800         DepKind::IsNoBuiltins => { force!(is_no_builtins, krate!()); }
801         DepKind::ImplDefaultness => { force!(impl_defaultness, def_id!()); }
802         DepKind::ExportedSymbolIds => { force!(exported_symbol_ids, krate!()); }
803         DepKind::NativeLibraries => { force!(native_libraries, krate!()); }
804         DepKind::PluginRegistrarFn => { force!(plugin_registrar_fn, krate!()); }
805         DepKind::DeriveRegistrarFn => { force!(derive_registrar_fn, krate!()); }
806         DepKind::CrateDisambiguator => { force!(crate_disambiguator, krate!()); }
807         DepKind::CrateHash => { force!(crate_hash, krate!()); }
808         DepKind::OriginalCrateName => { force!(original_crate_name, krate!()); }
809
810         DepKind::AllTraitImplementations => {
811             force!(all_trait_implementations, krate!());
812         }
813
814         DepKind::IsDllimportForeignItem => {
815             force!(is_dllimport_foreign_item, def_id!());
816         }
817         DepKind::IsStaticallyIncludedForeignItem => {
818             force!(is_statically_included_foreign_item, def_id!());
819         }
820         DepKind::NativeLibraryKind => { force!(native_library_kind, def_id!()); }
821         DepKind::LinkArgs => { force!(link_args, LOCAL_CRATE); }
822
823         DepKind::NamedRegion => { force!(named_region_map, def_id!().index); }
824         DepKind::IsLateBound => { force!(is_late_bound_map, def_id!().index); }
825         DepKind::ObjectLifetimeDefaults => {
826             force!(object_lifetime_defaults_map, def_id!().index);
827         }
828
829         DepKind::Visibility => { force!(visibility, def_id!()); }
830         DepKind::DepKind => { force!(dep_kind, krate!()); }
831         DepKind::CrateName => { force!(crate_name, krate!()); }
832         DepKind::ItemChildren => { force!(item_children, def_id!()); }
833         DepKind::ExternModStmtCnum => { force!(extern_mod_stmt_cnum, def_id!()); }
834         DepKind::GetLangItems => { force!(get_lang_items, LOCAL_CRATE); }
835         DepKind::DefinedLangItems => { force!(defined_lang_items, krate!()); }
836         DepKind::MissingLangItems => { force!(missing_lang_items, krate!()); }
837         DepKind::ExternConstBody => { force!(extern_const_body, def_id!()); }
838         DepKind::VisibleParentMap => { force!(visible_parent_map, LOCAL_CRATE); }
839         DepKind::MissingExternCrateItem => {
840             force!(missing_extern_crate_item, krate!());
841         }
842         DepKind::UsedCrateSource => { force!(used_crate_source, krate!()); }
843         DepKind::PostorderCnums => { force!(postorder_cnums, LOCAL_CRATE); }
844         DepKind::HasCloneClosures => { force!(has_clone_closures, krate!()); }
845         DepKind::HasCopyClosures => { force!(has_copy_closures, krate!()); }
846
847         DepKind::Freevars => { force!(freevars, def_id!()); }
848         DepKind::MaybeUnusedTraitImport => {
849             force!(maybe_unused_trait_import, def_id!());
850         }
851         DepKind::MaybeUnusedExternCrates => { force!(maybe_unused_extern_crates, LOCAL_CRATE); }
852         DepKind::StabilityIndex => { force!(stability_index, LOCAL_CRATE); }
853         DepKind::AllCrateNums => { force!(all_crate_nums, LOCAL_CRATE); }
854         DepKind::ExportedSymbols => { force!(exported_symbols, krate!()); }
855         DepKind::CollectAndPartitionTranslationItems => {
856             force!(collect_and_partition_translation_items, LOCAL_CRATE);
857         }
858         DepKind::ExportName => { force!(export_name, def_id!()); }
859         DepKind::ContainsExternIndicator => {
860             force!(contains_extern_indicator, def_id!());
861         }
862         DepKind::IsTranslatedFunction => { force!(is_translated_function, def_id!()); }
863         DepKind::OutputFilenames => { force!(output_filenames, LOCAL_CRATE); }
864     }
865
866     true
867 }
868