about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-02-07 16:14:20 +0000
committerbors <bors@rust-lang.org>2015-02-07 16:14:20 +0000
commitce5aad2f107e79c5f1baab40aff35b7899322d94 (patch)
treea1cf833eef7ca7aca3ce59e970ccff1ade81d3bd /src
parent8661b3dc0fbb9e21b94266ba62e23cebb8f0603f (diff)
parent7610feb82a386d1637c60a05d6c64b6c4c459bb6 (diff)
downloadrust-ce5aad2f107e79c5f1baab40aff35b7899322d94.tar.gz
rust-ce5aad2f107e79c5f1baab40aff35b7899322d94.zip
Auto merge of #21982 - pnkfelix:extend-Z-print-region-graph, r=nikomatsakis
Extend region-inference graphviz rendering with enclosing relationship as well as the constraint edges.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/infer/region_inference/graphviz.rs61
-rw-r--r--src/librustc/middle/region.rs28
2 files changed, 78 insertions, 11 deletions
diff --git a/src/librustc/middle/infer/region_inference/graphviz.rs b/src/librustc/middle/infer/region_inference/graphviz.rs
index 6a75b1b0d3d..362919755c3 100644
--- a/src/librustc/middle/infer/region_inference/graphviz.rs
+++ b/src/librustc/middle/infer/region_inference/graphviz.rs
@@ -19,12 +19,14 @@
 use graphviz as dot;
 
 use middle::ty;
+use middle::region::CodeExtent;
 use super::Constraint;
 use middle::infer::SubregionOrigin;
 use middle::infer::region_inference::RegionVarBindings;
 use util::nodemap::{FnvHashMap, FnvHashSet};
 use util::ppaux::Repr;
 
+use std::borrow::Cow;
 use std::collections::hash_map::Entry::Vacant;
 use std::old_io::{self, File};
 use std::env;
@@ -120,13 +122,18 @@ struct ConstraintGraph<'a, 'tcx: 'a> {
     node_ids: FnvHashMap<Node, uint>,
 }
 
-#[derive(Clone, Hash, PartialEq, Eq, Debug)]
+#[derive(Clone, Hash, PartialEq, Eq, Debug, Copy)]
 enum Node {
     RegionVid(ty::RegionVid),
     Region(ty::Region),
 }
 
-type Edge = Constraint;
+// type Edge = Constraint;
+#[derive(Clone, PartialEq, Eq, Debug, Copy)]
+enum Edge {
+    Constraint(Constraint),
+    EnclScope(CodeExtent, CodeExtent),
+}
 
 impl<'a, 'tcx> ConstraintGraph<'a, 'tcx> {
     fn new(tcx: &'a ty::ctxt<'tcx>,
@@ -146,6 +153,11 @@ impl<'a, 'tcx> ConstraintGraph<'a, 'tcx> {
                 add_node(n1);
                 add_node(n2);
             }
+
+            tcx.region_maps.each_encl_scope(|sub, sup| {
+                add_node(Node::Region(ty::ReScope(*sub)));
+                add_node(Node::Region(ty::ReScope(*sup)));
+            });
         }
 
         ConstraintGraph { tcx: tcx,
@@ -160,7 +172,17 @@ impl<'a, 'tcx> dot::Labeller<'a, Node, Edge> for ConstraintGraph<'a, 'tcx> {
         dot::Id::new(&*self.graph_name).ok().unwrap()
     }
     fn node_id(&self, n: &Node) -> dot::Id {
-        dot::Id::new(format!("node_{}", self.node_ids.get(n).unwrap())).ok().unwrap()
+        let node_id = match self.node_ids.get(n) {
+            Some(node_id) => node_id,
+            None => panic!("no node_id found for node: {:?}", n),
+        };
+        let name = || format!("node_{}", node_id);
+        match dot::Id::new(name()) {
+            Ok(id) => id,
+            Err(_) => {
+                panic!("failed to create graphviz node identified by {}", name());
+            }
+        }
     }
     fn node_label(&self, n: &Node) -> dot::LabelText {
         match *n {
@@ -171,7 +193,12 @@ impl<'a, 'tcx> dot::Labeller<'a, Node, Edge> for ConstraintGraph<'a, 'tcx> {
         }
     }
     fn edge_label(&self, e: &Edge) -> dot::LabelText {
-        dot::LabelText::label(format!("{}", self.map.get(e).unwrap().repr(self.tcx)))
+        match *e {
+            Edge::Constraint(ref c) =>
+                dot::LabelText::label(format!("{}", self.map.get(c).unwrap().repr(self.tcx))),
+            Edge::EnclScope(..) =>
+                dot::LabelText::label(format!("(enclosed)")),
+        }
     }
 }
 
