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