]> git.lizzy.rs Git - rust.git/blob - src/librustc/dep_graph/dep_node.rs
make parameter-environment a query
[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 hir::def_id::CrateNum;
12 use std::fmt::Debug;
13 use std::sync::Arc;
14
15 macro_rules! try_opt {
16     ($e:expr) => (
17         match $e {
18             Some(r) => r,
19             None => return None,
20         }
21     )
22 }
23
24 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
25 pub enum DepNode<D: Clone + Debug> {
26     // The `D` type is "how definitions are identified".
27     // During compilation, it is always `DefId`, but when serializing
28     // it is mapped to `DefPath`.
29
30     // Represents the `Krate` as a whole (the `hir::Krate` value) (as
31     // distinct from the krate module). This is basically a hash of
32     // the entire krate, so if you read from `Krate` (e.g., by calling
33     // `tcx.hir.krate()`), we will have to assume that any change
34     // means that you need to be recompiled. This is because the
35     // `Krate` value gives you access to all other items. To avoid
36     // this fate, do not call `tcx.hir.krate()`; instead, prefer
37     // wrappers like `tcx.visit_all_items_in_krate()`.  If there is no
38     // suitable wrapper, you can use `tcx.dep_graph.ignore()` to gain
39     // access to the krate, but you must remember to add suitable
40     // edges yourself for the individual items that you read.
41     Krate,
42
43     // Represents the HIR node with the given node-id
44     Hir(D),
45
46     // Represents the body of a function or method. The def-id is that of the
47     // function/method.
48     HirBody(D),
49
50     // Represents the metadata for a given HIR node, typically found
51     // in an extern crate.
52     MetaData(D),
53
54     // Represents some piece of metadata global to its crate.
55     GlobalMetaData(D, GlobalMetaDataKind),
56
57     // Represents some artifact that we save to disk. Note that these
58     // do not have a def-id as part of their identifier.
59     WorkProduct(Arc<WorkProductId>),
60
61     // Represents different phases in the compiler.
62     RegionMaps(D),
63     Coherence,
64     Resolve,
65     CoherenceCheckTrait(D),
66     CoherenceCheckImpl(D),
67     CoherenceOverlapCheck(D),
68     CoherenceOverlapCheckSpecial(D),
69     Variance,
70     PrivacyAccessLevels(CrateNum),
71
72     // Represents the MIR for a fn; also used as the task node for
73     // things read/modify that MIR.
74     MirKrate,
75     Mir(D),
76     MirShim(Vec<D>),
77
78     BorrowCheckKrate,
79     BorrowCheck(D),
80     RvalueCheck(D),
81     Reachability,
82     MirKeys,
83     LateLintCheck,
84     TransCrateItem(D),
85     TransWriteMetadata,
86     CrateVariances,
87
88     // Nodes representing bits of computed IR in the tcx. Each shared
89     // table in the tcx (or elsewhere) maps to one of these
90     // nodes. Often we map multiple tables to the same node if there
91     // is no point in distinguishing them (e.g., both the type and
92     // predicates for an item wind up in `ItemSignature`).
93     AssociatedItems(D),
94     ItemSignature(D),
95     ItemVarianceConstraints(D),
96     ItemVariances(D),
97     IsForeignItem(D),
98     TypeParamPredicates((D, D)),
99     SizedConstraint(D),
100     DtorckConstraint(D),
101     AdtDestructor(D),
102     AssociatedItemDefIds(D),
103     InherentImpls(D),
104     TypeckBodiesKrate,
105     TypeckTables(D),
106     UsedTraitImports(D),
107     ConstEval(D),
108     SymbolName(D),
109     SpecializationGraph(D),
110     ObjectSafety(D),
111     IsCopy(D),
112     IsSized(D),
113     IsFreeze(D),
114
115     // The set of impls for a given trait. Ultimately, it would be
116     // nice to get more fine-grained here (e.g., to include a
117     // simplified type), but we can't do that until we restructure the
118     // HIR to distinguish the *header* of an impl from its body.  This
119     // is because changes to the header may change the self-type of
120     // the impl and hence would require us to be more conservative
121     // than changes in the impl body.
122     TraitImpls(D),
123
124     AllLocalTraitImpls,
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
134     // Trait selection cache is a little funny. Given a trait
135     // reference like `Foo: SomeTrait<Bar>`, there could be
136     // arbitrarily many def-ids to map on in there (e.g., `Foo`,
137     // `SomeTrait`, `Bar`). We could have a vector of them, but it
138     // requires heap-allocation, and trait sel in general can be a
139     // surprisingly hot path. So instead we pick two def-ids: the
140     // trait def-id, and the first def-id in the input types. If there
141     // is no def-id in the input types, then we use the trait def-id
142     // again. So for example:
143     //
144     // - `i32: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Clone }`
145     // - `u32: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Clone }`
146     // - `Clone: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Clone }`
147     // - `Vec<i32>: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Vec }`
148     // - `String: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: String }`
149     // - `Foo: Trait<Bar>` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
150     // - `Foo: Trait<i32>` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
151     // - `(Foo, Bar): Trait` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
152     // - `i32: Trait<Foo>` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
153     //
154     // You can see that we map many trait refs to the same
155     // trait-select node.  This is not a problem, it just means
156     // imprecision in our dep-graph tracking.  The important thing is
157     // that for any given trait-ref, we always map to the **same**
158     // trait-select node.
159     TraitSelect { trait_def_id: D, input_def_id: D },
160
161     // For proj. cache, we just keep a list of all def-ids, since it is
162     // not a hotspot.
163     ProjectionCache { def_ids: Vec<D> },
164
165     ParameterEnvironment(D),
166     DescribeDef(D),
167     DefSpan(D),
168     Stability(D),
169     Deprecation(D),
170     ItemBodyNestedBodies(D),
171     ConstIsRvaluePromotableToStatic(D),
172     ImplParent(D),
173     TraitOfItem(D),
174     IsExportedSymbol(D),
175     IsMirAvailable(D),
176     ItemAttrs(D),
177     FnArgNames(D),
178     FileMap(D, Arc<String>),
179 }
180
181 impl<D: Clone + Debug> DepNode<D> {
182     /// Used in testing
183     pub fn from_label_string(label: &str, data: D) -> Result<DepNode<D>, ()> {
184         macro_rules! check {
185             ($($name:ident,)*) => {
186                 match label {
187                     $(stringify!($name) => Ok(DepNode::$name(data)),)*
188                     _ => Err(())
189                 }
190             }
191         }
192
193         if label == "Krate" {
194             // special case
195             return Ok(DepNode::Krate);
196         }
197
198         check! {
199             BorrowCheck,
200             Hir,
201             HirBody,
202             TransCrateItem,
203             AssociatedItems,
204             ItemSignature,
205             ItemVariances,
206             IsForeignItem,
207             AssociatedItemDefIds,
208             InherentImpls,
209             TypeckTables,
210             UsedTraitImports,
211             TraitImpls,
212             ReprHints,
213         }
214     }
215
216     pub fn map_def<E, OP>(&self, mut op: OP) -> Option<DepNode<E>>
217         where OP: FnMut(&D) -> Option<E>, E: Clone + Debug
218     {
219         use self::DepNode::*;
220
221         match *self {
222             Krate => Some(Krate),
223             BorrowCheckKrate => Some(BorrowCheckKrate),
224             MirKrate => Some(MirKrate),
225             TypeckBodiesKrate => Some(TypeckBodiesKrate),
226             Coherence => Some(Coherence),
227             CrateVariances => Some(CrateVariances),
228             Resolve => Some(Resolve),
229             Variance => Some(Variance),
230             PrivacyAccessLevels(k) => Some(PrivacyAccessLevels(k)),
231             Reachability => Some(Reachability),
232             MirKeys => Some(MirKeys),
233             LateLintCheck => Some(LateLintCheck),
234             TransWriteMetadata => Some(TransWriteMetadata),
235
236             // work product names do not need to be mapped, because
237             // they are always absolute.
238             WorkProduct(ref id) => Some(WorkProduct(id.clone())),
239
240             IsCopy(ref d) => op(d).map(IsCopy),
241             IsSized(ref d) => op(d).map(IsSized),
242             IsFreeze(ref d) => op(d).map(IsFreeze),
243             Hir(ref d) => op(d).map(Hir),
244             HirBody(ref d) => op(d).map(HirBody),
245             MetaData(ref d) => op(d).map(MetaData),
246             CoherenceCheckTrait(ref d) => op(d).map(CoherenceCheckTrait),
247             CoherenceCheckImpl(ref d) => op(d).map(CoherenceCheckImpl),
248             CoherenceOverlapCheck(ref d) => op(d).map(CoherenceOverlapCheck),
249             CoherenceOverlapCheckSpecial(ref d) => op(d).map(CoherenceOverlapCheckSpecial),
250             Mir(ref d) => op(d).map(Mir),
251             MirShim(ref def_ids) => {
252                 let def_ids: Option<Vec<E>> = def_ids.iter().map(op).collect();
253                 def_ids.map(MirShim)
254             }
255             BorrowCheck(ref d) => op(d).map(BorrowCheck),
256             RegionMaps(ref d) => op(d).map(RegionMaps),
257             RvalueCheck(ref d) => op(d).map(RvalueCheck),
258             TransCrateItem(ref d) => op(d).map(TransCrateItem),
259             AssociatedItems(ref d) => op(d).map(AssociatedItems),
260             ItemSignature(ref d) => op(d).map(ItemSignature),
261             ItemVariances(ref d) => op(d).map(ItemVariances),
262             ItemVarianceConstraints(ref d) => op(d).map(ItemVarianceConstraints),
263             IsForeignItem(ref d) => op(d).map(IsForeignItem),
264             TypeParamPredicates((ref item, ref param)) => {
265                 Some(TypeParamPredicates((try_opt!(op(item)), try_opt!(op(param)))))
266             }
267             SizedConstraint(ref d) => op(d).map(SizedConstraint),
268             DtorckConstraint(ref d) => op(d).map(DtorckConstraint),
269             AdtDestructor(ref d) => op(d).map(AdtDestructor),
270             AssociatedItemDefIds(ref d) => op(d).map(AssociatedItemDefIds),
271             InherentImpls(ref d) => op(d).map(InherentImpls),
272             TypeckTables(ref d) => op(d).map(TypeckTables),
273             UsedTraitImports(ref d) => op(d).map(UsedTraitImports),
274             ConstEval(ref d) => op(d).map(ConstEval),
275             SymbolName(ref d) => op(d).map(SymbolName),
276             SpecializationGraph(ref d) => op(d).map(SpecializationGraph),
277             ObjectSafety(ref d) => op(d).map(ObjectSafety),
278             TraitImpls(ref d) => op(d).map(TraitImpls),
279             AllLocalTraitImpls => Some(AllLocalTraitImpls),
280             TraitItems(ref d) => op(d).map(TraitItems),
281             ReprHints(ref d) => op(d).map(ReprHints),
282             TraitSelect { ref trait_def_id, ref input_def_id } => {
283                 op(trait_def_id).and_then(|trait_def_id| {
284                     op(input_def_id).and_then(|input_def_id| {
285                         Some(TraitSelect { trait_def_id: trait_def_id,
286                                            input_def_id: input_def_id })
287                     })
288                 })
289             }
290             ProjectionCache { ref def_ids } => {
291                 let def_ids: Option<Vec<E>> = def_ids.iter().map(op).collect();
292                 def_ids.map(|d| ProjectionCache { def_ids: d })
293             }
294             ParameterEnvironment(ref d) => op(d).map(ParameterEnvironment),
295             DescribeDef(ref d) => op(d).map(DescribeDef),
296             DefSpan(ref d) => op(d).map(DefSpan),
297             Stability(ref d) => op(d).map(Stability),
298             Deprecation(ref d) => op(d).map(Deprecation),
299             ItemAttrs(ref d) => op(d).map(ItemAttrs),
300             FnArgNames(ref d) => op(d).map(FnArgNames),
301             ImplParent(ref d) => op(d).map(ImplParent),
302             TraitOfItem(ref d) => op(d).map(TraitOfItem),
303             IsExportedSymbol(ref d) => op(d).map(IsExportedSymbol),
304             ItemBodyNestedBodies(ref d) => op(d).map(ItemBodyNestedBodies),
305             ConstIsRvaluePromotableToStatic(ref d) => op(d).map(ConstIsRvaluePromotableToStatic),
306             IsMirAvailable(ref d) => op(d).map(IsMirAvailable),
307             GlobalMetaData(ref d, kind) => op(d).map(|d| GlobalMetaData(d, kind)),
308             FileMap(ref d, ref file_name) => op(d).map(|d| FileMap(d, file_name.clone())),
309         }
310     }
311 }
312
313 /// A "work product" corresponds to a `.o` (or other) file that we
314 /// save in between runs. These ids do not have a DefId but rather
315 /// some independent path or string that persists between runs without
316 /// the need to be mapped or unmapped. (This ensures we can serialize
317 /// them even in the absence of a tcx.)
318 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
319 pub struct WorkProductId(pub String);
320
321 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
322 pub enum GlobalMetaDataKind {
323     Krate,
324     CrateDeps,
325     DylibDependencyFormats,
326     LangItems,
327     LangItemsMissing,
328     NativeLibraries,
329     CodeMap,
330     Impls,
331     ExportedSymbols,
332 }