@@ -186,28 +213,40 @@ fn constraint_to_nodes(c: &Constraint) -> (Node, Node) {
     }
 }
 
+fn edge_to_nodes(e: &Edge) -> (Node, Node) {
+    match *e {
+        Edge::Constraint(ref c) => constraint_to_nodes(c),
+        Edge::EnclScope(sub, sup) => {
+            (Node::Region(ty::ReScope(sub)), Node::Region(ty::ReScope(sup)))
+        }
+    }
+}
+
 impl<'a, 'tcx> dot::GraphWalk<'a, Node, Edge> for ConstraintGraph<'a, 'tcx> {
     fn nodes(&self) -> dot::Nodes<Node> {
         let mut set = FnvHashSet();
-        for constraint in self.map.keys() {
-            let (n1, n2) = constraint_to_nodes(constraint);
-            set.insert(n1);
-            set.insert(n2);
+        for node in self.node_ids.keys() {
+            set.insert(*node);
         }
         debug!("constraint graph has {} nodes", set.len());
         set.into_iter().collect()
     }
     fn edges(&self) -> dot::Edges<Edge> {
         debug!("constraint graph has {} edges", self.map.len());
-        self.map.keys().map(|e|*e).collect()
+        let mut v : Vec<_> = self.map.keys().map(|e| Edge::Constraint(*e)).collect();
+        self.tcx.region_maps.each_encl_scope(|sub, sup| {
+            v.push(Edge::EnclScope(*sub, *sup))
+        });
+        debug!("region graph has {} edges", v.len());
+        Cow::Owned(v)
     }
     fn source(&self, edge: &Edge) -> Node {
-        let (n1, _) = constraint_to_nodes(edge);
+        let (n1, _) = edge_to_nodes(edge);
         debug!("edge {:?} has source {:?}", edge, n1);
         n1
     }
     fn target(&self, edge: &Edge) -> Node {
-        let (_, n2) = constraint_to_nodes(edge);
+        let (_, n2) = edge_to_nodes(edge);
         debug!("edge {:?} has target {:?}", edge, n2);
         n2
     }
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index e8215eb5660..037b1c31a17 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -260,6 +260,34 @@ struct RegionResolutionVisitor<'a> {
 
 
 impl RegionMaps {
+    pub fn each_encl_scope<E>(&self, mut e:E) where E: FnMut(&CodeExtent, &CodeExtent) {
+        for (child, parent) in self.scope_map.borrow().iter() {
+            e(child, parent)
+        }
+    }
+    pub fn each_var_scope<E>(&self, mut e:E) where E: FnMut(&ast::NodeId, &CodeExtent) {
+        for (child, parent) in self.var_map.borrow().iter() {
+            e(child, parent)
+        }
+    }
+    pub fn each_encl_free_region<E>(&self, mut e:E) where E: FnMut(&FreeRegion, &FreeRegion) {
+        for (child, parents) in self.free_region_map.borrow().iter() {
+            for parent in parents.iter() {
+                e(child, parent)
+            }
+        }
+    }
+    pub fn each_rvalue_scope<E>(&self, mut e:E) where E: FnMut(&ast::NodeId, &CodeExtent) {
+        for (child, parent) in self.rvalue_scopes.borrow().iter() {
+            e(child, parent)
+        }
+    }
+    pub fn each_terminating_scope<E>(&self, mut e:E) where E: FnMut(&CodeExtent) {
+        for scope in self.terminating_scopes.borrow().iter() {
+            e(scope)
+        }
+    }
+
     pub fn relate_free_regions(&self, sub: FreeRegion, sup: FreeRegion) {
         match self.free_region_map.borrow_mut().get_mut(&sub) {
             Some(sups) => {