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