Skip to content

Commit 303fdc1

Browse files
committed
cleanup dep-graph debugging code
Create some re-usable filtering subroutines.
1 parent 0082fc0 commit 303fdc1

File tree

3 files changed

+79
-19
lines changed

3 files changed

+79
-19
lines changed

src/librustc/dep_graph/debug.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright 2012-2015 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+
//! Code for debugging the dep-graph.
12+
13+
use super::dep_node::DepNode;
14+
use std::error::Error;
15+
use std::fmt::Debug;
16+
17+
/// A dep-node filter goes from a user-defined string to a query over
18+
/// nodes. Right now the format is like this:
19+
///
20+
/// x & y & z
21+
///
22+
/// where the format-string of the dep-node must contain `x`, `y`, and
23+
/// `z`.
24+
#[derive(Debug)]
25+
pub struct DepNodeFilter {
26+
text: String
27+
}
28+
29+
impl DepNodeFilter {
30+
pub fn new(text: &str) -> Self {
31+
DepNodeFilter {
32+
text: text.trim().to_string()
33+
}
34+
}
35+
36+
/// True if all nodes always pass the filter.
37+
pub fn accepts_all(&self) -> bool {
38+
self.text.is_empty()
39+
}
40+
41+
/// Tests whether `node` meets the filter, returning true if so.
42+
pub fn test<D: Clone + Debug>(&self, node: &DepNode<D>) -> bool {
43+
let debug_str = format!("{:?}", node);
44+
self.text.split("&")
45+
.map(|s| s.trim())
46+
.all(|f| debug_str.contains(f))
47+
}
48+
}
49+
50+
/// A filter like `F -> G` where `F` and `G` are valid dep-node
51+
/// filters. This can be used to test the source/target independently.
52+
pub struct EdgeFilter {
53+
pub source: DepNodeFilter,
54+
pub target: DepNodeFilter,
55+
}
56+
57+
impl EdgeFilter {
58+
pub fn new(test: &str) -> Result<EdgeFilter, Box<Error>> {
59+
let parts: Vec<_> = test.split("->").collect();
60+
if parts.len() != 2 {
61+
Err(format!("expected a filter like `a&b -> c&d`, not `{}`", test).into())
62+
} else {
63+
Ok(EdgeFilter {
64+
source: DepNodeFilter::new(parts[0]),
65+
target: DepNodeFilter::new(parts[1]),
66+
})
67+
}
68+
}
69+
}

src/librustc/dep_graph/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
pub mod debug;
1112
mod dep_node;
1213
mod dep_tracking_map;
1314
mod edges;

src/librustc_incremental/assert_dep_graph.rs

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
4545
use graphviz as dot;
4646
use rustc::dep_graph::{DepGraphQuery, DepNode};
47+
use rustc::dep_graph::debug::{DepNodeFilter, EdgeFilter};
4748
use rustc::hir::def_id::DefId;
4849
use rustc::ty::TyCtxt;
4950
use rustc_data_structures::fnv::{FnvHashMap, FnvHashSet};
@@ -220,12 +221,11 @@ fn dump_graph(tcx: TyCtxt) {
220221
let nodes = match env::var("RUST_DEP_GRAPH_FILTER") {
221222
Ok(string) => {
222223
// Expect one of: "-> target", "source -> target", or "source ->".
223-
let parts: Vec<_> = string.split("->").collect();
224-
if parts.len() > 2 {
225-
bug!("Invalid RUST_DEP_GRAPH_FILTER: expected '[source] -> [target]'");
226-
}
227-
let sources = node_set(&query, &parts[0]);
228-
let targets = node_set(&query, &parts[1]);
224+
let edge_filter = EdgeFilter::new(&string).unwrap_or_else(|e| {
225+
bug!("invalid filter: {}", e)
226+
});
227+
let sources = node_set(&query, &edge_filter.source);
228+
let targets = node_set(&query, &edge_filter.target);
229229
filter_nodes(&query, &sources, &targets)
230230
}
231231
Err(_) => {
@@ -295,26 +295,16 @@ impl<'a, 'tcx> dot::Labeller<'a> for GraphvizDepGraph {
295295
// Given an optional filter like `"x,y,z"`, returns either `None` (no
296296
// filter) or the set of nodes whose labels contain all of those
297297
// substrings.
298-
fn node_set(query: &DepGraphQuery<DefId>, filter: &str)
298+
fn node_set(query: &DepGraphQuery<DefId>, filter: &DepNodeFilter)
299299
-> Option<FnvHashSet<DepNode<DefId>>>
300300
{
301301
debug!("node_set(filter={:?})", filter);
302302

303-
if filter.trim().is_empty() {
303+
if filter.accepts_all() {
304304
return None;
305305
}
306306

307-
let filters: Vec<&str> = filter.split("&").map(|s| s.trim()).collect();
308-
309-
debug!("node_set: filters={:?}", filters);
310-
311-
Some(query.nodes()
312-
.into_iter()
313-
.filter(|n| {
314-
let s = format!("{:?}", n);
315-
filters.iter().all(|f| s.contains(f))
316-
})
317-
.collect())
307+
Some(query.nodes().into_iter().filter(|n| filter.test(n)).collect())
318308
}
319309

320310
fn filter_nodes(query: &DepGraphQuery<DefId>,

0 commit comments

Comments
 (0)