1 //! This module provides linkage between RegionInferenceContext and
2 //! libgraphviz traits, specialized to attaching borrowck analysis
3 //! data to rendered labels.
6 use std
::io
::{self, Write}
;
9 use crate::borrow_check
::constraints
::OutlivesConstraint
;
11 impl<'tcx
> RegionInferenceContext
<'tcx
> {
12 /// Write out the region constraint graph.
13 crate fn dump_graphviz_raw_constraints(&self, mut w
: &mut dyn Write
) -> io
::Result
<()> {
14 dot
::render(&RawConstraints { regioncx: self }
, &mut w
)
17 /// Write out the region constraint graph.
18 crate fn dump_graphviz_scc_constraints(&self, mut w
: &mut dyn Write
) -> io
::Result
<()> {
19 let mut nodes_per_scc
: IndexVec
<ConstraintSccIndex
, _
> = self.constraint_sccs
24 for region
in self.definitions
.indices() {
25 let scc
= self.constraint_sccs
.scc(region
);
26 nodes_per_scc
[scc
].push(region
);
29 dot
::render(&SccConstraints { regioncx: self, nodes_per_scc }
, &mut w
)
33 struct RawConstraints
<'a
, 'tcx
> {
34 regioncx
: &'a RegionInferenceContext
<'tcx
>,
37 impl<'a
, 'this
, 'tcx
> dot
::Labeller
<'this
> for RawConstraints
<'a
, 'tcx
> {
38 type Node
= RegionVid
;
39 type Edge
= OutlivesConstraint
;
41 fn graph_id(&'this
self) -> dot
::Id
<'this
> {
42 dot
::Id
::new("RegionInferenceContext").unwrap()
44 fn node_id(&'this
self, n
: &RegionVid
) -> dot
::Id
<'this
> {
45 dot
::Id
::new(format
!("r{}", n
.index())).unwrap()
47 fn node_shape(&'this
self, _node
: &RegionVid
) -> Option
<dot
::LabelText
<'this
>> {
48 Some(dot
::LabelText
::LabelStr(Cow
::Borrowed("box")))
50 fn node_label(&'this
self, n
: &RegionVid
) -> dot
::LabelText
<'this
> {
51 dot
::LabelText
::LabelStr(format
!("{:?}", n
).into())
53 fn edge_label(&'this
self, e
: &OutlivesConstraint
) -> dot
::LabelText
<'this
> {
54 dot
::LabelText
::LabelStr(format
!("{:?}", e
.locations
).into())
58 impl<'a
, 'this
, 'tcx
> dot
::GraphWalk
<'this
> for RawConstraints
<'a
, 'tcx
> {
59 type Node
= RegionVid
;
60 type Edge
= OutlivesConstraint
;
62 fn nodes(&'this
self) -> dot
::Nodes
<'this
, RegionVid
> {
63 let vids
: Vec
<RegionVid
> = self.regioncx
.definitions
.indices().collect();
66 fn edges(&'this
self) -> dot
::Edges
<'this
, OutlivesConstraint
> {
67 (&self.regioncx
.constraints
.outlives().raw
[..]).into()
70 // Render `a: b` as `a -> b`, indicating the flow
71 // of data during inference.
73 fn source(&'this
self, edge
: &OutlivesConstraint
) -> RegionVid
{
77 fn target(&'this
self, edge
: &OutlivesConstraint
) -> RegionVid
{
82 struct SccConstraints
<'a
, 'tcx
> {
83 regioncx
: &'a RegionInferenceContext
<'tcx
>,
84 nodes_per_scc
: IndexVec
<ConstraintSccIndex
, Vec
<RegionVid
>>,
87 impl<'a
, 'this
, 'tcx
> dot
::Labeller
<'this
> for SccConstraints
<'a
, 'tcx
> {
88 type Node
= ConstraintSccIndex
;
89 type Edge
= (ConstraintSccIndex
, ConstraintSccIndex
);
91 fn graph_id(&'this
self) -> dot
::Id
<'this
> {
92 dot
::Id
::new("RegionInferenceContext".to_string()).unwrap()
94 fn node_id(&'this
self, n
: &ConstraintSccIndex
) -> dot
::Id
<'this
> {
95 dot
::Id
::new(format
!("r{}", n
.index())).unwrap()
97 fn node_shape(&'this
self, _node
: &ConstraintSccIndex
) -> Option
<dot
::LabelText
<'this
>> {
98 Some(dot
::LabelText
::LabelStr(Cow
::Borrowed("box")))
100 fn node_label(&'this
self, n
: &ConstraintSccIndex
) -> dot
::LabelText
<'this
> {
101 let nodes
= &self.nodes_per_scc
[*n
];
102 dot
::LabelText
::LabelStr(format
!("{:?} = {:?}", n
, nodes
).into())
106 impl<'a
, 'this
, 'tcx
> dot
::GraphWalk
<'this
> for SccConstraints
<'a
, 'tcx
> {
107 type Node
= ConstraintSccIndex
;
108 type Edge
= (ConstraintSccIndex
, ConstraintSccIndex
);
110 fn nodes(&'this
self) -> dot
::Nodes
<'this
, ConstraintSccIndex
> {
111 let vids
: Vec
<ConstraintSccIndex
> = self.regioncx
.constraint_sccs
.all_sccs().collect();
114 fn edges(&'this
self) -> dot
::Edges
<'this
, (ConstraintSccIndex
, ConstraintSccIndex
)> {
115 let edges
: Vec
<_
> = self.regioncx
123 .map(move |&scc_b
| (scc_a
, scc_b
))
130 // Render `a: b` as `a -> b`, indicating the flow
131 // of data during inference.
133 fn source(&'this
self, edge
: &(ConstraintSccIndex
, ConstraintSccIndex
)) -> ConstraintSccIndex
{
137 fn target(&'this
self, edge
: &(ConstraintSccIndex
, ConstraintSccIndex
)) -> ConstraintSccIndex
{