]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_query_system/src/dep_graph/mod.rs
Rollup merge of #102281 - RalfJung:invalid-enums, r=cjgillot
[rust.git] / compiler / rustc_query_system / src / dep_graph / mod.rs
1 pub mod debug;
2 mod dep_node;
3 mod graph;
4 mod query;
5 mod serialized;
6
7 pub use dep_node::{DepKindStruct, DepNode, DepNodeParams, WorkProductId};
8 pub use graph::{
9     hash_result, DepGraph, DepNodeColor, DepNodeIndex, TaskDeps, TaskDepsRef, WorkProduct,
10 };
11 pub use query::DepGraphQuery;
12 pub use serialized::{SerializedDepGraph, SerializedDepNodeIndex};
13
14 use crate::ich::StableHashingContext;
15 use rustc_data_structures::profiling::SelfProfilerRef;
16 use rustc_serialize::{opaque::FileEncoder, Encodable};
17 use rustc_session::Session;
18
19 use std::fmt;
20 use std::hash::Hash;
21
22 pub trait DepContext: Copy {
23     type DepKind: self::DepKind;
24
25     /// Create a hashing context for hashing new results.
26     fn with_stable_hashing_context<R>(&self, f: impl FnOnce(StableHashingContext<'_>) -> R) -> R;
27
28     /// Access the DepGraph.
29     fn dep_graph(&self) -> &DepGraph<Self::DepKind>;
30
31     /// Access the profiler.
32     fn profiler(&self) -> &SelfProfilerRef;
33
34     /// Access the compiler session.
35     fn sess(&self) -> &Session;
36
37     fn dep_kind_info(&self, dep_node: Self::DepKind) -> &DepKindStruct<Self>;
38
39     #[inline(always)]
40     fn fingerprint_style(&self, kind: Self::DepKind) -> FingerprintStyle {
41         let data = self.dep_kind_info(kind);
42         if data.is_anon {
43             return FingerprintStyle::Opaque;
44         }
45         data.fingerprint_style
46     }
47
48     #[inline(always)]
49     /// Return whether this kind always require evaluation.
50     fn is_eval_always(&self, kind: Self::DepKind) -> bool {
51         self.dep_kind_info(kind).is_eval_always
52     }
53
54     /// Try to force a dep node to execute and see if it's green.
55     fn try_force_from_dep_node(self, dep_node: DepNode<Self::DepKind>) -> bool {
56         debug!("try_force_from_dep_node({:?}) --- trying to force", dep_node);
57
58         let cb = self.dep_kind_info(dep_node.kind);
59         if let Some(f) = cb.force_from_dep_node {
60             f(self, dep_node);
61             true
62         } else {
63             false
64         }
65     }
66
67     /// Load data from the on-disk cache.
68     fn try_load_from_on_disk_cache(self, dep_node: DepNode<Self::DepKind>) {
69         let cb = self.dep_kind_info(dep_node.kind);
70         if let Some(f) = cb.try_load_from_on_disk_cache {
71             f(self, dep_node)
72         }
73     }
74 }
75
76 pub trait HasDepContext: Copy {
77     type DepKind: self::DepKind;
78     type DepContext: self::DepContext<DepKind = Self::DepKind>;
79
80     fn dep_context(&self) -> &Self::DepContext;
81 }
82
83 impl<T: DepContext> HasDepContext for T {
84     type DepKind = T::DepKind;
85     type DepContext = Self;
86
87     fn dep_context(&self) -> &Self::DepContext {
88         self
89     }
90 }
91
92 /// Describes the contents of the fingerprint generated by a given query.
93 #[derive(Debug, PartialEq, Eq, Copy, Clone)]
94 pub enum FingerprintStyle {
95     /// The fingerprint is actually a DefPathHash.
96     DefPathHash,
97     /// Query key was `()` or equivalent, so fingerprint is just zero.
98     Unit,
99     /// Some opaque hash.
100     Opaque,
101 }
102
103 impl FingerprintStyle {
104     #[inline]
105     pub fn reconstructible(self) -> bool {
106         match self {
107             FingerprintStyle::DefPathHash | FingerprintStyle::Unit => true,
108             FingerprintStyle::Opaque => false,
109         }
110     }
111 }
112
113 /// Describe the different families of dependency nodes.
114 pub trait DepKind: Copy + fmt::Debug + Eq + Hash + Send + Encodable<FileEncoder> + 'static {
115     /// DepKind to use when incr. comp. is turned off.
116     const NULL: Self;
117
118     /// DepKind to use to create the initial forever-red node.
119     const RED: Self;
120
121     /// Implementation of `std::fmt::Debug` for `DepNode`.
122     fn debug_node(node: &DepNode<Self>, f: &mut fmt::Formatter<'_>) -> fmt::Result;
123
124     /// Execute the operation with provided dependencies.
125     fn with_deps<OP, R>(deps: TaskDepsRef<'_, Self>, op: OP) -> R
126     where
127         OP: FnOnce() -> R;
128
129     /// Access dependencies from current implicit context.
130     fn read_deps<OP>(op: OP)
131     where
132         OP: for<'a> FnOnce(TaskDepsRef<'a, Self>);
133 }