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.
14 macro_rules! try_opt {
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`.
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.
42 // Represents the HIR node with the given node-id
45 // Represents the body of a function or method. The def-id is that of the
49 // Represents the metadata for a given HIR node, typically found
50 // in an extern crate.
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>),
57 // Represents different phases in the compiler.
73 CoherenceCheckImpl(D),
74 CoherenceOverlapCheck(D),
75 CoherenceOverlapCheckSpecial(D),
76 CoherenceOverlapInherentCheck(D),
77 CoherenceOrphanCheck(D),
89 // Represents the MIR for a fn; also used as the task node for
90 // things read/modify that MIR.
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`).
113 AssociatedItemDefIds(D),
118 // The set of impls for a given trait. Ultimately, it would be
119 // nice to get more fine-grained here (e.g., to include a
120 // simplified type), but we can't do that until we restructure the
121 // HIR to distinguish the *header* of an impl from its body. This
122 // is because changes to the header may change the self-type of
123 // the impl and hence would require us to be more conservative
124 // than changes in the impl body.
127 // Nodes representing caches. To properly handle a true cache, we
128 // don't use a DepTrackingMap, but rather we push a task node.
129 // Otherwise the write into the map would be incorrectly
130 // attributed to the first task that happened to fill the cache,
131 // which would yield an overly conservative dep-graph.
137 impl<D: Clone + Debug> DepNode<D> {
139 pub fn from_label_string(label: &str, data: D) -> Result<DepNode<D>, ()> {
141 ($($name:ident,)*) => {
143 $(stringify!($name) => Ok(DepNode::$name(data)),)*
149 if label == "Krate" {
151 return Ok(DepNode::Krate);
163 AssociatedItemDefIds,
172 pub fn map_def<E, OP>(&self, mut op: OP) -> Option<DepNode<E>>
173 where OP: FnMut(&D) -> Option<E>, E: Clone + Debug
175 use self::DepNode::*;
178 Krate => Some(Krate),
179 CollectLanguageItems => Some(CollectLanguageItems),
180 CheckStaticRecursion => Some(CheckStaticRecursion),
181 ResolveLifetimes => Some(ResolveLifetimes),
182 RegionResolveCrate => Some(RegionResolveCrate),
183 CheckLoops => Some(CheckLoops),
184 PluginRegistrar => Some(PluginRegistrar),
185 StabilityIndex => Some(StabilityIndex),
186 Coherence => Some(Coherence),
187 EffectCheck => Some(EffectCheck),
188 Liveness => Some(Liveness),
189 Resolve => Some(Resolve),
190 EntryPoint => Some(EntryPoint),
191 CheckEntryFn => Some(CheckEntryFn),
192 Variance => Some(Variance),
193 Dropck => Some(Dropck),
194 UnusedTraitCheck => Some(UnusedTraitCheck),
195 Privacy => Some(Privacy),
196 Reachability => Some(Reachability),
197 DeadCheck => Some(DeadCheck),
198 LateLintCheck => Some(LateLintCheck),
199 TransCrate => Some(TransCrate),
200 TransWriteMetadata => Some(TransWriteMetadata),
201 LinkBinary => Some(LinkBinary),
203 // work product names do not need to be mapped, because
204 // they are always absolute.
205 WorkProduct(ref id) => Some(WorkProduct(id.clone())),
207 Hir(ref d) => op(d).map(Hir),
208 HirBody(ref d) => op(d).map(HirBody),
209 MetaData(ref d) => op(d).map(MetaData),
210 CollectItem(ref d) => op(d).map(CollectItem),
211 CollectItemSig(ref d) => op(d).map(CollectItemSig),
212 CoherenceCheckImpl(ref d) => op(d).map(CoherenceCheckImpl),
213 CoherenceOverlapCheck(ref d) => op(d).map(CoherenceOverlapCheck),
214 CoherenceOverlapCheckSpecial(ref d) => op(d).map(CoherenceOverlapCheckSpecial),
215 CoherenceOverlapInherentCheck(ref d) => op(d).map(CoherenceOverlapInherentCheck),
216 CoherenceOrphanCheck(ref d) => op(d).map(CoherenceOrphanCheck),
217 WfCheck(ref d) => op(d).map(WfCheck),
218 TypeckItemType(ref d) => op(d).map(TypeckItemType),
219 DropckImpl(ref d) => op(d).map(DropckImpl),
220 CheckConst(ref d) => op(d).map(CheckConst),
221 IntrinsicCheck(ref d) => op(d).map(IntrinsicCheck),
222 MatchCheck(ref d) => op(d).map(MatchCheck),
223 Mir(ref d) => op(d).map(Mir),
224 BorrowCheck(ref d) => op(d).map(BorrowCheck),
225 RvalueCheck(ref d) => op(d).map(RvalueCheck),
226 StabilityCheck(ref d) => op(d).map(StabilityCheck),
227 TransCrateItem(ref d) => op(d).map(TransCrateItem),
228 TransInlinedItem(ref d) => op(d).map(TransInlinedItem),
229 AssociatedItems(ref d) => op(d).map(AssociatedItems),
230 ItemSignature(ref d) => op(d).map(ItemSignature),
231 SizedConstraint(ref d) => op(d).map(SizedConstraint),
232 AssociatedItemDefIds(ref d) => op(d).map(AssociatedItemDefIds),
233 InherentImpls(ref d) => op(d).map(InherentImpls),
234 TypeckTables(ref d) => op(d).map(TypeckTables),
235 UsedTraitImports(ref d) => op(d).map(UsedTraitImports),
236 TraitImpls(ref d) => op(d).map(TraitImpls),
237 TraitItems(ref d) => op(d).map(TraitItems),
238 ReprHints(ref d) => op(d).map(ReprHints),
239 TraitSelect(ref type_ds) => {
240 let type_ds = try_opt!(type_ds.iter().map(|d| op(d)).collect());
241 Some(TraitSelect(type_ds))
247 /// A "work product" corresponds to a `.o` (or other) file that we
248 /// save in between runs. These ids do not have a DefId but rather
249 /// some independent path or string that persists between runs without
250 /// the need to be mapped or unmapped. (This ensures we can serialize
251 /// them even in the absence of a tcx.)
252 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
253 pub struct WorkProductId(pub String);