rustc_query_system/dep_graph/
debug.rs

1//! Code for debugging the dep-graph.
2
3use std::error::Error;
4
5use rustc_data_structures::fx::FxHashMap;
6use rustc_data_structures::sync::Lock;
7
8use super::{DepNode, DepNodeIndex};
9
10/// A dep-node filter goes from a user-defined string to a query over
11/// nodes. Right now the format is like this:
12/// ```ignore (illustrative)
13/// x & y & z
14/// ```
15/// where the format-string of the dep-node must contain `x`, `y`, and
16/// `z`.
17#[derive(Debug)]
18pub struct DepNodeFilter {
19    text: String,
20}
21
22impl DepNodeFilter {
23    pub fn new(text: &str) -> Self {
24        DepNodeFilter { text: text.trim().to_string() }
25    }
26
27    /// Returns `true` if all nodes always pass the filter.
28    pub fn accepts_all(&self) -> bool {
29        self.text.is_empty()
30    }
31
32    /// Tests whether `node` meets the filter, returning true if so.
33    pub fn test(&self, node: &DepNode) -> bool {
34        let debug_str = format!("{node:?}");
35        self.text.split('&').map(|s| s.trim()).all(|f| debug_str.contains(f))
36    }
37}
38
39/// A filter like `F -> G` where `F` and `G` are valid dep-node
40/// filters. This can be used to test the source/target independently.
41pub struct EdgeFilter {
42    pub source: DepNodeFilter,
43    pub target: DepNodeFilter,
44    pub index_to_node: Lock<FxHashMap<DepNodeIndex, DepNode>>,
45}
46
47impl EdgeFilter {
48    pub fn new(test: &str) -> Result<EdgeFilter, Box<dyn Error>> {
49        if let [source, target] = *test.split("->").collect::<Vec<_>>() {
50            Ok(EdgeFilter {
51                source: DepNodeFilter::new(source),
52                target: DepNodeFilter::new(target),
53                index_to_node: Lock::new(FxHashMap::default()),
54            })
55        } else {
56            Err(format!("expected a filter like `a&b -> c&d`, not `{test}`").into())
57        }
58    }
59
60    #[cfg(debug_assertions)]
61    pub fn test(&self, source: &DepNode, target: &DepNode) -> bool {
62        self.source.test(source) && self.target.test(target)
63    }
64}