]> git.lizzy.rs Git - rust.git/blob - src/librustc/dep_graph/dep_node.rs
56b218889854d0a49121b063c42018359575c297
[rust.git] / src / librustc / dep_graph / dep_node.rs
1 // Copyright 2014 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
12 //! This module defines the `DepNode` type which the compiler uses to represent
13 //! nodes in the dependency graph. A `DepNode` consists of a `DepKind` (which
14 //! specifies the kind of thing it represents, like a piece of HIR, MIR, etc)
15 //! and a `Fingerprint`, a 128 bit hash value the exact meaning of which
16 //! depends on the node's `DepKind`. Together, the kind and the fingerprint
17 //! fully identify a dependency node, even across multiple compilation sessions.
18 //! In other words, the value of the fingerprint does not depend on anything
19 //! that is specific to a given compilation session, like an unpredictable
20 //! interning key (e.g. NodeId, DefId, Symbol) or the numeric value of a
21 //! pointer. The concept behind this could be compared to how git commit hashes
22 //! uniquely identify a given commit and has a few advantages:
23 //!
24 //! * A `DepNode` can simply be serialized to disk and loaded in another session
25 //!   without the need to do any "rebasing (like we have to do for Spans and
26 //!   NodeIds) or "retracing" like we had to do for `DefId` in earlier
27 //!   implementations of the dependency graph.
28 //! * A `Fingerprint` is just a bunch of bits, which allows `DepNode` to
29 //!   implement `Copy`, `Sync`, `Send`, `Freeze`, etc.
30 //! * Since we just have a bit pattern, `DepNode` can be mapped from disk into
31 //!   memory without any post-processing (e.g. "abomination-style" pointer
32 //!   reconstruction).
33 //! * Because a `DepNode` is self-contained, we can instantiate `DepNodes` that
34 //!   refer to things that do not exist anymore. In previous implementations
35 //!   `DepNode` contained a `DefId`. A `DepNode` referring to something that
36 //!   had been removed between the previous and the current compilation session
37 //!   could not be instantiated because the current compilation session
38 //!   contained no `DefId` for thing that had been removed.
39 //!
40 //! `DepNode` definition happens in the `define_dep_nodes!()` macro. This macro
41 //! defines the `DepKind` enum and a corresponding `DepConstructor` enum. The
42 //! `DepConstructor` enum links a `DepKind` to the parameters that are needed at
43 //! runtime in order to construct a valid `DepNode` fingerprint.
44 //!
45 //! Because the macro sees what parameters a given `DepKind` requires, it can
46 //! "infer" some properties for each kind of `DepNode`:
47 //!
48 //! * Whether a `DepNode` of a given kind has any parameters at all. Some
49 //!   `DepNode`s, like `Krate`, represent global concepts with only one value.
50 //! * Whether it is possible, in principle, to reconstruct a query key from a
51 //!   given `DepNode`. Many `DepKind`s only require a single `DefId` parameter,
52 //!   in which case it is possible to map the node's fingerprint back to the
53 //!   `DefId` it was computed from. In other cases, too much information gets
54 //!   lost during fingerprint computation.
55 //!
56 //! The `DepConstructor` enum, together with `DepNode::new()` ensures that only
57 //! valid `DepNode` instances can be constructed. For example, the API does not
58 //! allow for constructing parameterless `DepNode`s with anything other
59 //! than a zeroed out fingerprint. More generally speaking, it relieves the
60 //! user of the `DepNode` API of having to know how to compute the expected
61 //! fingerprint for a given set of node parameters.
62
63 use hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX};
64 use hir::map::DefPathHash;
65 use hir::{HirId, ItemLocalId};
66
67 use ich::Fingerprint;
68 use ty::{TyCtxt, Instance, InstanceDef, ParamEnv, ParamEnvAnd, PolyTraitRef, Ty};
69 use ty::subst::Substs;
70 use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
71 use ich::StableHashingContext;
72 use std::fmt;
73 use std::hash::Hash;
74 use syntax_pos::symbol::InternedString;
75
76 // erase!() just makes tokens go away. It's used to specify which macro argument
77 // is repeated (i.e. which sub-expression of the macro we are in) but don't need
78 // to actually use any of the arguments.
79 macro_rules! erase {
80     ($x:tt) => ({})
81 }
82
83 macro_rules! is_anon_attr {
84     (anon) => (true);
85     ($attr:ident) => (false);
86 }
87
88 macro_rules! is_input_attr {
89     (input) => (true);
90     ($attr:ident) => (false);
91 }
92
93 macro_rules! contains_anon_attr {
94     ($($attr:ident),*) => ({$(is_anon_attr!($attr) | )* false});
95 }
96
97 macro_rules! contains_input_attr {
98     ($($attr:ident),*) => ({$(is_input_attr!($attr) | )* false});
99 }
100
101 macro_rules! define_dep_nodes {
102     (<$tcx:tt>
103     $(
104         [$($attr:ident),* ]
105         $variant:ident $(( $($tuple_arg:tt),* ))*
106                        $({ $($struct_arg_name:ident : $struct_arg_ty:ty),* })*
107       ,)*
108     ) => (
109         #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash,
110                  RustcEncodable, RustcDecodable)]
111         pub enum DepKind {
112             $($variant),*
113         }
114
115         impl DepKind {
116             #[allow(unreachable_code)]
117             #[inline]
118             pub fn can_reconstruct_query_key<$tcx>(&self) -> bool {
119                 match *self {
120                     $(
121                         DepKind :: $variant => {
122                             if contains_anon_attr!($($attr),*) {
123                                 return false;
124                             }
125
126                             // tuple args
127                             $({
128                                 return <( $($tuple_arg,)* ) as DepNodeParams>
129                                     ::CAN_RECONSTRUCT_QUERY_KEY;
130                             })*
131
132                             // struct args
133                             $({
134
135                                 return <( $($struct_arg_ty,)* ) as DepNodeParams>
136                                     ::CAN_RECONSTRUCT_QUERY_KEY;
137                             })*
138
139                             true
140                         }
141                     )*
142                 }
143             }
144
145             #[inline]
146             pub fn is_anon(&self) -> bool {
147                 match *self {
148                     $(
149                         DepKind :: $variant => { contains_anon_attr!($($attr),*) }
150                     )*
151                 }
152             }
153
154             #[inline]
155             pub fn is_input(&self) -> bool {
156                 match *self {
157                     $(
158                         DepKind :: $variant => { contains_input_attr!($($attr),*) }
159                     )*
160                 }
161             }
162
163             #[allow(unreachable_code)]
164             #[inline]
165             pub fn has_params(&self) -> bool {
166                 match *self {
167                     $(
168                         DepKind :: $variant => {
169                             // tuple args
170                             $({
171                                 $(erase!($tuple_arg);)*
172                                 return true;
173                             })*
174
175                             // struct args
176                             $({
177                                 $(erase!($struct_arg_name);)*
178                                 return true;
179                             })*
180
181                             false
182                         }
183                     )*
184                 }
185             }
186         }
187
188         pub enum DepConstructor<$tcx> {
189             $(
190                 $variant $(( $($tuple_arg),* ))*
191                          $({ $($struct_arg_name : $struct_arg_ty),* })*
192             ),*
193         }
194
195         #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash,
196                  RustcEncodable, RustcDecodable)]
197         pub struct DepNode {
198             pub kind: DepKind,
199             pub hash: Fingerprint,
200         }
201
202         impl DepNode {
203             #[allow(unreachable_code, non_snake_case)]
204             pub fn new<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
205                                        dep: DepConstructor<'gcx>)
206                                        -> DepNode
207                 where 'gcx: 'a + 'tcx,
208                       'tcx: 'a
209             {
210                 match dep {
211                     $(
212                         DepConstructor :: $variant $(( $($tuple_arg),* ))*
213                                                    $({ $($struct_arg_name),* })*
214                             =>
215                         {
216                             // tuple args
217                             $({
218                                 let tupled_args = ( $($tuple_arg,)* );
219                                 let hash = DepNodeParams::to_fingerprint(&tupled_args,
220                                                                          tcx);
221                                 let dep_node = DepNode {
222                                     kind: DepKind::$variant,
223                                     hash
224                                 };
225
226                                 if cfg!(debug_assertions) &&
227                                    !dep_node.kind.can_reconstruct_query_key() &&
228                                    (tcx.sess.opts.debugging_opts.incremental_info ||
229                                     tcx.sess.opts.debugging_opts.query_dep_graph)
230                                 {
231                                     tcx.dep_graph.register_dep_node_debug_str(dep_node, || {
232                                         tupled_args.to_debug_str(tcx)
233                                     });
234                                 }
235
236                                 return dep_node;
237                             })*
238
239                             // struct args
240                             $({
241                                 let tupled_args = ( $($struct_arg_name,)* );
242                                 let hash = DepNodeParams::to_fingerprint(&tupled_args,
243                                                                          tcx);
244                                 let dep_node = DepNode {
245                                     kind: DepKind::$variant,
246                                     hash
247                                 };
248
249                                 if cfg!(debug_assertions) &&
250                                    !dep_node.kind.can_reconstruct_query_key() &&
251                                    (tcx.sess.opts.debugging_opts.incremental_info ||
252                                     tcx.sess.opts.debugging_opts.query_dep_graph)
253                                 {
254                                     tcx.dep_graph.register_dep_node_debug_str(dep_node, || {
255                                         tupled_args.to_debug_str(tcx)
256                                     });
257                                 }
258
259                                 return dep_node;
260                             })*
261
262                             DepNode {
263                                 kind: DepKind::$variant,
264                                 hash: Fingerprint::zero(),
265                             }
266                         }
267                     )*
268                 }
269             }
270
271             /// Construct a DepNode from the given DepKind and DefPathHash. This
272             /// method will assert that the given DepKind actually requires a
273             /// single DefId/DefPathHash parameter.
274             #[inline]
275             pub fn from_def_path_hash(kind: DepKind,
276                                       def_path_hash: DefPathHash)
277                                       -> DepNode {
278                 assert!(kind.can_reconstruct_query_key() && kind.has_params());
279                 DepNode {
280                     kind,
281                     hash: def_path_hash.0,
282                 }
283             }
284
285             /// Create a new, parameterless DepNode. This method will assert
286             /// that the DepNode corresponding to the given DepKind actually
287             /// does not require any parameters.
288             #[inline]
289             pub fn new_no_params(kind: DepKind) -> DepNode {
290                 assert!(!kind.has_params());
291                 DepNode {
292                     kind,
293                     hash: Fingerprint::zero(),
294                 }
295             }
296
297             /// Extract the DefId corresponding to this DepNode. This will work
298             /// if two conditions are met:
299             ///
300             /// 1. The Fingerprint of the DepNode actually is a DefPathHash, and
301             /// 2. the item that the DefPath refers to exists in the current tcx.
302             ///
303             /// Condition (1) is determined by the DepKind variant of the
304             /// DepNode. Condition (2) might not be fulfilled if a DepNode
305             /// refers to something from the previous compilation session that
306             /// has been removed.
307             #[inline]
308             pub fn extract_def_id(&self, tcx: TyCtxt) -> Option<DefId> {
309                 if self.kind.can_reconstruct_query_key() {
310                     let def_path_hash = DefPathHash(self.hash);
311                     if let Some(ref def_path_map) = tcx.def_path_hash_to_def_id.as_ref() {
312                         def_path_map.get(&def_path_hash).cloned()
313                     } else {
314                        None
315                     }
316                 } else {
317                     None
318                 }
319             }
320
321             /// Used in testing
322             pub fn from_label_string(label: &str,
323                                      def_path_hash: DefPathHash)
324                                      -> Result<DepNode, ()> {
325                 let kind = match label {
326                     $(
327                         stringify!($variant) => DepKind::$variant,
328                     )*
329                     _ => return Err(()),
330                 };
331
332                 if !kind.can_reconstruct_query_key() {
333                     return Err(());
334                 }
335
336                 if kind.has_params() {
337                     Ok(def_path_hash.to_dep_node(kind))
338                 } else {
339                     Ok(DepNode::new_no_params(kind))
340                 }
341             }
342
343             /// Used in testing
344             pub fn has_label_string(label: &str) -> bool {
345                 match label {
346                     $(
347                         stringify!($variant) => true,
348                     )*
349                     _ => false,
350                 }
351             }
352         }
353
354         /// Contains variant => str representations for constructing
355         /// DepNode groups for tests.
356         #[allow(dead_code, non_upper_case_globals)]
357         pub mod label_strs {
358            $(
359                 pub const $variant: &'static str = stringify!($variant);
360             )*
361         }
362     );
363 }
364
365 impl fmt::Debug for DepNode {
366     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
367         write!(f, "{:?}", self.kind)?;
368
369         if !self.kind.has_params() && !self.kind.is_anon() {
370             return Ok(());
371         }
372
373         write!(f, "(")?;
374
375         ::ty::tls::with_opt(|opt_tcx| {
376             if let Some(tcx) = opt_tcx {
377                 if let Some(def_id) = self.extract_def_id(tcx) {
378                     write!(f, "{}", tcx.def_path_debug_str(def_id))?;
379                 } else if let Some(ref s) = tcx.dep_graph.dep_node_debug_str(*self) {
380                     write!(f, "{}", s)?;
381                 } else {
382                     write!(f, "{}", self.hash)?;
383                 }
384             } else {
385                 write!(f, "{}", self.hash)?;
386             }
387             Ok(())
388         })?;
389
390         write!(f, ")")
391     }
392 }
393
394
395 impl DefPathHash {
396     #[inline]
397     pub fn to_dep_node(self, kind: DepKind) -> DepNode {
398         DepNode::from_def_path_hash(kind, self)
399     }
400 }
401
402 impl DefId {
403     #[inline]
404     pub fn to_dep_node(self, tcx: TyCtxt, kind: DepKind) -> DepNode {
405         DepNode::from_def_path_hash(kind, tcx.def_path_hash(self))
406     }
407 }
408
409 impl DepKind {
410     #[inline]
411     pub fn fingerprint_needed_for_crate_hash(self) -> bool {
412         match self {
413             DepKind::HirBody |
414             DepKind::Krate => true,
415             _ => false,
416         }
417     }
418 }
419
420 define_dep_nodes!( <'tcx>
421     // Represents the `Krate` as a whole (the `hir::Krate` value) (as
422     // distinct from the krate module). This is basically a hash of
423     // the entire krate, so if you read from `Krate` (e.g., by calling
424     // `tcx.hir.krate()`), we will have to assume that any change
425     // means that you need to be recompiled. This is because the
426     // `Krate` value gives you access to all other items. To avoid
427     // this fate, do not call `tcx.hir.krate()`; instead, prefer
428     // wrappers like `tcx.visit_all_items_in_krate()`.  If there is no
429     // suitable wrapper, you can use `tcx.dep_graph.ignore()` to gain
430     // access to the krate, but you must remember to add suitable
431     // edges yourself for the individual items that you read.
432     [input] Krate,
433
434     // Represents the body of a function or method. The def-id is that of the
435     // function/method.
436     [input] HirBody(DefId),
437
438     // Represents the HIR node with the given node-id
439     [input] Hir(DefId),
440
441     // Represents metadata from an extern crate.
442     [input] CrateMetadata(CrateNum),
443
444     // Represents some artifact that we save to disk. Note that these
445     // do not have a def-id as part of their identifier.
446     [] WorkProduct(WorkProductId),
447
448     // Represents different phases in the compiler.
449     [] RegionScopeTree(DefId),
450     [] Coherence,
451     [] CoherenceInherentImplOverlapCheck,
452     [] CoherenceCheckTrait(DefId),
453     [] PrivacyAccessLevels(CrateNum),
454
455     // Represents the MIR for a fn; also used as the task node for
456     // things read/modify that MIR.
457     [] MirConstQualif(DefId),
458     [] MirConst(DefId),
459     [] MirValidated(DefId),
460     [] MirOptimized(DefId),
461     [] MirShim { instance_def: InstanceDef<'tcx> },
462
463     [] BorrowCheckKrate,
464     [] BorrowCheck(DefId),
465     [] MirBorrowCheck(DefId),
466     [] UnsafetyViolations(DefId),
467
468     [] Reachability,
469     [] MirKeys,
470     [] CrateVariances,
471
472     // Nodes representing bits of computed IR in the tcx. Each shared
473     // table in the tcx (or elsewhere) maps to one of these
474     // nodes.
475     [] AssociatedItems(DefId),
476     [] TypeOfItem(DefId),
477     [] GenericsOfItem(DefId),
478     [] PredicatesOfItem(DefId),
479     [] InferredOutlivesOf(DefId),
480     [] SuperPredicatesOfItem(DefId),
481     [] TraitDefOfItem(DefId),
482     [] AdtDefOfItem(DefId),
483     [] IsDefaultImpl(DefId),
484     [] ImplTraitRef(DefId),
485     [] ImplPolarity(DefId),
486     [] ClosureKind(DefId),
487     [] FnSignature(DefId),
488     [] GenSignature(DefId),
489     [] CoerceUnsizedInfo(DefId),
490
491     [] ItemVarianceConstraints(DefId),
492     [] ItemVariances(DefId),
493     [] IsConstFn(DefId),
494     [] IsForeignItem(DefId),
495     [] TypeParamPredicates { item_id: DefId, param_id: DefId },
496     [] SizedConstraint(DefId),
497     [] DtorckConstraint(DefId),
498     [] AdtDestructor(DefId),
499     [] AssociatedItemDefIds(DefId),
500     [] InherentImpls(DefId),
501     [] TypeckBodiesKrate,
502     [] TypeckTables(DefId),
503     [] UsedTraitImports(DefId),
504     [] HasTypeckTables(DefId),
505     [] ConstEval { param_env: ParamEnvAnd<'tcx, (DefId, &'tcx Substs<'tcx>)> },
506     [] SymbolName(DefId),
507     [] InstanceSymbolName { instance: Instance<'tcx> },
508     [] SpecializationGraph(DefId),
509     [] ObjectSafety(DefId),
510     [] FulfillObligation { param_env: ParamEnv<'tcx>, trait_ref: PolyTraitRef<'tcx> },
511     [] VtableMethods { trait_ref: PolyTraitRef<'tcx> },
512
513     [] IsCopy { param_env: ParamEnvAnd<'tcx, Ty<'tcx>> },
514     [] IsSized { param_env: ParamEnvAnd<'tcx, Ty<'tcx>> },
515     [] IsFreeze { param_env: ParamEnvAnd<'tcx, Ty<'tcx>> },
516     [] NeedsDrop { param_env: ParamEnvAnd<'tcx, Ty<'tcx>> },
517     [] Layout { param_env: ParamEnvAnd<'tcx, Ty<'tcx>> },
518
519     // The set of impls for a given trait.
520     [] TraitImpls(DefId),
521
522     [] AllLocalTraitImpls,
523
524     // Trait selection cache is a little funny. Given a trait
525     // reference like `Foo: SomeTrait<Bar>`, there could be
526     // arbitrarily many def-ids to map on in there (e.g., `Foo`,
527     // `SomeTrait`, `Bar`). We could have a vector of them, but it
528     // requires heap-allocation, and trait sel in general can be a
529     // surprisingly hot path. So instead we pick two def-ids: the
530     // trait def-id, and the first def-id in the input types. If there
531     // is no def-id in the input types, then we use the trait def-id
532     // again. So for example:
533     //
534     // - `i32: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Clone }`
535     // - `u32: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Clone }`
536     // - `Clone: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Clone }`
537     // - `Vec<i32>: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Vec }`
538     // - `String: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: String }`
539     // - `Foo: Trait<Bar>` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
540     // - `Foo: Trait<i32>` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
541     // - `(Foo, Bar): Trait` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
542     // - `i32: Trait<Foo>` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
543     //
544     // You can see that we map many trait refs to the same
545     // trait-select node.  This is not a problem, it just means
546     // imprecision in our dep-graph tracking.  The important thing is
547     // that for any given trait-ref, we always map to the **same**
548     // trait-select node.
549     [anon] TraitSelect,
550
551     [] ParamEnv(DefId),
552     [] DescribeDef(DefId),
553     [] DefSpan(DefId),
554     [] LookupStability(DefId),
555     [] LookupDeprecationEntry(DefId),
556     [] ItemBodyNestedBodies(DefId),
557     [] ConstIsRvaluePromotableToStatic(DefId),
558     [] RvaluePromotableMap(DefId),
559     [] ImplParent(DefId),
560     [] TraitOfItem(DefId),
561     [] IsExportedSymbol(DefId),
562     [] IsMirAvailable(DefId),
563     [] ItemAttrs(DefId),
564     [] FnArgNames(DefId),
565     [] DylibDepFormats(CrateNum),
566     [] IsPanicRuntime(CrateNum),
567     [] IsCompilerBuiltins(CrateNum),
568     [] HasGlobalAllocator(CrateNum),
569     [] ExternCrate(DefId),
570     [] LintLevels,
571     [] Specializes { impl1: DefId, impl2: DefId },
572     [input] InScopeTraits(DefIndex),
573     [] ModuleExports(DefId),
574     [] IsSanitizerRuntime(CrateNum),
575     [] IsProfilerRuntime(CrateNum),
576     [] GetPanicStrategy(CrateNum),
577     [] IsNoBuiltins(CrateNum),
578     [] ImplDefaultness(DefId),
579     [] ExportedSymbolIds(CrateNum),
580     [] NativeLibraries(CrateNum),
581     [] PluginRegistrarFn(CrateNum),
582     [] DeriveRegistrarFn(CrateNum),
583     [] CrateDisambiguator(CrateNum),
584     [] CrateHash(CrateNum),
585     [] OriginalCrateName(CrateNum),
586
587     [] ImplementationsOfTrait { krate: CrateNum, trait_id: DefId },
588     [] AllTraitImplementations(CrateNum),
589
590     [] IsDllimportForeignItem(DefId),
591     [] IsStaticallyIncludedForeignItem(DefId),
592     [] NativeLibraryKind(DefId),
593     [] LinkArgs,
594
595     [] NamedRegion(DefIndex),
596     [] IsLateBound(DefIndex),
597     [] ObjectLifetimeDefaults(DefIndex),
598
599     [] Visibility(DefId),
600     [] DepKind(CrateNum),
601     [] CrateName(CrateNum),
602     [] ItemChildren(DefId),
603     [] ExternModStmtCnum(DefId),
604     [] GetLangItems,
605     [] DefinedLangItems(CrateNum),
606     [] MissingLangItems(CrateNum),
607     [] ExternConstBody(DefId),
608     [] VisibleParentMap,
609     [] MissingExternCrateItem(CrateNum),
610     [] UsedCrateSource(CrateNum),
611     [] PostorderCnums,
612     [] HasCloneClosures(CrateNum),
613     [] HasCopyClosures(CrateNum),
614
615     // This query is not expected to have inputs -- as a result, it's
616     // not a good candidate for "replay" because it's essentially a
617     // pure function of its input (and hence the expectation is that
618     // no caller would be green **apart** from just this
619     // query). Making it anonymous avoids hashing the result, which
620     // may save a bit of time.
621     [anon] EraseRegionsTy { ty: Ty<'tcx> },
622
623     [] Freevars(DefId),
624     [] MaybeUnusedTraitImport(DefId),
625     [] MaybeUnusedExternCrates,
626     [] StabilityIndex,
627     [] AllCrateNums,
628     [] ExportedSymbols(CrateNum),
629     [] CollectAndPartitionTranslationItems,
630     [] ExportName(DefId),
631     [] ContainsExternIndicator(DefId),
632     [] IsTranslatedFunction(DefId),
633     [] CodegenUnit(InternedString),
634     [] CompileCodegenUnit(InternedString),
635     [] OutputFilenames,
636     [anon] NormalizeTy,
637     // We use this for most things when incr. comp. is turned off.
638     [] Null,
639 );
640
641 trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
642     const CAN_RECONSTRUCT_QUERY_KEY: bool;
643
644     /// This method turns the parameters of a DepNodeConstructor into an opaque
645     /// Fingerprint to be used in DepNode.
646     /// Not all DepNodeParams support being turned into a Fingerprint (they
647     /// don't need to if the corresponding DepNode is anonymous).
648     fn to_fingerprint(&self, _: TyCtxt<'a, 'gcx, 'tcx>) -> Fingerprint {
649         panic!("Not implemented. Accidentally called on anonymous node?")
650     }
651
652     fn to_debug_str(&self, _: TyCtxt<'a, 'gcx, 'tcx>) -> String {
653         format!("{:?}", self)
654     }
655 }
656
657 impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a, T> DepNodeParams<'a, 'gcx, 'tcx> for T
658     where T: HashStable<StableHashingContext<'gcx>> + fmt::Debug
659 {
660     default const CAN_RECONSTRUCT_QUERY_KEY: bool = false;
661
662     default fn to_fingerprint(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Fingerprint {
663         let mut hcx = tcx.create_stable_hashing_context();
664         let mut hasher = StableHasher::new();
665
666         self.hash_stable(&mut hcx, &mut hasher);
667
668         hasher.finish()
669     }
670
671     default fn to_debug_str(&self, _: TyCtxt<'a, 'gcx, 'tcx>) -> String {
672         format!("{:?}", *self)
673     }
674 }
675
676 impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefId,) {
677     const CAN_RECONSTRUCT_QUERY_KEY: bool = true;
678
679     fn to_fingerprint(&self, tcx: TyCtxt) -> Fingerprint {
680         tcx.def_path_hash(self.0).0
681     }
682
683     fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String {
684         tcx.item_path_str(self.0)
685     }
686 }
687
688 impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefIndex,) {
689     const CAN_RECONSTRUCT_QUERY_KEY: bool = true;
690
691     fn to_fingerprint(&self, tcx: TyCtxt) -> Fingerprint {
692         tcx.hir.definitions().def_path_hash(self.0).0
693     }
694
695     fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String {
696         tcx.item_path_str(DefId::local(self.0))
697     }
698 }
699
700 impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (CrateNum,) {
701     const CAN_RECONSTRUCT_QUERY_KEY: bool = true;
702
703     fn to_fingerprint(&self, tcx: TyCtxt) -> Fingerprint {
704         let def_id = DefId {
705             krate: self.0,
706             index: CRATE_DEF_INDEX,
707         };
708         tcx.def_path_hash(def_id).0
709     }
710
711     fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String {
712         tcx.crate_name(self.0).as_str().to_string()
713     }
714 }
715
716 impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefId, DefId) {
717     const CAN_RECONSTRUCT_QUERY_KEY: bool = false;
718
719     // We actually would not need to specialize the implementation of this
720     // method but it's faster to combine the hashes than to instantiate a full
721     // hashing context and stable-hashing state.
722     fn to_fingerprint(&self, tcx: TyCtxt) -> Fingerprint {
723         let (def_id_0, def_id_1) = *self;
724
725         let def_path_hash_0 = tcx.def_path_hash(def_id_0);
726         let def_path_hash_1 = tcx.def_path_hash(def_id_1);
727
728         def_path_hash_0.0.combine(def_path_hash_1.0)
729     }
730
731     fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String {
732         let (def_id_0, def_id_1) = *self;
733
734         format!("({}, {})",
735                 tcx.def_path_debug_str(def_id_0),
736                 tcx.def_path_debug_str(def_id_1))
737     }
738 }
739
740 impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (HirId,) {
741     const CAN_RECONSTRUCT_QUERY_KEY: bool = false;
742
743     // We actually would not need to specialize the implementation of this
744     // method but it's faster to combine the hashes than to instantiate a full
745     // hashing context and stable-hashing state.
746     fn to_fingerprint(&self, tcx: TyCtxt) -> Fingerprint {
747         let (HirId {
748             owner,
749             local_id: ItemLocalId(local_id),
750         },) = *self;
751
752         let def_path_hash = tcx.def_path_hash(DefId::local(owner));
753         let local_id = Fingerprint::from_smaller_hash(local_id as u64);
754
755         def_path_hash.0.combine(local_id)
756     }
757 }
758
759 /// A "work product" corresponds to a `.o` (or other) file that we
760 /// save in between runs. These ids do not have a DefId but rather
761 /// some independent path or string that persists between runs without
762 /// the need to be mapped or unmapped. (This ensures we can serialize
763 /// them even in the absence of a tcx.)
764 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash,
765          RustcEncodable, RustcDecodable)]
766 pub struct WorkProductId {
767     hash: Fingerprint
768 }
769
770 impl WorkProductId {
771     pub fn from_cgu_name(cgu_name: &str) -> WorkProductId {
772         let mut hasher = StableHasher::new();
773         cgu_name.len().hash(&mut hasher);
774         cgu_name.hash(&mut hasher);
775         WorkProductId {
776             hash: hasher.finish()
777         }
778     }
779
780     pub fn from_fingerprint(fingerprint: Fingerprint) -> WorkProductId {
781         WorkProductId {
782             hash: fingerprint
783         }
784     }
785
786     pub fn to_dep_node(self) -> DepNode {
787         DepNode {
788             kind: DepKind::WorkProduct,
789             hash: self.hash,
790         }
791     }
792 }
793
794 impl_stable_hash_for!(struct ::dep_graph::WorkProductId {
795     hash
796 });
797