• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 pub mod debug;
2 mod dep_node;
3 mod graph;
4 mod query;
5 mod serialized;
6 
7 pub use dep_node::{DepKindStruct, DepNode, DepNodeParams, WorkProductId};
8 pub use graph::{
9     hash_result, DepGraph, DepGraphData, DepNodeColor, DepNodeIndex, TaskDeps, TaskDepsRef,
10     WorkProduct,
11 };
12 pub use query::DepGraphQuery;
13 pub use serialized::{SerializedDepGraph, SerializedDepNodeIndex};
14 
15 use crate::ich::StableHashingContext;
16 use rustc_data_structures::profiling::SelfProfilerRef;
17 use rustc_serialize::{opaque::FileEncoder, Encodable};
18 use rustc_session::Session;
19 
20 use std::hash::Hash;
21 use std::{fmt, panic};
22 
23 use self::graph::{print_markframe_trace, MarkFrame};
24 
25 pub trait DepContext: Copy {
26     type DepKind: self::DepKind;
27 
28     /// Create a hashing context for hashing new results.
with_stable_hashing_context<R>(self, f: impl FnOnce(StableHashingContext<'_>) -> R) -> R29     fn with_stable_hashing_context<R>(self, f: impl FnOnce(StableHashingContext<'_>) -> R) -> R;
30 
31     /// Access the DepGraph.
dep_graph(&self) -> &DepGraph<Self::DepKind>32     fn dep_graph(&self) -> &DepGraph<Self::DepKind>;
33 
34     /// Access the profiler.
profiler(&self) -> &SelfProfilerRef35     fn profiler(&self) -> &SelfProfilerRef;
36 
37     /// Access the compiler session.
sess(&self) -> &Session38     fn sess(&self) -> &Session;
39 
dep_kind_info(&self, dep_node: Self::DepKind) -> &DepKindStruct<Self>40     fn dep_kind_info(&self, dep_node: Self::DepKind) -> &DepKindStruct<Self>;
41 
42     #[inline(always)]
fingerprint_style(self, kind: Self::DepKind) -> FingerprintStyle43     fn fingerprint_style(self, kind: Self::DepKind) -> FingerprintStyle {
44         let data = self.dep_kind_info(kind);
45         if data.is_anon {
46             return FingerprintStyle::Opaque;
47         }
48         data.fingerprint_style
49     }
50 
51     #[inline(always)]
52     /// Return whether this kind always require evaluation.
is_eval_always(self, kind: Self::DepKind) -> bool53     fn is_eval_always(self, kind: Self::DepKind) -> bool {
54         self.dep_kind_info(kind).is_eval_always
55     }
56 
57     /// Try to force a dep node to execute and see if it's green.
58     #[inline]
59     #[instrument(skip(self, frame), level = "debug")]
try_force_from_dep_node( self, dep_node: DepNode<Self::DepKind>, frame: Option<&MarkFrame<'_>>, ) -> bool60     fn try_force_from_dep_node(
61         self,
62         dep_node: DepNode<Self::DepKind>,
63         frame: Option<&MarkFrame<'_>>,
64     ) -> bool {
65         let cb = self.dep_kind_info(dep_node.kind);
66         if let Some(f) = cb.force_from_dep_node {
67             if let Err(value) = panic::catch_unwind(panic::AssertUnwindSafe(|| {
68                 f(self, dep_node);
69             })) {
70                 if !value.is::<rustc_errors::FatalErrorMarker>() {
71                     print_markframe_trace(self.dep_graph(), frame);
72                 }
73                 panic::resume_unwind(value)
74             }
75             true
76         } else {
77             false
78         }
79     }
80 
81     /// Load data from the on-disk cache.
try_load_from_on_disk_cache(self, dep_node: DepNode<Self::DepKind>)82     fn try_load_from_on_disk_cache(self, dep_node: DepNode<Self::DepKind>) {
83         let cb = self.dep_kind_info(dep_node.kind);
84         if let Some(f) = cb.try_load_from_on_disk_cache {
85             f(self, dep_node)
86         }
87     }
88 }
89 
90 pub trait HasDepContext: Copy {
91     type DepKind: self::DepKind;
92     type DepContext: self::DepContext<DepKind = Self::DepKind>;
93 
dep_context(&self) -> &Self::DepContext94     fn dep_context(&self) -> &Self::DepContext;
95 }
96 
97 impl<T: DepContext> HasDepContext for T {
98     type DepKind = T::DepKind;
99     type DepContext = Self;
100 
dep_context(&self) -> &Self::DepContext101     fn dep_context(&self) -> &Self::DepContext {
102         self
103     }
104 }
105 
106 impl<T: HasDepContext, Q: Copy> HasDepContext for (T, Q) {
107     type DepKind = T::DepKind;
108     type DepContext = T::DepContext;
109 
dep_context(&self) -> &Self::DepContext110     fn dep_context(&self) -> &Self::DepContext {
111         self.0.dep_context()
112     }
113 }
114 
115 /// Describes the contents of the fingerprint generated by a given query.
116 #[derive(Debug, PartialEq, Eq, Copy, Clone)]
117 pub enum FingerprintStyle {
118     /// The fingerprint is actually a DefPathHash.
119     DefPathHash,
120     /// The fingerprint is actually a HirId.
121     HirId,
122     /// Query key was `()` or equivalent, so fingerprint is just zero.
123     Unit,
124     /// Some opaque hash.
125     Opaque,
126 }
127 
128 impl FingerprintStyle {
129     #[inline]
reconstructible(self) -> bool130     pub fn reconstructible(self) -> bool {
131         match self {
132             FingerprintStyle::DefPathHash | FingerprintStyle::Unit | FingerprintStyle::HirId => {
133                 true
134             }
135             FingerprintStyle::Opaque => false,
136         }
137     }
138 }
139 
140 /// Describe the different families of dependency nodes.
141 pub trait DepKind: Copy + fmt::Debug + Eq + Hash + Send + Encodable<FileEncoder> + 'static {
142     /// DepKind to use when incr. comp. is turned off.
143     const NULL: Self;
144 
145     /// DepKind to use to create the initial forever-red node.
146     const RED: Self;
147 
148     /// Implementation of `std::fmt::Debug` for `DepNode`.
debug_node(node: &DepNode<Self>, f: &mut fmt::Formatter<'_>) -> fmt::Result149     fn debug_node(node: &DepNode<Self>, f: &mut fmt::Formatter<'_>) -> fmt::Result;
150 
151     /// Execute the operation with provided dependencies.
with_deps<OP, R>(deps: TaskDepsRef<'_, Self>, op: OP) -> R where OP: FnOnce() -> R152     fn with_deps<OP, R>(deps: TaskDepsRef<'_, Self>, op: OP) -> R
153     where
154         OP: FnOnce() -> R;
155 
156     /// Access dependencies from current implicit context.
read_deps<OP>(op: OP) where OP: for<'a> FnOnce(TaskDepsRef<'a, Self>)157     fn read_deps<OP>(op: OP)
158     where
159         OP: for<'a> FnOnce(TaskDepsRef<'a, Self>);
160 }
161