@@ -32,8 +32,11 @@ pub(crate) struct Formatter<'mir, 'tcx, A>
32
32
where
33
33
A : Analysis < ' tcx > ,
34
34
{
35
- body : & ' mir Body < ' tcx > ,
36
- results : RefCell < Option < Results < ' tcx , A > > > ,
35
+ // The `RefCell` is used because `<Formatter as Labeller>::node_label`
36
+ // takes `&self`, but it needs to modify the cursor. This is also the
37
+ // reason for the `Formatter`/`BlockFormatter` split; `BlockFormatter` has
38
+ // the operations that involve the mutation, i.e. within the `borrow_mut`.
39
+ cursor : RefCell < ResultsCursor < ' mir , ' tcx , A > > ,
37
40
style : OutputStyle ,
38
41
reachable : BitSet < BasicBlock > ,
39
42
}
@@ -48,11 +51,15 @@ where
48
51
style : OutputStyle ,
49
52
) -> Self {
50
53
let reachable = mir:: traversal:: reachable_as_bitset ( body) ;
51
- Formatter { body, results : Some ( results) . into ( ) , style, reachable }
54
+ Formatter { cursor : results. into_results_cursor ( body) . into ( ) , style, reachable }
55
+ }
56
+
57
+ fn body ( & self ) -> & ' mir Body < ' tcx > {
58
+ self . cursor . borrow ( ) . body ( )
52
59
}
53
60
54
61
pub ( crate ) fn into_results ( self ) -> Results < ' tcx , A > {
55
- self . results . into_inner ( ) . unwrap ( )
62
+ self . cursor . into_inner ( ) . into_results ( )
56
63
}
57
64
}
58
65
81
88
type Edge = CfgEdge ;
82
89
83
90
fn graph_id ( & self ) -> dot:: Id < ' _ > {
84
- let name = graphviz_safe_def_name ( self . body . source . def_id ( ) ) ;
91
+ let name = graphviz_safe_def_name ( self . body ( ) . source . def_id ( ) ) ;
85
92
dot:: Id :: new ( format ! ( "graph_for_def_id_{name}" ) ) . unwrap ( )
86
93
}
87
94
@@ -91,19 +98,11 @@ where
91
98
92
99
fn node_label ( & self , block : & Self :: Node ) -> dot:: LabelText < ' _ > {
93
100
let mut label = Vec :: new ( ) ;
94
- self . results . replace_with ( |results| {
95
- // `Formatter::result` is a `RefCell<Option<_>>` so we can replace
96
- // the value with `None`, move it into the results cursor, move it
97
- // back out, and return it to the refcell wrapped in `Some`.
98
- let mut fmt = BlockFormatter {
99
- cursor : results. take ( ) . unwrap ( ) . into_results_cursor ( self . body ) ,
100
- style : self . style ,
101
- bg : Background :: Light ,
102
- } ;
101
+ let mut cursor = self . cursor . borrow_mut ( ) ;
102
+ let mut fmt =
103
+ BlockFormatter { cursor : & mut cursor, style : self . style , bg : Background :: Light } ;
104
+ fmt. write_node_label ( & mut label, * block) . unwrap ( ) ;
103
105
104
- fmt. write_node_label ( & mut label, * block) . unwrap ( ) ;
105
- Some ( fmt. cursor . into_results ( ) )
106
- } ) ;
107
106
dot:: LabelText :: html ( String :: from_utf8 ( label) . unwrap ( ) )
108
107
}
109
108
@@ -112,20 +111,20 @@ where
112
111
}
113
112
114
113
fn edge_label ( & self , e : & Self :: Edge ) -> dot:: LabelText < ' _ > {
115
- let label = & self . body [ e. source ] . terminator ( ) . kind . fmt_successor_labels ( ) [ e. index ] ;
114
+ let label = & self . body ( ) [ e. source ] . terminator ( ) . kind . fmt_successor_labels ( ) [ e. index ] ;
116
115
dot:: LabelText :: label ( label. clone ( ) )
117
116
}
118
117
}
119
118
120
- impl < ' mir , ' tcx , A > dot:: GraphWalk < ' mir > for Formatter < ' mir , ' tcx , A >
119
+ impl < ' tcx , A > dot:: GraphWalk < ' _ > for Formatter < ' _ , ' tcx , A >
121
120
where
122
121
A : Analysis < ' tcx > ,
123
122
{
124
123
type Node = BasicBlock ;
125
124
type Edge = CfgEdge ;
126
125
127
126
fn nodes ( & self ) -> dot:: Nodes < ' _ , Self :: Node > {
128
- self . body
127
+ self . body ( )
129
128
. basic_blocks
130
129
. indices ( )
131
130
. filter ( |& idx| self . reachable . contains ( idx) )
@@ -134,10 +133,10 @@ where
134
133
}
135
134
136
135
fn edges ( & self ) -> dot:: Edges < ' _ , Self :: Edge > {
137
- self . body
138
- . basic_blocks
136
+ let body = self . body ( ) ;
137
+ body . basic_blocks
139
138
. indices ( )
140
- . flat_map ( |bb| dataflow_successors ( self . body , bb) )
139
+ . flat_map ( |bb| dataflow_successors ( body, bb) )
141
140
. collect :: < Vec < _ > > ( )
142
141
. into ( )
143
142
}
@@ -147,20 +146,20 @@ where
147
146
}
148
147
149
148
fn target ( & self , edge : & Self :: Edge ) -> Self :: Node {
150
- self . body [ edge. source ] . terminator ( ) . successors ( ) . nth ( edge. index ) . unwrap ( )
149
+ self . body ( ) [ edge. source ] . terminator ( ) . successors ( ) . nth ( edge. index ) . unwrap ( )
151
150
}
152
151
}
153
152
154
- struct BlockFormatter < ' mir , ' tcx , A >
153
+ struct BlockFormatter < ' a , ' mir , ' tcx , A >
155
154
where
156
155
A : Analysis < ' tcx > ,
157
156
{
158
- cursor : ResultsCursor < ' mir , ' tcx , A > ,
157
+ cursor : & ' a mut ResultsCursor < ' mir , ' tcx , A > ,
159
158
bg : Background ,
160
159
style : OutputStyle ,
161
160
}
162
161
163
- impl < ' mir , ' tcx , A > BlockFormatter < ' mir , ' tcx , A >
162
+ impl < ' tcx , A > BlockFormatter < ' _ , ' _ , ' tcx , A >
164
163
where
165
164
A : Analysis < ' tcx > ,
166
165
A :: Domain : DebugWithContext < A > ,
0 commit comments