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