]> git.lizzy.rs Git - rust.git/blob - src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs
0116fbcfc8860d39e648cb4b7cf7e774985624be
[rust.git] / src / librustc_mir / borrow_check / nll / region_infer / graphviz.rs
1 // Copyright 2014 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 //! This module provides linkage between RegionInferenceContext and
12 //! libgraphviz traits, specialized to attaching borrowck analysis
13 //! data to rendered labels.
14
15 use dot::{self, IntoCow};
16 use rustc_data_structures::indexed_vec::Idx;
17 use std::borrow::Cow;
18 use std::io::{self, Write};
19 use super::*;
20 use borrow_check::nll::constraint_set::OutlivesConstraint;
21
22
23 impl<'tcx> RegionInferenceContext<'tcx> {
24     /// Write out the region constraint graph.
25     pub(crate) fn dump_graphviz(&self, mut w: &mut dyn Write) -> io::Result<()> {
26         dot::render(self, &mut w)
27     }
28 }
29
30 impl<'this, 'tcx> dot::Labeller<'this> for RegionInferenceContext<'tcx> {
31     type Node = RegionVid;
32     type Edge = OutlivesConstraint;
33
34     fn graph_id(&'this self) -> dot::Id<'this> {
35         dot::Id::new(format!("RegionInferenceContext")).unwrap()
36     }
37     fn node_id(&'this self, n: &RegionVid) -> dot::Id<'this> {
38         dot::Id::new(format!("r{}", n.index())).unwrap()
39     }
40     fn node_shape(&'this self, _node: &RegionVid) -> Option<dot::LabelText<'this>> {
41         Some(dot::LabelText::LabelStr(Cow::Borrowed("box")))
42     }
43     fn node_label(&'this self, n: &RegionVid) -> dot::LabelText<'this> {
44         dot::LabelText::LabelStr(format!("{:?}", n).into_cow())
45     }
46     fn edge_label(&'this self, e: &OutlivesConstraint) -> dot::LabelText<'this> {
47         dot::LabelText::LabelStr(format!("{:?}", e.locations).into_cow())
48     }
49 }
50
51 impl<'this, 'tcx> dot::GraphWalk<'this> for RegionInferenceContext<'tcx> {
52     type Node = RegionVid;
53     type Edge = OutlivesConstraint;
54
55     fn nodes(&'this self) -> dot::Nodes<'this, RegionVid> {
56         let vids: Vec<RegionVid> = self.definitions.indices().collect();
57         vids.into_cow()
58     }
59     fn edges(&'this self) -> dot::Edges<'this, OutlivesConstraint> {
60         (&self.constraints.raw[..]).into_cow()
61     }
62
63     // Render `a: b` as `a <- b`, indicating the flow
64     // of data during inference.
65
66     fn source(&'this self, edge: &OutlivesConstraint) -> RegionVid {
67         edge.sub
68     }
69
70     fn target(&'this self, edge: &OutlivesConstraint) -> RegionVid {
71         edge.sup
72     }
73 }