From baeae780e054865d1bfb11de0eb7b294a9390599 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Tue, 26 Jan 2016 22:23:05 +0100 Subject: [PATCH] Switch libgraphviz from type params to associated types for Node/Edge. --- src/libgraphviz/lib.rs | 102 +++++++++++------- src/librustc/middle/cfg/graphviz.rs | 12 ++- .../middle/infer/region_inference/graphviz.rs | 8 +- src/librustc_borrowck/graphviz.rs | 8 +- src/librustc_trans/trans/assert_dep_graph.rs | 8 +- 5 files changed, 90 insertions(+), 48 deletions(-) diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs index 2e26cc1b2660..f1317e80b034 100644 --- a/src/libgraphviz/lib.rs +++ b/src/libgraphviz/lib.rs @@ -62,7 +62,9 @@ //! dot::render(&edges, output).unwrap() //! } //! -//! impl<'a> dot::Labeller<'a, Nd, Ed> for Edges { +//! impl<'a> dot::Labeller<'a> for Edges { +//! type Node = Nd; +//! type Edge = Ed; //! fn graph_id(&'a self) -> dot::Id<'a> { dot::Id::new("example1").unwrap() } //! //! fn node_id(&'a self, n: &Nd) -> dot::Id<'a> { @@ -70,7 +72,9 @@ //! } //! } //! -//! impl<'a> dot::GraphWalk<'a, Nd, Ed> for Edges { +//! impl<'a> dot::GraphWalk<'a> for Edges { +//! type Node = Nd; +//! type Edge = Ed; //! fn nodes(&self) -> dot::Nodes<'a,Nd> { //! // (assumes that |N| \approxeq |E|) //! let &Edges(ref v) = self; @@ -167,7 +171,9 @@ //! dot::render(&graph, output).unwrap() //! } //! -//! impl<'a> dot::Labeller<'a, Nd, Ed<'a>> for Graph { +//! impl<'a> dot::Labeller<'a> for Graph { +//! type Node = Nd; +//! type Edge = Ed<'a>; //! fn graph_id(&'a self) -> dot::Id<'a> { dot::Id::new("example2").unwrap() } //! fn node_id(&'a self, n: &Nd) -> dot::Id<'a> { //! dot::Id::new(format!("N{}", n)).unwrap() @@ -180,7 +186,9 @@ //! } //! } //! -//! impl<'a> dot::GraphWalk<'a, Nd, Ed<'a>> for Graph { +//! impl<'a> dot::GraphWalk<'a> for Graph { +//! type Node = Nd; +//! type Edge = Ed<'a>; //! fn nodes(&self) -> dot::Nodes<'a,Nd> { (0..self.nodes.len()).collect() } //! fn edges(&'a self) -> dot::Edges<'a,Ed<'a>> { self.edges.iter().collect() } //! fn source(&self, e: &Ed) -> Nd { let & &(s,_) = e; s } @@ -225,7 +233,9 @@ //! dot::render(&graph, output).unwrap() //! } //! -//! impl<'a> dot::Labeller<'a, Nd<'a>, Ed<'a>> for Graph { +//! impl<'a> dot::Labeller<'a> for Graph { +//! type Node = Nd<'a>; +//! type Edge = Ed<'a>; //! fn graph_id(&'a self) -> dot::Id<'a> { dot::Id::new("example3").unwrap() } //! fn node_id(&'a self, n: &Nd<'a>) -> dot::Id<'a> { //! dot::Id::new(format!("N{}", n.0)).unwrap() @@ -239,7 +249,9 @@ //! } //! } //! -//! impl<'a> dot::GraphWalk<'a, Nd<'a>, Ed<'a>> for Graph { +//! impl<'a> dot::GraphWalk<'a> for Graph { +//! type Node = Nd<'a>; +//! type Edge = Ed<'a>; //! fn nodes(&'a self) -> dot::Nodes<'a,Nd<'a>> { //! self.nodes.iter().map(|s| &s[..]).enumerate().collect() //! } @@ -447,45 +459,48 @@ impl<'a> Id<'a> { /// The graph instance is responsible for providing the DOT compatible /// identifiers for the nodes and (optionally) rendered labels for the nodes and /// edges, as well as an identifier for the graph itself. -pub trait Labeller<'a,N,E> { +pub trait Labeller<'a> { + type Node; + type Edge; + /// Must return a DOT compatible identifier naming the graph. fn graph_id(&'a self) -> Id<'a>; /// Maps `n` to a unique identifier with respect to `self`. The /// implementor is responsible for ensuring that the returned name /// is a valid DOT identifier. - fn node_id(&'a self, n: &N) -> Id<'a>; + fn node_id(&'a self, n: &Self::Node) -> Id<'a>; /// Maps `n` to one of the [graphviz `shape` names][1]. If `None` /// is returned, no `shape` attribute is specified. /// /// [1]: http://www.graphviz.org/content/node-shapes - fn node_shape(&'a self, _node: &N) -> Option> { + fn node_shape(&'a self, _node: &Self::Node) -> Option> { None } /// Maps `n` to a label that will be used in the rendered output. /// The label need not be unique, and may be the empty string; the /// default is just the output from `node_id`. - fn node_label(&'a self, n: &N) -> LabelText<'a> { + fn node_label(&'a self, n: &Self::Node) -> LabelText<'a> { LabelStr(self.node_id(n).name) } /// Maps `e` to a label that will be used in the rendered output. /// The label need not be unique, and may be the empty string; the /// default is in fact the empty string. - fn edge_label(&'a self, e: &E) -> LabelText<'a> { + fn edge_label(&'a self, e: &Self::Edge) -> LabelText<'a> { let _ignored = e; LabelStr("".into_cow()) } /// Maps `n` to a style that will be used in the rendered output. - fn node_style(&'a self, _n: &N) -> Style { + fn node_style(&'a self, _n: &Self::Node) -> Style { Style::None } /// Maps `e` to a style that will be used in the rendered output. - fn edge_style(&'a self, _e: &E) -> Style { + fn edge_style(&'a self, _e: &Self::Edge) -> Style { Style::None } } @@ -596,15 +611,18 @@ pub type Edges<'a,E> = Cow<'a,[E]>; /// `Cow<[T]>` to leave implementors the freedom to create /// entirely new vectors or to pass back slices into internally owned /// vectors. -pub trait GraphWalk<'a, N: Clone, E: Clone> { +pub trait GraphWalk<'a> { + type Node: Clone; + type Edge: Clone; + /// Returns all the nodes in this graph. - fn nodes(&'a self) -> Nodes<'a, N>; + fn nodes(&'a self) -> Nodes<'a, Self::Node>; /// Returns all of the edges in this graph. - fn edges(&'a self) -> Edges<'a, E>; + fn edges(&'a self) -> Edges<'a, Self::Edge>; /// The source node for `edge`. - fn source(&'a self, edge: &E) -> N; + fn source(&'a self, edge: &Self::Edge) -> Self::Node; /// The target node for `edge`. - fn target(&'a self, edge: &E) -> N; + fn target(&'a self, edge: &Self::Edge) -> Self::Node; } #[derive(Copy, Clone, PartialEq, Eq, Debug)] @@ -622,28 +640,26 @@ pub fn default_options() -> Vec { /// Renders directed graph `g` into the writer `w` in DOT syntax. /// (Simple wrapper around `render_opts` that passes a default set of options.) -pub fn render<'a, - N: Clone + 'a, - E: Clone + 'a, - G: Labeller<'a, N, E> + GraphWalk<'a, N, E>, - W: Write> - (g: &'a G, - w: &mut W) - -> io::Result<()> { +pub fn render<'a,N,E,G,W>(g: &'a G, w: &mut W) -> io::Result<()> + where N: Clone + 'a, + E: Clone + 'a, + G: Labeller<'a, Node=N, Edge=E> + GraphWalk<'a, Node=N, Edge=E>, + W: Write +{ render_opts(g, w, &[]) } /// Renders directed graph `g` into the writer `w` in DOT syntax. /// (Main entry point for the library.) -pub fn render_opts<'a, - N: Clone + 'a, - E: Clone + 'a, - G: Labeller<'a, N, E> + GraphWalk<'a, N, E>, - W: Write> - (g: &'a G, - w: &mut W, - options: &[RenderOption]) - -> io::Result<()> { +pub fn render_opts<'a, N, E, G, W>(g: &'a G, + w: &mut W, + options: &[RenderOption]) + -> io::Result<()> + where N: Clone + 'a, + E: Clone + 'a, + G: Labeller<'a, Node=N, Edge=E> + GraphWalk<'a, Node=N, Edge=E>, + W: Write +{ fn writeln(w: &mut W, arg: &[&str]) -> io::Result<()> { for &s in arg { try!(w.write_all(s.as_bytes())); @@ -858,7 +874,9 @@ mod tests { Id::new(format!("N{}", *n)).unwrap() } - impl<'a> Labeller<'a, Node, &'a Edge> for LabelledGraph { + impl<'a> Labeller<'a> for LabelledGraph { + type Node = Node; + type Edge = &'a Edge; fn graph_id(&'a self) -> Id<'a> { Id::new(&self.name[..]).unwrap() } @@ -882,7 +900,9 @@ mod tests { } } - impl<'a> Labeller<'a, Node, &'a Edge> for LabelledGraphWithEscStrs { + impl<'a> Labeller<'a> for LabelledGraphWithEscStrs { + type Node = Node; + type Edge = &'a Edge; fn graph_id(&'a self) -> Id<'a> { self.graph.graph_id() } @@ -901,7 +921,9 @@ mod tests { } } - impl<'a> GraphWalk<'a, Node, &'a Edge> for LabelledGraph { + impl<'a> GraphWalk<'a> for LabelledGraph { + type Node = Node; + type Edge = &'a Edge; fn nodes(&'a self) -> Nodes<'a, Node> { (0..self.node_labels.len()).collect() } @@ -916,7 +938,9 @@ mod tests { } } - impl<'a> GraphWalk<'a, Node, &'a Edge> for LabelledGraphWithEscStrs { + impl<'a> GraphWalk<'a> for LabelledGraphWithEscStrs { + type Node = Node; + type Edge = &'a Edge; fn nodes(&'a self) -> Nodes<'a, Node> { self.graph.nodes() } diff --git a/src/librustc/middle/cfg/graphviz.rs b/src/librustc/middle/cfg/graphviz.rs index e80709250708..c9c712c2d6e1 100644 --- a/src/librustc/middle/cfg/graphviz.rs +++ b/src/librustc/middle/cfg/graphviz.rs @@ -52,7 +52,9 @@ fn replace_newline_with_backslash_l(s: String) -> String { } } -impl<'a, 'ast> dot::Labeller<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a, 'ast> { +impl<'a, 'ast> dot::Labeller<'a> for LabelledCFG<'a, 'ast> { + type Node = Node<'a>; + type Edge = Edge<'a>; fn graph_id(&'a self) -> dot::Id<'a> { dot::Id::new(&self.name[..]).unwrap() } fn node_id(&'a self, &(i,_): &Node<'a>) -> dot::Id<'a> { @@ -97,7 +99,9 @@ impl<'a, 'ast> dot::Labeller<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a, 'ast> { } } -impl<'a> dot::GraphWalk<'a, Node<'a>, Edge<'a>> for &'a cfg::CFG { +impl<'a> dot::GraphWalk<'a> for &'a cfg::CFG { + type Node = Node<'a>; + type Edge = Edge<'a>; fn nodes(&'a self) -> dot::Nodes<'a, Node<'a>> { let mut v = Vec::new(); self.graph.each_node(|i, nd| { v.push((i, nd)); true }); @@ -116,8 +120,10 @@ impl<'a> dot::GraphWalk<'a, Node<'a>, Edge<'a>> for &'a cfg::CFG { } } -impl<'a, 'ast> dot::GraphWalk<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a, 'ast> +impl<'a, 'ast> dot::GraphWalk<'a> for LabelledCFG<'a, 'ast> { + type Node = Node<'a>; + type Edge = Edge<'a>; fn nodes(&'a self) -> dot::Nodes<'a, Node<'a>> { self.cfg.nodes() } fn edges(&'a self) -> dot::Edges<'a, Edge<'a>> { self.cfg.edges() } fn source(&'a self, edge: &Edge<'a>) -> Node<'a> { self.cfg.source(edge) } diff --git a/src/librustc/middle/infer/region_inference/graphviz.rs b/src/librustc/middle/infer/region_inference/graphviz.rs index b6c9b5636d9a..23559e7b340e 100644 --- a/src/librustc/middle/infer/region_inference/graphviz.rs +++ b/src/librustc/middle/infer/region_inference/graphviz.rs @@ -173,7 +173,9 @@ impl<'a, 'tcx> ConstraintGraph<'a, 'tcx> { } } -impl<'a, 'tcx> dot::Labeller<'a, Node, Edge> for ConstraintGraph<'a, 'tcx> { +impl<'a, 'tcx> dot::Labeller<'a> for ConstraintGraph<'a, 'tcx> { + type Node = Node; + type Edge = Edge; fn graph_id(&self) -> dot::Id { dot::Id::new(&*self.graph_name).unwrap() } @@ -224,7 +226,9 @@ fn edge_to_nodes(e: &Edge) -> (Node, Node) { } } -impl<'a, 'tcx> dot::GraphWalk<'a, Node, Edge> for ConstraintGraph<'a, 'tcx> { +impl<'a, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'tcx> { + type Node = Node; + type Edge = Edge; fn nodes(&self) -> dot::Nodes { let mut set = FnvHashSet(); for node in self.node_ids.keys() { diff --git a/src/librustc_borrowck/graphviz.rs b/src/librustc_borrowck/graphviz.rs index 7a5491cdbe7f..fd23772bcda1 100644 --- a/src/librustc_borrowck/graphviz.rs +++ b/src/librustc_borrowck/graphviz.rs @@ -129,7 +129,9 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> { } } -impl<'a, 'tcx> dot::Labeller<'a, Node<'a>, Edge<'a>> for DataflowLabeller<'a, 'tcx> { +impl<'a, 'tcx> dot::Labeller<'a> for DataflowLabeller<'a, 'tcx> { + type Node = Node<'a>; + type Edge = Edge<'a>; fn graph_id(&'a self) -> dot::Id<'a> { self.inner.graph_id() } fn node_id(&'a self, n: &Node<'a>) -> dot::Id<'a> { self.inner.node_id(n) } fn node_label(&'a self, n: &Node<'a>) -> dot::LabelText<'a> { @@ -143,7 +145,9 @@ impl<'a, 'tcx> dot::Labeller<'a, Node<'a>, Edge<'a>> for DataflowLabeller<'a, 't fn edge_label(&'a self, e: &Edge<'a>) -> dot::LabelText<'a> { self.inner.edge_label(e) } } -impl<'a, 'tcx> dot::GraphWalk<'a, Node<'a>, Edge<'a>> for DataflowLabeller<'a, 'tcx> { +impl<'a, 'tcx> dot::GraphWalk<'a> for DataflowLabeller<'a, 'tcx> { + type Node = Node<'a>; + type Edge = Edge<'a>; fn nodes(&'a self) -> dot::Nodes<'a, Node<'a>> { self.inner.nodes() } fn edges(&'a self) -> dot::Edges<'a, Edge<'a>> { self.inner.edges() } fn source(&'a self, edge: &Edge<'a>) -> Node<'a> { self.inner.source(edge) } diff --git a/src/librustc_trans/trans/assert_dep_graph.rs b/src/librustc_trans/trans/assert_dep_graph.rs index a186a8ea99ce..11386715492b 100644 --- a/src/librustc_trans/trans/assert_dep_graph.rs +++ b/src/librustc_trans/trans/assert_dep_graph.rs @@ -253,7 +253,9 @@ fn dump_graph(tcx: &TyCtxt) { pub struct GraphvizDepGraph(FnvHashSet, Vec<(DepNode, DepNode)>); -impl<'a, 'tcx> dot::GraphWalk<'a, DepNode, (DepNode, DepNode)> for GraphvizDepGraph { +impl<'a, 'tcx> dot::GraphWalk<'a> for GraphvizDepGraph { + type Node = DepNode; + type Edge = (DepNode, DepNode); fn nodes(&self) -> dot::Nodes { let nodes: Vec<_> = self.0.iter().cloned().collect(); nodes.into_cow() @@ -269,7 +271,9 @@ impl<'a, 'tcx> dot::GraphWalk<'a, DepNode, (DepNode, DepNode)> for GraphvizDepGr } } -impl<'a, 'tcx> dot::Labeller<'a, DepNode, (DepNode, DepNode)> for GraphvizDepGraph { +impl<'a, 'tcx> dot::Labeller<'a> for GraphvizDepGraph { + type Node = DepNode; + type Edge = (DepNode, DepNode); fn graph_id(&self) -> dot::Id { dot::Id::new("DependencyGraph").unwrap() }