19
19
use graphviz as dot;
20
20
21
21
use middle:: ty;
22
+ use middle:: region:: CodeExtent ;
22
23
use super :: Constraint ;
23
24
use middle:: infer:: SubregionOrigin ;
24
25
use middle:: infer:: region_inference:: RegionVarBindings ;
25
26
use util:: nodemap:: { FnvHashMap , FnvHashSet } ;
26
27
use util:: ppaux:: Repr ;
27
28
29
+ use std:: borrow:: Cow ;
28
30
use std:: collections:: hash_map:: Entry :: Vacant ;
29
31
use std:: old_io:: { self , File } ;
30
32
use std:: env;
@@ -120,13 +122,18 @@ struct ConstraintGraph<'a, 'tcx: 'a> {
120
122
node_ids : FnvHashMap < Node , uint > ,
121
123
}
122
124
123
- #[ derive( Clone , Hash , PartialEq , Eq , Debug ) ]
125
+ #[ derive( Clone , Hash , PartialEq , Eq , Debug , Copy ) ]
124
126
enum Node {
125
127
RegionVid ( ty:: RegionVid ) ,
126
128
Region ( ty:: Region ) ,
127
129
}
128
130
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
+ }
130
137
131
138
impl < ' a , ' tcx > ConstraintGraph < ' a , ' tcx > {
132
139
fn new ( tcx : & ' a ty:: ctxt < ' tcx > ,
@@ -146,6 +153,11 @@ impl<'a, 'tcx> ConstraintGraph<'a, 'tcx> {
146
153
add_node ( n1) ;
147
154
add_node ( n2) ;
148
155
}
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
+ } ) ;
149
161
}
150
162
151
163
ConstraintGraph { tcx : tcx,
@@ -160,7 +172,17 @@ impl<'a, 'tcx> dot::Labeller<'a, Node, Edge> for ConstraintGraph<'a, 'tcx> {
160
172
dot:: Id :: new ( & * self . graph_name ) . ok ( ) . unwrap ( )
161
173
}
162
174
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
+ }
164
186
}
165
187
fn node_label ( & self , n : & Node ) -> dot:: LabelText {
166
188
match * n {
@@ -171,7 +193,12 @@ impl<'a, 'tcx> dot::Labeller<'a, Node, Edge> for ConstraintGraph<'a, 'tcx> {
171
193
}
172
194
}
173
195
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
+ }
175
202
}
176
203
}
177
204
@@ -186,28 +213,40 @@ fn constraint_to_nodes(c: &Constraint) -> (Node, Node) {
186
213
}
187
214
}
188
215
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
+
189
225
impl < ' a , ' tcx > dot:: GraphWalk < ' a , Node , Edge > for ConstraintGraph < ' a , ' tcx > {
190
226
fn nodes ( & self ) -> dot:: Nodes < Node > {
191
227
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) ;
196
230
}
197
231
debug ! ( "constraint graph has {} nodes" , set. len( ) ) ;
198
232
set. into_iter ( ) . collect ( )
199
233
}
200
234
fn edges ( & self ) -> dot:: Edges < Edge > {
201
235
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)
203
242
}
204
243
fn source ( & self , edge : & Edge ) -> Node {
205
- let ( n1, _) = constraint_to_nodes ( edge) ;
244
+ let ( n1, _) = edge_to_nodes ( edge) ;
206
245
debug ! ( "edge {:?} has source {:?}" , edge, n1) ;
207
246
n1
208
247
}
209
248
fn target ( & self , edge : & Edge ) -> Node {
210
- let ( _, n2) = constraint_to_nodes ( edge) ;
249
+ let ( _, n2) = edge_to_nodes ( edge) ;
211
250
debug ! ( "edge {:?} has target {:?}" , edge, n2) ;
212
251
n2
213
252
}
0 commit comments