Skip to content

Commit 576ba8f

Browse files
committed
Extend region-inference graphviz rendering with enclosing relationship
as well as the constraint edges.
1 parent 189930f commit 576ba8f

File tree

2 files changed

+78
-11
lines changed

2 files changed

+78
-11
lines changed

src/librustc/middle/infer/region_inference/graphviz.rs

+50-11
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@
1919
use graphviz as dot;
2020

2121
use middle::ty;
22+
use middle::region::CodeExtent;
2223
use super::Constraint;
2324
use middle::infer::SubregionOrigin;
2425
use middle::infer::region_inference::RegionVarBindings;
2526
use util::nodemap::{FnvHashMap, FnvHashSet};
2627
use util::ppaux::Repr;
2728

29+
use std::borrow::Cow;
2830
use std::collections::hash_map::Entry::Vacant;
2931
use std::old_io::{self, File};
3032
use std::env;
@@ -120,13 +122,18 @@ struct ConstraintGraph<'a, 'tcx: 'a> {
120122
node_ids: FnvHashMap<Node, uint>,
121123
}
122124

123-
#[derive(Clone, Hash, PartialEq, Eq, Debug)]
125+
#[derive(Clone, Hash, PartialEq, Eq, Debug, Copy)]
124126
enum Node {
125127
RegionVid(ty::RegionVid),
126128
Region(ty::Region),
127129
}
128130

129-
type Edge = Constraint;
131+
// type Edge = Constraint;
132+
#[derive(Clone, PartialEq, Eq, Debug, Copy)]
133+
enum Edge {
134+
Constraint(Constraint),
135+
EnclScope(CodeExtent, CodeExtent),
136+
}
130137

131138
impl<'a, 'tcx> ConstraintGraph<'a, 'tcx> {
132139
fn new(tcx: &'a ty::ctxt<'tcx>,
@@ -146,6 +153,11 @@ impl<'a, 'tcx> ConstraintGraph<'a, 'tcx> {
146153
add_node(n1);
147154
add_node(n2);
148155
}
156+
157+
tcx.region_maps.each_encl_scope(|&mut: sub, sup| {
158+
add_node(Node::Region(ty::ReScope(*sub)));
159+
add_node(Node::Region(ty::ReScope(*sup)));
160+
});
149161
}
150162

151163
ConstraintGraph { tcx: tcx,
@@ -160,7 +172,17 @@ impl<'a, 'tcx> dot::Labeller<'a, Node, Edge> for ConstraintGraph<'a, 'tcx> {
160172
dot::Id::new(&*self.graph_name).ok().unwrap()
161173
}
162174
fn node_id(&self, n: &Node) -> dot::Id {
163-
dot::Id::new(format!("node_{}", self.node_ids.get(n).unwrap())).ok().unwrap()
175+
let node_id = match self.node_ids.get(n) {
176+
Some(node_id) => node_id,
177+
None => panic!("no node_id found for node: {:?}", n),
178+
};
179+
let name = |&:| format!("node_{}", node_id);
180+
match dot::Id::new(name()) {
181+
Ok(id) => id,
182+
Err(_) => {
183+
panic!("failed to create graphviz node identified by {}", name());
184+
}
185+
}
164186
}
165187
fn node_label(&self, n: &Node) -> dot::LabelText {
166188
match *n {
@@ -171,7 +193,12 @@ impl<'a, 'tcx> dot::Labeller<'a, Node, Edge> for ConstraintGraph<'a, 'tcx> {
171193
}
172194
}
173195
fn edge_label(&self, e: &Edge) -> dot::LabelText {
174-
dot::LabelText::label(format!("{}", self.map.get(e).unwrap().repr(self.tcx)))
196+
match *e {
197+
Edge::Constraint(ref c) =>
198+
dot::LabelText::label(format!("{}", self.map.get(c).unwrap().repr(self.tcx))),
199+
Edge::EnclScope(..) =>
200+
dot::LabelText::label(format!("(enclosed)")),
201+
}
175202
}
176203
}
177204

