]> git.lizzy.rs Git - rust.git/blob - src/librustc/dep_graph/dep_node.rs
rustc(codegen): uncache `def_symbol_name` prefix from `symbol_name`.
[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 { instance: Instance<'tcx> },
504     [] SpecializationGraph(DefId),
505     [] ObjectSafety(DefId),
506     [] FulfillObligation { param_env: ParamEnv<'tcx>, trait_ref: PolyTraitRef<'tcx> },
507     [] VtableMethods { trait_ref: PolyTraitRef<'tcx> },
508
509     [] IsCopy { param_env: ParamEnvAnd<'tcx, Ty<'tcx>> },
510     [] IsSized { param_env: ParamEnvAnd<'tcx, Ty<'tcx>> },
511     [] IsFreeze { param_env: ParamEnvAnd<'tcx, Ty<'tcx>> },
512     [] NeedsDrop { param_env: ParamEnvAnd<'tcx, Ty<'tcx>> },
513     [] Layout { param_env: ParamEnvAnd<'tcx, Ty<'tcx>> },
514
515     // The set of impls for a given trait.
516     [] TraitImpls(DefId),
517
518     [eval_always] AllLocalTraitImpls,
519
520     [anon] TraitSelect,
521
522     [] ParamEnv(DefId),
523     [] DescribeDef(DefId),
524
525     // FIXME(mw): DefSpans are not really inputs since they are derived from
526     // HIR. But at the moment HIR hashing still contains some hacks that allow
527     // to make type debuginfo to be source location independent. Declaring
528     // DefSpan an input makes sure that changes to these are always detected
529     // regardless of HIR hashing.
530     [eval_always] DefSpan(DefId),
531     [] LookupStability(DefId),
532     [] LookupDeprecationEntry(DefId),
533     [] ConstIsRvaluePromotableToStatic(DefId),
534     [] RvaluePromotableMap(DefId),
535     [] ImplParent(DefId),
536     [] TraitOfItem(DefId),
537     [] IsReachableNonGeneric(DefId),
538     [] IsUnreachableLocalDefinition(DefId),
539     [] IsMirAvailable(DefId),
540     [] ItemAttrs(DefId),
541     [] CodegenFnAttrs(DefId),
542     [] FnArgNames(DefId),
543     [] RenderedConst(DefId),
544     [] DylibDepFormats(CrateNum),
545     [] IsCompilerBuiltins(CrateNum),
546     [] HasGlobalAllocator(CrateNum),
547     [] HasPanicHandler(CrateNum),
548     [eval_always] ExternCrate(DefId),
549     [] Specializes { impl1: DefId, impl2: DefId },
550     [eval_always] InScopeTraits(DefIndex),
551     [eval_always] ModuleExports(DefId),
552     [] IsSanitizerRuntime(CrateNum),
553     [] IsProfilerRuntime(CrateNum),
554     [] GetPanicStrategy(CrateNum),
555     [] IsNoBuiltins(CrateNum),
556     [] ImplDefaultness(DefId),
557     [] CheckItemWellFormed(DefId),
558     [] CheckTraitItemWellFormed(DefId),
559     [] CheckImplItemWellFormed(DefId),
560     [] ReachableNonGenerics(CrateNum),
561     [] EntryFn(CrateNum),
562     [] PluginRegistrarFn(CrateNum),
563     [] ProcMacroDeclsStatic(CrateNum),
564     [eval_always] CrateDisambiguator(CrateNum),
565     [eval_always] CrateHash(CrateNum),
566     [eval_always] OriginalCrateName(CrateNum),
567     [eval_always] ExtraFileName(CrateNum),
568
569     [] ImplementationsOfTrait { krate: CrateNum, trait_id: DefId },
570     [] AllTraitImplementations(CrateNum),
571
572     [] DllimportForeignItems(CrateNum),
573     [] IsDllimportForeignItem(DefId),
574     [] IsStaticallyIncludedForeignItem(DefId),
575     [] NativeLibraryKind(DefId),
576     [eval_always] LinkArgs,
577
578     [] ResolveLifetimes(CrateNum),
579     [] NamedRegion(DefIndex),
580     [] IsLateBound(DefIndex),
581     [] ObjectLifetimeDefaults(DefIndex),
582
583     [] Visibility(DefId),
584     [eval_always] DepKind(CrateNum),
585     [eval_always] CrateName(CrateNum),
586     [] ItemChildren(DefId),
587     [] ExternModStmtCnum(DefId),
588     [eval_always] GetLibFeatures,
589     [] DefinedLibFeatures(CrateNum),
590     [eval_always] GetLangItems,
591     [] DefinedLangItems(CrateNum),
592     [] MissingLangItems(CrateNum),
593     [] VisibleParentMap,
594     [eval_always] MissingExternCrateItem(CrateNum),
595     [eval_always] UsedCrateSource(CrateNum),
596     [eval_always] PostorderCnums,
597
598     [eval_always] Freevars(DefId),
599     [eval_always] MaybeUnusedTraitImport(DefId),
600     [eval_always] MaybeUnusedExternCrates,
601     [eval_always] NamesImportedByGlobUse(DefId),
602     [eval_always] StabilityIndex,
603     [eval_always] AllTraits,
604     [eval_always] AllCrateNums,
605     [] ExportedSymbols(CrateNum),
606     [eval_always] CollectAndPartitionMonoItems,
607     [] IsCodegenedItem(DefId),
608     [] CodegenUnit(InternedString),
609     [] BackendOptimizationLevel(CrateNum),
610     [] CompileCodegenUnit(InternedString),
611     [eval_always] OutputFilenames,
612     [] NormalizeProjectionTy(CanonicalProjectionGoal<'tcx>),
613     [] NormalizeTyAfterErasingRegions(ParamEnvAnd<'tcx, Ty<'tcx>>),
614     [] ImpliedOutlivesBounds(CanonicalTyGoal<'tcx>),
615     [] DropckOutlives(CanonicalTyGoal<'tcx>),
616     [] EvaluateObligation(CanonicalPredicateGoal<'tcx>),
617     [] EvaluateGoal(traits::ChalkCanonicalGoal<'tcx>),
618     [] TypeOpAscribeUserType(CanonicalTypeOpAscribeUserTypeGoal<'tcx>),
619     [] TypeOpEq(CanonicalTypeOpEqGoal<'tcx>),
620     [] TypeOpSubtype(CanonicalTypeOpSubtypeGoal<'tcx>),
621     [] TypeOpProvePredicate(CanonicalTypeOpProvePredicateGoal<'tcx>),
622     [] TypeOpNormalizeTy(CanonicalTypeOpNormalizeGoal<'tcx, Ty<'tcx>>),
623     [] TypeOpNormalizePredicate(CanonicalTypeOpNormalizeGoal<'tcx, Predicate<'tcx>>),
624     [] TypeOpNormalizePolyFnSig(CanonicalTypeOpNormalizeGoal<'tcx, PolyFnSig<'tcx>>),
625     [] TypeOpNormalizeFnSig(CanonicalTypeOpNormalizeGoal<'tcx, FnSig<'tcx>>),
626
627     [] SubstituteNormalizeAndTestPredicates { key: (DefId, SubstsRef<'tcx>) },
628     [] MethodAutoderefSteps(CanonicalTyGoal<'tcx>),
629
630     [eval_always] TargetFeaturesWhitelist,
631
632     [] InstanceDefSizeEstimate { instance_def: InstanceDef<'tcx> },
633
634     [eval_always] Features,
635
636     [] ForeignModules(CrateNum),
637
638     [] UpstreamMonomorphizations(CrateNum),
639     [] UpstreamMonomorphizationsFor(DefId),
640 ]);
641
642 pub trait RecoverKey<'tcx>: Sized {
643     fn recover(tcx: TyCtxt<'_, 'tcx, 'tcx>, dep_node: &DepNode) -> Option<Self>;
644 }
645
646 impl RecoverKey<'tcx> for CrateNum {
647     fn recover(tcx: TyCtxt<'_, 'tcx, 'tcx>, dep_node: &DepNode) -> Option<Self> {
648         dep_node.extract_def_id(tcx).map(|id| id.krate)
649     }
650 }
651
652 impl RecoverKey<'tcx> for DefId {
653     fn recover(tcx: TyCtxt<'_, 'tcx, 'tcx>, dep_node: &DepNode) -> Option<Self> {
654         dep_node.extract_def_id(tcx)
655     }
656 }
657
658 trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
659     const CAN_RECONSTRUCT_QUERY_KEY: bool;
660
661     /// This method turns the parameters of a DepNodeConstructor into an opaque
662     /// Fingerprint to be used in DepNode.
663     /// Not all DepNodeParams support being turned into a Fingerprint (they
664     /// don't need to if the corresponding DepNode is anonymous).
665     fn to_fingerprint(&self, _: TyCtxt<'a, 'gcx, 'tcx>) -> Fingerprint {
666         panic!("Not implemented. Accidentally called on anonymous node?")
667     }
668
669     fn to_debug_str(&self, _: TyCtxt<'a, 'gcx, 'tcx>) -> String {
670         format!("{:?}", self)
671     }
672 }
673
674 impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a, T> DepNodeParams<'a, 'gcx, 'tcx> for T
675     where T: HashStable<StableHashingContext<'a>> + fmt::Debug
676 {
677     default const CAN_RECONSTRUCT_QUERY_KEY: bool = false;
678
679     default fn to_fingerprint(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Fingerprint {
680         let mut hcx = tcx.create_stable_hashing_context();
681         let mut hasher = StableHasher::new();
682
683         self.hash_stable(&mut hcx, &mut hasher);
684
685         hasher.finish()
686     }
687
688     default fn to_debug_str(&self, _: TyCtxt<'a, 'gcx, 'tcx>) -> String {
689         format!("{:?}", *self)
690     }
691 }
692
693 impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for DefId {
694     const CAN_RECONSTRUCT_QUERY_KEY: bool = true;
695
696     fn to_fingerprint(&self, tcx: TyCtxt<'_, '_, '_>) -> Fingerprint {
697         tcx.def_path_hash(*self).0
698     }
699
700     fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String {
701         tcx.def_path_str(*self)
702     }
703 }
704
705 impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for DefIndex {
706     const CAN_RECONSTRUCT_QUERY_KEY: bool = true;
707
708     fn to_fingerprint(&self, tcx: TyCtxt<'_, '_, '_>) -> Fingerprint {
709         tcx.hir().definitions().def_path_hash(*self).0
710     }
711
712     fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String {
713         tcx.def_path_str(DefId::local(*self))
714     }
715 }
716
717 impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for CrateNum {
718     const CAN_RECONSTRUCT_QUERY_KEY: bool = true;
719
720     fn to_fingerprint(&self, tcx: TyCtxt<'_, '_, '_>) -> Fingerprint {
721         let def_id = DefId {
722             krate: *self,
723             index: CRATE_DEF_INDEX,
724         };
725         tcx.def_path_hash(def_id).0
726     }
727
728     fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String {
729         tcx.crate_name(*self).as_str().to_string()
730     }
731 }
732
733 impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefId, DefId) {
734     const CAN_RECONSTRUCT_QUERY_KEY: bool = false;
735
736     // We actually would not need to specialize the implementation of this
737     // method but it's faster to combine the hashes than to instantiate a full
738     // hashing context and stable-hashing state.
739     fn to_fingerprint(&self, tcx: TyCtxt<'_, '_, '_>) -> Fingerprint {
740         let (def_id_0, def_id_1) = *self;
741
742         let def_path_hash_0 = tcx.def_path_hash(def_id_0);
743         let def_path_hash_1 = tcx.def_path_hash(def_id_1);
744
745         def_path_hash_0.0.combine(def_path_hash_1.0)
746     }
747
748     fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String {
749         let (def_id_0, def_id_1) = *self;
750
751         format!("({}, {})",
752                 tcx.def_path_debug_str(def_id_0),
753                 tcx.def_path_debug_str(def_id_1))
754     }
755 }
756
757 impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for HirId {
758     const CAN_RECONSTRUCT_QUERY_KEY: bool = false;
759
760     // We actually would not need to specialize the implementation of this
761     // method but it's faster to combine the hashes than to instantiate a full
762     // hashing context and stable-hashing state.
763     fn to_fingerprint(&self, tcx: TyCtxt<'_, '_, '_>) -> Fingerprint {
764         let HirId {
765             owner,
766             local_id,
767         } = *self;
768
769         let def_path_hash = tcx.def_path_hash(DefId::local(owner));
770         let local_id = Fingerprint::from_smaller_hash(local_id.as_u32().into());
771
772         def_path_hash.0.combine(local_id)
773     }
774 }
775
776 /// A "work product" corresponds to a `.o` (or other) file that we
777 /// save in between runs. These IDs do not have a `DefId` but rather
778 /// some independent path or string that persists between runs without
779 /// the need to be mapped or unmapped. (This ensures we can serialize
780 /// them even in the absence of a tcx.)
781 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash,
782          RustcEncodable, RustcDecodable)]
783 pub struct WorkProductId {
784     hash: Fingerprint
785 }
786
787 impl WorkProductId {
788     pub fn from_cgu_name(cgu_name: &str) -> WorkProductId {
789         let mut hasher = StableHasher::new();
790         cgu_name.len().hash(&mut hasher);
791         cgu_name.hash(&mut hasher);
792         WorkProductId {
793             hash: hasher.finish()
794         }
795     }
796
797     pub fn from_fingerprint(fingerprint: Fingerprint) -> WorkProductId {
798         WorkProductId {
799             hash: fingerprint
800         }
801     }
802 }
803
804 impl_stable_hash_for!(struct crate::dep_graph::WorkProductId {
805     hash
806 });