]> git.proxmox.com Git - rustc.git/blob - src/librustc/dep_graph/dep_node.rs
df6db366df5b36bd6426bd9acbb65c2f5a52aeaf
[rustc.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 use std::fmt::Debug;
12 use std::sync::Arc;
13
14 macro_rules! try_opt {
15 ($e:expr) => (
16 match $e {
17 Some(r) => r,
18 None => return None,
19 }
20 )
21 }
22
23 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
24 pub enum DepNode<D: Clone + Debug> {
25 // The `D` type is "how definitions are identified".
26 // During compilation, it is always `DefId`, but when serializing
27 // it is mapped to `DefPath`.
28
29 // Represents the `Krate` as a whole (the `hir::Krate` value) (as
30 // distinct from the krate module). This is basically a hash of
31 // the entire krate, so if you read from `Krate` (e.g., by calling
32 // `tcx.hir.krate()`), we will have to assume that any change
33 // means that you need to be recompiled. This is because the
34 // `Krate` value gives you access to all other items. To avoid
35 // this fate, do not call `tcx.hir.krate()`; instead, prefer
36 // wrappers like `tcx.visit_all_items_in_krate()`. If there is no
37 // suitable wrapper, you can use `tcx.dep_graph.ignore()` to gain
38 // access to the krate, but you must remember to add suitable
39 // edges yourself for the individual items that you read.
40 Krate,
41
42 // Represents the HIR node with the given node-id
43 Hir(D),
44
45 // Represents the body of a function or method. The def-id is that of the
46 // function/method.
47 HirBody(D),
48
49 // Represents the metadata for a given HIR node, typically found
50 // in an extern crate.
51 MetaData(D),
52
53 // Represents some artifact that we save to disk. Note that these
54 // do not have a def-id as part of their identifier.
55 WorkProduct(Arc<WorkProductId>),
56
57 // Represents different phases in the compiler.
58 CollectLanguageItems,
59 CheckStaticRecursion,
60 ResolveLifetimes,
61 RegionResolveCrate,
62 CheckLoops,
63 PluginRegistrar,
64 StabilityIndex,
65 CollectItem(D),
66 CollectItemSig(D),
67 Coherence,
68 EffectCheck,
69 Liveness,
70 Resolve,
71 EntryPoint,
72 CheckEntryFn,
73 CoherenceCheckImpl(D),
74 CoherenceOverlapCheck(D),
75 CoherenceOverlapCheckSpecial(D),
76 CoherenceOverlapInherentCheck(D),
77 CoherenceOrphanCheck(D),
78 Variance,
79 WfCheck(D),
80 TypeckItemType(D),
81 Dropck,
82 DropckImpl(D),
83 UnusedTraitCheck,
84 CheckConst(D),
85 Privacy,
86 IntrinsicCheck(D),
87 MatchCheck(D),
88
89 // Represents the MIR for a fn; also used as the task node for
90 // things read/modify that MIR.
91 Mir(D),
92
93 BorrowCheck(D),
94 RvalueCheck(D),
95 Reachability,
96 DeadCheck,
97 StabilityCheck(D),
98 LateLintCheck,
99 TransCrate,
100 TransCrateItem(D),
101 TransInlinedItem(D),
102 TransWriteMetadata,
103 LinkBinary,
104
105 // Nodes representing bits of computed IR in the tcx. Each shared
106 // table in the tcx (or elsewhere) maps to one of these
107 // nodes. Often we map multiple tables to the same node if there
108 // is no point in distinguishing them (e.g., both the type and
109 // predicates for an item wind up in `ItemSignature`).
110 AssociatedItems(D),
111 ItemSignature(D),
112 SizedConstraint(D),
113 AssociatedItemDefIds(D),
114 InherentImpls(D),
115 TypeckTables(D),
116
117 // The set of impls for a given trait. Ultimately, it would be
118 // nice to get more fine-grained here (e.g., to include a
119 // simplified type), but we can't do that until we restructure the
120 // HIR to distinguish the *header* of an impl from its body. This
121 // is because changes to the header may change the self-type of
122 // the impl and hence would require us to be more conservative
123 // than changes in the impl body.
124 TraitImpls(D),
125
126 // Nodes representing caches. To properly handle a true cache, we
127 // don't use a DepTrackingMap, but rather we push a task node.
128 // Otherwise the write into the map would be incorrectly
129 // attributed to the first task that happened to fill the cache,
130 // which would yield an overly conservative dep-graph.
131 TraitItems(D),
132 ReprHints(D),
133 TraitSelect(Vec<D>),
134 }
135
136 impl<D: Clone + Debug> DepNode<D> {
137 /// Used in testing
138 pub fn from_label_string(label: &str, data: D) -> Result<DepNode<D>, ()> {
139 macro_rules! check {
140 ($($name:ident,)*) => {
141 match label {
142 $(stringify!($name) => Ok(DepNode::$name(data)),)*
143 _ => Err(())
144 }
145 }
146 }
147
148 if label == "Krate" {
149 // special case
150 return Ok(DepNode::Krate);
151 }
152
153 check! {
154 CollectItem,
155 BorrowCheck,
156 Hir,
157 HirBody,
158 TransCrateItem,
159 TypeckItemType,
160 AssociatedItems,
161 ItemSignature,
162 AssociatedItemDefIds,
163 InherentImpls,
164 TypeckTables,
165 TraitImpls,
166 ReprHints,
167 }
168 }
169
170 pub fn map_def<E, OP>(&self, mut op: OP) -> Option<DepNode<E>>
171 where OP: FnMut(&D) -> Option<E>, E: Clone + Debug
172 {
173 use self::DepNode::*;
174
175 match *self {
176 Krate => Some(Krate),
177 CollectLanguageItems => Some(CollectLanguageItems),
178 CheckStaticRecursion => Some(CheckStaticRecursion),
179 ResolveLifetimes => Some(ResolveLifetimes),
180 RegionResolveCrate => Some(RegionResolveCrate),
181 CheckLoops => Some(CheckLoops),
182 PluginRegistrar => Some(PluginRegistrar),
183 StabilityIndex => Some(StabilityIndex),
184 Coherence => Some(Coherence),
185 EffectCheck => Some(EffectCheck),
186 Liveness => Some(Liveness),
187 Resolve => Some(Resolve),
188 EntryPoint => Some(EntryPoint),
189 CheckEntryFn => Some(CheckEntryFn),
190 Variance => Some(Variance),
191 Dropck => Some(Dropck),
192 UnusedTraitCheck => Some(UnusedTraitCheck),
193 Privacy => Some(Privacy),
194 Reachability => Some(Reachability),
195 DeadCheck => Some(DeadCheck),
196 LateLintCheck => Some(LateLintCheck),
197 TransCrate => Some(TransCrate),
198 TransWriteMetadata => Some(TransWriteMetadata),
199 LinkBinary => Some(LinkBinary),
200
201 // work product names do not need to be mapped, because
202 // they are always absolute.
203 WorkProduct(ref id) => Some(WorkProduct(id.clone())),
204
205 Hir(ref d) => op(d).map(Hir),
206 HirBody(ref d) => op(d).map(HirBody),
207 MetaData(ref d) => op(d).map(MetaData),
208 CollectItem(ref d) => op(d).map(CollectItem),
209 CollectItemSig(ref d) => op(d).map(CollectItemSig),
210 CoherenceCheckImpl(ref d) => op(d).map(CoherenceCheckImpl),
211 CoherenceOverlapCheck(ref d) => op(d).map(CoherenceOverlapCheck),
212 CoherenceOverlapCheckSpecial(ref d) => op(d).map(CoherenceOverlapCheckSpecial),
213 CoherenceOverlapInherentCheck(ref d) => op(d).map(CoherenceOverlapInherentCheck),
214 CoherenceOrphanCheck(ref d) => op(d).map(CoherenceOrphanCheck),
215 WfCheck(ref d) => op(d).map(WfCheck),
216 TypeckItemType(ref d) => op(d).map(TypeckItemType),
217 DropckImpl(ref d) => op(d).map(DropckImpl),
218 CheckConst(ref d) => op(d).map(CheckConst),
219 IntrinsicCheck(ref d) => op(d).map(IntrinsicCheck),
220 MatchCheck(ref d) => op(d).map(MatchCheck),
221 Mir(ref d) => op(d).map(Mir),
222 BorrowCheck(ref d) => op(d).map(BorrowCheck),
223 RvalueCheck(ref d) => op(d).map(RvalueCheck),
224 StabilityCheck(ref d) => op(d).map(StabilityCheck),
225 TransCrateItem(ref d) => op(d).map(TransCrateItem),
226 TransInlinedItem(ref d) => op(d).map(TransInlinedItem),
227 AssociatedItems(ref d) => op(d).map(AssociatedItems),
228 ItemSignature(ref d) => op(d).map(ItemSignature),
229 SizedConstraint(ref d) => op(d).map(SizedConstraint),
230 AssociatedItemDefIds(ref d) => op(d).map(AssociatedItemDefIds),
231 InherentImpls(ref d) => op(d).map(InherentImpls),
232 TypeckTables(ref d) => op(d).map(TypeckTables),
233 TraitImpls(ref d) => op(d).map(TraitImpls),
234 TraitItems(ref d) => op(d).map(TraitItems),
235 ReprHints(ref d) => op(d).map(ReprHints),
236 TraitSelect(ref type_ds) => {
237 let type_ds = try_opt!(type_ds.iter().map(|d| op(d)).collect());
238 Some(TraitSelect(type_ds))
239 }
240 }
241 }
242 }
243
244 /// A "work product" corresponds to a `.o` (or other) file that we
245 /// save in between runs. These ids do not have a DefId but rather
246 /// some independent path or string that persists between runs without
247 /// the need to be mapped or unmapped. (This ensures we can serialize
248 /// them even in the absence of a tcx.)
249 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
250 pub struct WorkProductId(pub String);
251