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.
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.
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:
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
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.
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.
45 //! Because the macro sees what parameters a given `DepKind` requires, it can
46 //! "infer" some properties for each kind of `DepNode`:
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.
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.
63 use hir::def_id::{CrateNum, DefId};
64 use hir::map::DefPathHash;
68 use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
69 use ich::StableHashingContext;
73 // erase!() just makes tokens go away. It's used to specify which macro argument
74 // is repeated (i.e. which sub-expression of the macro we are in) but don't need
75 // to actually use any of the arguments.
80 macro_rules! define_dep_nodes {
82 $variant:ident $(( $($tuple_arg:tt),* ))*
83 $({ $($struct_arg_name:ident : $struct_arg_ty:ty),* })*
86 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash,
87 RustcEncodable, RustcDecodable)]
93 #[allow(unreachable_code)]
95 pub fn can_reconstruct_query_key(&self) -> bool {
98 DepKind :: $variant => {
101 return <( $($tuple_arg,)* ) as DepNodeParams>
102 ::CAN_RECONSTRUCT_QUERY_KEY;
107 return <( $($struct_arg_ty,)* ) as DepNodeParams>
108 ::CAN_RECONSTRUCT_QUERY_KEY;
117 #[allow(unreachable_code)]
119 pub fn has_params(&self) -> bool {
122 DepKind :: $variant => {
125 $(erase!($tuple_arg);)*
131 $(erase!($struct_arg_name);)*
142 pub enum DepConstructor {
144 $variant $(( $($tuple_arg),* ))*
145 $({ $($struct_arg_name : $struct_arg_ty),* })*
149 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash,
150 RustcEncodable, RustcDecodable)]
153 pub hash: Fingerprint,
157 #[allow(unreachable_code, non_snake_case)]
158 pub fn new(tcx: TyCtxt, dep: DepConstructor) -> DepNode {
161 DepConstructor :: $variant $(( $($tuple_arg),* ))*
162 $({ $($struct_arg_name),* })*
167 let tupled_args = ( $($tuple_arg,)* );
168 let hash = DepNodeParams::to_fingerprint(&tupled_args,
170 let dep_node = DepNode {
171 kind: DepKind::$variant,
175 if cfg!(debug_assertions) &&
176 !dep_node.kind.can_reconstruct_query_key() &&
177 (tcx.sess.opts.debugging_opts.incremental_info ||
178 tcx.sess.opts.debugging_opts.query_dep_graph)
180 tcx.dep_graph.register_dep_node_debug_str(dep_node, || {
181 tupled_args.to_debug_str(tcx)
190 let tupled_args = ( $($struct_arg_name,)* );
191 let hash = DepNodeParams::to_fingerprint(&tupled_args,
193 let dep_node = DepNode {
194 kind: DepKind::$variant,
198 if cfg!(debug_assertions) &&
199 !dep_node.kind.can_reconstruct_query_key() &&
200 (tcx.sess.opts.debugging_opts.incremental_info ||
201 tcx.sess.opts.debugging_opts.query_dep_graph)
203 tcx.dep_graph.register_dep_node_debug_str(dep_node, || {
204 tupled_args.to_debug_str(tcx)
212 kind: DepKind::$variant,
213 hash: Fingerprint::zero(),
220 /// Construct a DepNode from the given DepKind and DefPathHash. This
221 /// method will assert that the given DepKind actually requires a
222 /// single DefId/DefPathHash parameter.
224 pub fn from_def_path_hash(kind: DepKind,
225 def_path_hash: DefPathHash)
227 assert!(kind.can_reconstruct_query_key() && kind.has_params());
230 hash: def_path_hash.0,
234 /// Create a new, parameterless DepNode. This method will assert
235 /// that the DepNode corresponding to the given DepKind actually
236 /// does not require any parameters.
238 pub fn new_no_params(kind: DepKind) -> DepNode {
239 assert!(!kind.has_params());
242 hash: Fingerprint::zero(),
246 /// Extract the DefId corresponding to this DepNode. This will work
247 /// if two conditions are met:
249 /// 1. The Fingerprint of the DepNode actually is a DefPathHash, and
250 /// 2. the item that the DefPath refers to exists in the current tcx.
252 /// Condition (1) is determined by the DepKind variant of the
253 /// DepNode. Condition (2) might not be fulfilled if a DepNode
254 /// refers to something from the previous compilation session that
255 /// has been removed.
257 pub fn extract_def_id(&self, tcx: TyCtxt) -> Option<DefId> {
258 if self.kind.can_reconstruct_query_key() {
259 let def_path_hash = DefPathHash(self.hash);
260 if let Some(ref def_path_map) = tcx.def_path_hash_to_def_id.as_ref() {
261 def_path_map.get(&def_path_hash).cloned()
271 pub fn from_label_string(label: &str,
272 def_path_hash: DefPathHash)
273 -> Result<DepNode, ()> {
274 let kind = match label {
276 stringify!($variant) => DepKind::$variant,
281 if !kind.can_reconstruct_query_key() {
285 if kind.has_params() {
286 Ok(def_path_hash.to_dep_node(kind))
288 Ok(DepNode::new_no_params(kind))
295 impl fmt::Debug for DepNode {
296 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
297 write!(f, "{:?}", self.kind)?;
299 if !self.kind.has_params() {
305 ::ty::tls::with_opt(|opt_tcx| {
306 if let Some(tcx) = opt_tcx {
307 if let Some(def_id) = self.extract_def_id(tcx) {
308 write!(f, "{}", tcx.item_path_str(def_id))?;
309 } else if let Some(ref s) = tcx.dep_graph.dep_node_debug_str(*self) {
312 write!(f, "{:?}", self.hash)?;
315 write!(f, "{:?}", self.hash)?;
327 pub fn to_dep_node(self, kind: DepKind) -> DepNode {
328 DepNode::from_def_path_hash(kind, self)
334 pub fn to_dep_node(self, tcx: TyCtxt, kind: DepKind) -> DepNode {
335 DepNode::from_def_path_hash(kind, tcx.def_path_hash(self))
340 // Represents the `Krate` as a whole (the `hir::Krate` value) (as
341 // distinct from the krate module). This is basically a hash of
342 // the entire krate, so if you read from `Krate` (e.g., by calling
343 // `tcx.hir.krate()`), we will have to assume that any change
344 // means that you need to be recompiled. This is because the
345 // `Krate` value gives you access to all other items. To avoid
346 // this fate, do not call `tcx.hir.krate()`; instead, prefer
347 // wrappers like `tcx.visit_all_items_in_krate()`. If there is no
348 // suitable wrapper, you can use `tcx.dep_graph.ignore()` to gain
349 // access to the krate, but you must remember to add suitable
350 // edges yourself for the individual items that you read.
353 // Represents the HIR node with the given node-id
356 // Represents the body of a function or method. The def-id is that of the
360 // Represents the metadata for a given HIR node, typically found
361 // in an extern crate.
364 // Represents some artifact that we save to disk. Note that these
365 // do not have a def-id as part of their identifier.
366 WorkProduct(WorkProductId),
368 // Represents different phases in the compiler.
372 CoherenceCheckTrait(DefId),
373 PrivacyAccessLevels(CrateNum),
375 // Represents the MIR for a fn; also used as the task node for
376 // things read/modify that MIR.
388 // Nodes representing bits of computed IR in the tcx. Each shared
389 // table in the tcx (or elsewhere) maps to one of these
391 AssociatedItems(DefId),
393 GenericsOfItem(DefId),
394 PredicatesOfItem(DefId),
395 SuperPredicatesOfItem(DefId),
396 TraitDefOfItem(DefId),
398 IsDefaultImpl(DefId),
403 CoerceUnsizedInfo(DefId),
405 ItemVarianceConstraints(DefId),
406 ItemVariances(DefId),
408 IsForeignItem(DefId),
409 TypeParamPredicates { item_id: DefId, param_id: DefId },
410 SizedConstraint(DefId),
411 DtorckConstraint(DefId),
412 AdtDestructor(DefId),
413 AssociatedItemDefIds(DefId),
414 InherentImpls(DefId),
419 SpecializationGraph(DefId),
427 // The set of impls for a given trait. Ultimately, it would be
428 // nice to get more fine-grained here (e.g., to include a
429 // simplified type), but we can't do that until we restructure the
430 // HIR to distinguish the *header* of an impl from its body. This
431 // is because changes to the header may change the self-type of
432 // the impl and hence would require us to be more conservative
433 // than changes in the impl body.
438 // Nodes representing caches. To properly handle a true cache, we
439 // don't use a DepTrackingMap, but rather we push a task node.
440 // Otherwise the write into the map would be incorrectly
441 // attributed to the first task that happened to fill the cache,
442 // which would yield an overly conservative dep-graph.
446 // Trait selection cache is a little funny. Given a trait
447 // reference like `Foo: SomeTrait<Bar>`, there could be
448 // arbitrarily many def-ids to map on in there (e.g., `Foo`,
449 // `SomeTrait`, `Bar`). We could have a vector of them, but it
450 // requires heap-allocation, and trait sel in general can be a
451 // surprisingly hot path. So instead we pick two def-ids: the
452 // trait def-id, and the first def-id in the input types. If there
453 // is no def-id in the input types, then we use the trait def-id
454 // again. So for example:
456 // - `i32: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Clone }`
457 // - `u32: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Clone }`
458 // - `Clone: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Clone }`
459 // - `Vec<i32>: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Vec }`
460 // - `String: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: String }`
461 // - `Foo: Trait<Bar>` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
462 // - `Foo: Trait<i32>` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
463 // - `(Foo, Bar): Trait` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
464 // - `i32: Trait<Foo>` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
466 // You can see that we map many trait refs to the same
467 // trait-select node. This is not a problem, it just means
468 // imprecision in our dep-graph tracking. The important thing is
469 // that for any given trait-ref, we always map to the **same**
470 // trait-select node.
471 TraitSelect { trait_def_id: DefId, input_def_id: DefId },
473 // For proj. cache, we just keep a list of all def-ids, since it is
475 ProjectionCache { def_ids: DefIdList },
482 ItemBodyNestedBodies(DefId),
483 ConstIsRvaluePromotableToStatic(DefId),
486 IsExportedSymbol(DefId),
487 IsMirAvailable(DefId),
490 DylibDepFormats(DefId),
492 IsPanicRuntime(DefId),
496 trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> {
497 const CAN_RECONSTRUCT_QUERY_KEY: bool;
498 fn to_fingerprint(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Fingerprint;
499 fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String;
502 impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a, T> DepNodeParams<'a, 'gcx, 'tcx> for T
503 where T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>> + fmt::Debug
505 default const CAN_RECONSTRUCT_QUERY_KEY: bool = false;
507 default fn to_fingerprint(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Fingerprint {
508 let mut hcx = StableHashingContext::new(tcx);
509 let mut hasher = StableHasher::new();
511 self.hash_stable(&mut hcx, &mut hasher);
516 default fn to_debug_str(&self, _: TyCtxt<'a, 'gcx, 'tcx>) -> String {
517 format!("{:?}", *self)
521 impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefId,) {
522 const CAN_RECONSTRUCT_QUERY_KEY: bool = true;
524 fn to_fingerprint(&self, tcx: TyCtxt) -> Fingerprint {
525 tcx.def_path_hash(self.0).0
528 fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String {
529 tcx.item_path_str(self.0)
533 impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefId, DefId) {
534 const CAN_RECONSTRUCT_QUERY_KEY: bool = false;
536 // We actually would not need to specialize the implementation of this
537 // method but it's faster to combine the hashes than to instantiate a full
538 // hashing context and stable-hashing state.
539 fn to_fingerprint(&self, tcx: TyCtxt) -> Fingerprint {
540 let (def_id_0, def_id_1) = *self;
542 let def_path_hash_0 = tcx.def_path_hash(def_id_0);
543 let def_path_hash_1 = tcx.def_path_hash(def_id_1);
545 def_path_hash_0.0.combine(def_path_hash_1.0)
548 fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String {
549 let (def_id_0, def_id_1) = *self;
552 tcx.def_path(def_id_0).to_string(tcx),
553 tcx.def_path(def_id_1).to_string(tcx))
558 impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefIdList,) {
559 const CAN_RECONSTRUCT_QUERY_KEY: bool = false;
561 // We actually would not need to specialize the implementation of this
562 // method but it's faster to combine the hashes than to instantiate a full
563 // hashing context and stable-hashing state.
564 fn to_fingerprint(&self, tcx: TyCtxt) -> Fingerprint {
565 let mut fingerprint = Fingerprint::zero();
567 for &def_id in self.0.iter() {
568 let def_path_hash = tcx.def_path_hash(def_id);
569 fingerprint = fingerprint.combine(def_path_hash.0);
575 fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String {
578 let mut s = String::new();
579 write!(&mut s, "[").unwrap();
581 for &def_id in self.0.iter() {
582 write!(&mut s, "{}", tcx.def_path(def_id).to_string(tcx)).unwrap();
585 write!(&mut s, "]").unwrap();
591 /// A "work product" corresponds to a `.o` (or other) file that we
592 /// save in between runs. These ids do not have a DefId but rather
593 /// some independent path or string that persists between runs without
594 /// the need to be mapped or unmapped. (This ensures we can serialize
595 /// them even in the absence of a tcx.)
596 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash,
597 RustcEncodable, RustcDecodable)]
598 pub struct WorkProductId {
603 pub fn from_cgu_name(cgu_name: &str) -> WorkProductId {
604 let mut hasher = StableHasher::new();
605 cgu_name.len().hash(&mut hasher);
606 cgu_name.hash(&mut hasher);
608 hash: hasher.finish()
612 pub fn from_fingerprint(fingerprint: Fingerprint) -> WorkProductId {
618 pub fn to_dep_node(self) -> DepNode {
620 kind: DepKind::WorkProduct,
626 impl_stable_hash_for!(struct ::dep_graph::WorkProductId {
630 type DefIdList = Vec<DefId>;