]> git.lizzy.rs Git - rust.git/blob - src/librustc/dep_graph/dep_node.rs
Auto merge of #38981 - sdleffler:patch-1, r=alexcrichton
[rust.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     UsedTraitImports(D),
117
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.
125     TraitImpls(D),
126
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.
132     TraitItems(D),
133     ReprHints(D),
134     TraitSelect(Vec<D>),
135 }
136
137 impl<D: Clone + Debug> DepNode<D> {
138     /// Used in testing
139     pub fn from_label_string(label: &str, data: D) -> Result<DepNode<D>, ()> {
140         macro_rules! check {
141             ($($name:ident,)*) => {
142                 match label {
143                     $(stringify!($name) => Ok(DepNode::$name(data)),)*
144                     _ => Err(())
145                 }
146             }
147         }
148
149         if label == "Krate" {
150             // special case
151             return Ok(DepNode::Krate);
152         }
153
154         check! {
155             CollectItem,
156             BorrowCheck,
157             Hir,
158             HirBody,
159             TransCrateItem,
160             TypeckItemType,
161             AssociatedItems,
162             ItemSignature,
163             AssociatedItemDefIds,
164             InherentImpls,
165             TypeckTables,
166             UsedTraitImports,
167             TraitImpls,
168             ReprHints,
169         }
170     }
171
172     pub fn map_def<E, OP>(&self, mut op: OP) -> Option<DepNode<E>>
173         where OP: FnMut(&D) -> Option<E>, E: Clone + Debug
174     {
175         use self::DepNode::*;
176
177         match *self {
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),
202
203             // work product names do not need to be mapped, because
204             // they are always absolute.
205             WorkProduct(ref id) => Some(WorkProduct(id.clone())),
206
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))
242             }
243         }
244     }
245 }
246
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);
254