]> git.lizzy.rs Git - rust.git/blob - src/librustc/dep_graph/dep_node.rs
Auto merge of #42394 - ollie27:rustdoc_deref_box, r=QuietMisdreavus
[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     NeedsDrop(D),
115     Layout(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     AllLocalTraitImpls,
127
128     // Nodes representing caches. To properly handle a true cache, we
129     // don't use a DepTrackingMap, but rather we push a task node.
130     // Otherwise the write into the map would be incorrectly
131     // attributed to the first task that happened to fill the cache,
132     // which would yield an overly conservative dep-graph.
133     TraitItems(D),
134     ReprHints(D),
135
136     /// Trait selection cache is a little funny. Given a trait
137     /// reference like `Foo: SomeTrait<Bar>`, there could be
138     /// arbitrarily many def-ids to map on in there (e.g., `Foo`,
139     /// `SomeTrait`, `Bar`). We could have a vector of them, but it
140     /// requires heap-allocation, and trait sel in general can be a
141     /// surprisingly hot path. So instead we pick two def-ids: the
142     /// trait def-id, and the first def-id in the input types. If there
143     /// is no def-id in the input types, then we use the trait def-id
144     /// again. So for example:
145     ///
146     /// - `i32: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Clone }`
147     /// - `u32: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Clone }`
148     /// - `Clone: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Clone }`
149     /// - `Vec<i32>: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Vec }`
150     /// - `String: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: String }`
151     /// - `Foo: Trait<Bar>` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
152     /// - `Foo: Trait<i32>` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
153     /// - `(Foo, Bar): Trait` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
154     /// - `i32: Trait<Foo>` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
155     ///
156     /// You can see that we map many trait refs to the same
157     /// trait-select node.  This is not a problem, it just means
158     /// imprecision in our dep-graph tracking.  The important thing is
159     /// that for any given trait-ref, we always map to the **same**
160     /// trait-select node.
161     TraitSelect { trait_def_id: D, input_def_id: D },
162
163     /// For proj. cache, we just keep a list of all def-ids, since it is
164     /// not a hotspot.
165     ProjectionCache { def_ids: Vec<D> },
166
167     ParamEnv(D),
168     DescribeDef(D),
169     DefSpan(D),
170     Stability(D),
171     Deprecation(D),
172     ItemBodyNestedBodies(D),
173     ConstIsRvaluePromotableToStatic(D),
174     ImplParent(D),
175     TraitOfItem(D),
176     IsExportedSymbol(D),
177     IsMirAvailable(D),
178     ItemAttrs(D),
179     FnArgNames(D),
180 }
181
182 impl<D: Clone + Debug> DepNode<D> {
183     /// Used in testing
184     pub fn from_label_string(label: &str, data: D) -> Result<DepNode<D>, ()> {
185         macro_rules! check {
186             ($($name:ident,)*) => {
187                 match label {
188                     $(stringify!($name) => Ok(DepNode::$name(data)),)*
189                     _ => Err(())
190                 }
191             }
192         }
193
194         if label == "Krate" {
195             // special case
196             return Ok(DepNode::Krate);
197         }
198
199         check! {
200             BorrowCheck,
201             Hir,
202             HirBody,
203             TransCrateItem,
204             AssociatedItems,
205             ItemSignature,
206             ItemVariances,
207             IsForeignItem,
208             AssociatedItemDefIds,
209             InherentImpls,
210             TypeckTables,
211             UsedTraitImports,
212             TraitImpls,
213             ReprHints,
214         }
215     }
216
217     pub fn map_def<E, OP>(&self, mut op: OP) -> Option<DepNode<E>>
218         where OP: FnMut(&D) -> Option<E>, E: Clone + Debug
219     {
220         use self::DepNode::*;
221
222         match *self {
223             Krate => Some(Krate),
224             BorrowCheckKrate => Some(BorrowCheckKrate),
225             MirKrate => Some(MirKrate),
226             TypeckBodiesKrate => Some(TypeckBodiesKrate),
227             Coherence => Some(Coherence),
228             CrateVariances => Some(CrateVariances),
229             Resolve => Some(Resolve),
230             Variance => Some(Variance),
231             PrivacyAccessLevels(k) => Some(PrivacyAccessLevels(k)),
232             Reachability => Some(Reachability),
233             MirKeys => Some(MirKeys),
234             LateLintCheck => Some(LateLintCheck),
235             TransWriteMetadata => Some(TransWriteMetadata),
236
237             // work product names do not need to be mapped, because
238             // they are always absolute.
239             WorkProduct(ref id) => Some(WorkProduct(id.clone())),
240
241             IsCopy(ref d) => op(d).map(IsCopy),
242             IsSized(ref d) => op(d).map(IsSized),
243             IsFreeze(ref d) => op(d).map(IsFreeze),
244             NeedsDrop(ref d) => op(d).map(NeedsDrop),
245             Layout(ref d) => op(d).map(Layout),
246             Hir(ref d) => op(d).map(Hir),
247             HirBody(ref d) => op(d).map(HirBody),
248             MetaData(ref d) => op(d).map(MetaData),
249             CoherenceCheckTrait(ref d) => op(d).map(CoherenceCheckTrait),
250             CoherenceCheckImpl(ref d) => op(d).map(CoherenceCheckImpl),
251             CoherenceOverlapCheck(ref d) => op(d).map(CoherenceOverlapCheck),
252             CoherenceOverlapCheckSpecial(ref d) => op(d).map(CoherenceOverlapCheckSpecial),
253             Mir(ref d) => op(d).map(Mir),
254             MirShim(ref def_ids) => {
255                 let def_ids: Option<Vec<E>> = def_ids.iter().map(op).collect();
256                 def_ids.map(MirShim)
257             }
258             BorrowCheck(ref d) => op(d).map(BorrowCheck),
259             RegionMaps(ref d) => op(d).map(RegionMaps),
260             RvalueCheck(ref d) => op(d).map(RvalueCheck),
261             TransCrateItem(ref d) => op(d).map(TransCrateItem),
262             AssociatedItems(ref d) => op(d).map(AssociatedItems),
263             ItemSignature(ref d) => op(d).map(ItemSignature),
264             ItemVariances(ref d) => op(d).map(ItemVariances),
265             ItemVarianceConstraints(ref d) => op(d).map(ItemVarianceConstraints),
266             IsForeignItem(ref d) => op(d).map(IsForeignItem),
267             TypeParamPredicates((ref item, ref param)) => {
268                 Some(TypeParamPredicates((try_opt!(op(item)), try_opt!(op(param)))))
269             }
270             SizedConstraint(ref d) => op(d).map(SizedConstraint),
271             DtorckConstraint(ref d) => op(d).map(DtorckConstraint),
272             AdtDestructor(ref d) => op(d).map(AdtDestructor),
273             AssociatedItemDefIds(ref d) => op(d).map(AssociatedItemDefIds),
274             InherentImpls(ref d) => op(d).map(InherentImpls),
275             TypeckTables(ref d) => op(d).map(TypeckTables),
276             UsedTraitImports(ref d) => op(d).map(UsedTraitImports),
277             ConstEval(ref d) => op(d).map(ConstEval),
278             SymbolName(ref d) => op(d).map(SymbolName),
279             SpecializationGraph(ref d) => op(d).map(SpecializationGraph),
280             ObjectSafety(ref d) => op(d).map(ObjectSafety),
281             TraitImpls(ref d) => op(d).map(TraitImpls),
282             AllLocalTraitImpls => Some(AllLocalTraitImpls),
283             TraitItems(ref d) => op(d).map(TraitItems),
284             ReprHints(ref d) => op(d).map(ReprHints),
285             TraitSelect { ref trait_def_id, ref input_def_id } => {
286                 op(trait_def_id).and_then(|trait_def_id| {
287                     op(input_def_id).and_then(|input_def_id| {
288                         Some(TraitSelect { trait_def_id: trait_def_id,
289                                            input_def_id: input_def_id })
290                     })
291                 })
292             }
293             ProjectionCache { ref def_ids } => {
294                 let def_ids: Option<Vec<E>> = def_ids.iter().map(op).collect();
295                 def_ids.map(|d| ProjectionCache { def_ids: d })
296             }
297             ParamEnv(ref d) => op(d).map(ParamEnv),
298             DescribeDef(ref d) => op(d).map(DescribeDef),
299             DefSpan(ref d) => op(d).map(DefSpan),
300             Stability(ref d) => op(d).map(Stability),
301             Deprecation(ref d) => op(d).map(Deprecation),
302             ItemAttrs(ref d) => op(d).map(ItemAttrs),
303             FnArgNames(ref d) => op(d).map(FnArgNames),
304             ImplParent(ref d) => op(d).map(ImplParent),
305             TraitOfItem(ref d) => op(d).map(TraitOfItem),
306             IsExportedSymbol(ref d) => op(d).map(IsExportedSymbol),
307             ItemBodyNestedBodies(ref d) => op(d).map(ItemBodyNestedBodies),
308             ConstIsRvaluePromotableToStatic(ref d) => op(d).map(ConstIsRvaluePromotableToStatic),
309             IsMirAvailable(ref d) => op(d).map(IsMirAvailable),
310             GlobalMetaData(ref d, kind) => op(d).map(|d| GlobalMetaData(d, kind)),
311         }
312     }
313 }
314
315 /// A "work product" corresponds to a `.o` (or other) file that we
316 /// save in between runs. These ids do not have a DefId but rather
317 /// some independent path or string that persists between runs without
318 /// the need to be mapped or unmapped. (This ensures we can serialize
319 /// them even in the absence of a tcx.)
320 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
321 pub struct WorkProductId(pub String);
322
323 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
324 pub enum GlobalMetaDataKind {
325     Krate,
326     CrateDeps,
327     DylibDependencyFormats,
328     LangItems,
329     LangItemsMissing,
330     NativeLibraries,
331     CodeMap,
332     Impls,
333     ExportedSymbols,
334 }