@@ -186,28 +213,40 @@ fn constraint_to_nodes(c: &Constraint) -> (Node, Node) {
186213
}
187214
}
188215

216+
fn edge_to_nodes(e: &Edge) -> (Node, Node) {
217+
match *e {
218+
Edge::Constraint(ref c) => constraint_to_nodes(c),
219+
Edge::EnclScope(sub, sup) => {
220+
(Node::Region(ty::ReScope(sub)), Node::Region(ty::ReScope(sup)))
221+
}
222+
}
223+
}
224+
189225
impl<'a, 'tcx> dot::GraphWalk<'a, Node, Edge> for ConstraintGraph<'a, 'tcx> {
190226
fn nodes(&self) -> dot::Nodes<Node> {
191227
let mut set = FnvHashSet();
192-
for constraint in self.map.keys() {
193-
let (n1, n2) = constraint_to_nodes(constraint);
194-
set.insert(n1);
195-
set.insert(n2);
228+
for node in self.node_ids.keys() {
229+
set.insert(*node);
196230
}
197231
debug!("constraint graph has {} nodes", set.len());
198232
set.into_iter().collect()
199233
}
200234
fn edges(&self) -> dot::Edges<Edge> {
201235
debug!("constraint graph has {} edges", self.map.len());
202-
self.map.keys().map(|e|*e).collect()
236+
let mut v : Vec<_> = self.map.keys().map(|e| Edge::Constraint(*e)).collect();
237+
self.tcx.region_maps.each_encl_scope(|&mut: sub, sup| {
238+
v.push(Edge::EnclScope(*sub, *sup))
239+
});
240+
debug!("region graph has {} edges", v.len());
241+
Cow::Owned(v)
203242
}
204243
fn source(&self, edge: &Edge) -> Node {
205-
let (n1, _) = constraint_to_nodes(edge);
244+
let (n1, _) = edge_to_nodes(edge);
206245
debug!("edge {:?} has source {:?}", edge, n1);
207246
n1
208247
}
209248
fn target(&self, edge: &Edge) -> Node {
210-
let (_, n2) = constraint_to_nodes(edge);
249+
let (_, n2) = edge_to_nodes(edge);
211250
debug!("edge {:?} has target {:?}", edge, n2);
212251
n2
213252
}

src/librustc/middle/region.rs

+28
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,34 @@ struct RegionResolutionVisitor<'a> {
260260

261261

262262
impl RegionMaps {
263+
pub fn each_encl_scope<E>(&self, mut e:E) where E: FnMut(&CodeExtent, &CodeExtent) {
264+
for (child, parent) in self.scope_map.borrow().iter() {
265+
e(child, parent)
266+
}
267+
}
268+
pub fn each_var_scope<E>(&self, mut e:E) where E: FnMut(&ast::NodeId, &CodeExtent) {
269+
for (child, parent) in self.var_map.borrow().iter() {
270+
e(child, parent)
271+
}
272+
}
273+
pub fn each_encl_free_region<E>(&self, mut e:E) where E: FnMut(&FreeRegion, &FreeRegion) {
274+
for (child, parents) in self.free_region_map.borrow().iter() {
275+
for parent in parents.iter() {
276+
e(child, parent)
277+
}
278+
}
279+
}
280+
pub fn each_rvalue_scope<E>(&self, mut e:E) where E: FnMut(&ast::NodeId, &CodeExtent) {
281+
for (child, parent) in self.rvalue_scopes.borrow().iter() {
282+
e(child, parent)
283+
}
284+
}
285+
pub fn each_terminating_scope<E>(&self, mut e:E) where E: FnMut(&CodeExtent) {
286+
for scope in self.terminating_scopes.borrow().iter() {
287+
e(scope)
288+
}
289+
}
290+
263291
pub fn relate_free_regions(&self, sub: FreeRegion, sup: FreeRegion) {
264292
match self.free_region_map.borrow_mut().get_mut(&sub) {
265293
Some(sups) => {

0 commit comments

Comments
 (0)