diff options
Diffstat (limited to 'compiler/rustc_query_system/src/dep_graph/debug.rs')
-rw-r--r-- | compiler/rustc_query_system/src/dep_graph/debug.rs | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/compiler/rustc_query_system/src/dep_graph/debug.rs b/compiler/rustc_query_system/src/dep_graph/debug.rs new file mode 100644 index 000000000..f9f3169af --- /dev/null +++ b/compiler/rustc_query_system/src/dep_graph/debug.rs @@ -0,0 +1,63 @@ +//! Code for debugging the dep-graph. + +use super::{DepKind, DepNode, DepNodeIndex}; +use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::sync::Lock; +use std::error::Error; + +/// A dep-node filter goes from a user-defined string to a query over +/// nodes. Right now the format is like this: +/// ```ignore (illustrative) +/// x & y & z +/// ``` +/// where the format-string of the dep-node must contain `x`, `y`, and +/// `z`. +#[derive(Debug)] +pub struct DepNodeFilter { + text: String, +} + +impl DepNodeFilter { + pub fn new(text: &str) -> Self { + DepNodeFilter { text: text.trim().to_string() } + } + + /// Returns `true` if all nodes always pass the filter. + pub fn accepts_all(&self) -> bool { + self.text.is_empty() + } + + /// Tests whether `node` meets the filter, returning true if so. + pub fn test<K: DepKind>(&self, node: &DepNode<K>) -> bool { + let debug_str = format!("{:?}", node); + self.text.split('&').map(|s| s.trim()).all(|f| debug_str.contains(f)) + } +} + +/// A filter like `F -> G` where `F` and `G` are valid dep-node +/// filters. This can be used to test the source/target independently. +pub struct EdgeFilter<K: DepKind> { + pub source: DepNodeFilter, + pub target: DepNodeFilter, + pub index_to_node: Lock<FxHashMap<DepNodeIndex, DepNode<K>>>, +} + +impl<K: DepKind> EdgeFilter<K> { + pub fn new(test: &str) -> Result<EdgeFilter<K>, Box<dyn Error>> { + let parts: Vec<_> = test.split("->").collect(); + if parts.len() != 2 { + Err(format!("expected a filter like `a&b -> c&d`, not `{}`", test).into()) + } else { + Ok(EdgeFilter { + source: DepNodeFilter::new(parts[0]), + target: DepNodeFilter::new(parts[1]), + index_to_node: Lock::new(FxHashMap::default()), + }) + } + } + + #[cfg(debug_assertions)] + pub fn test(&self, source: &DepNode<K>, target: &DepNode<K>) -> bool { + self.source.test(source) && self.target.test(target) + } +} |