1919use graphviz as dot;
2020
2121use middle:: ty;
22+ use middle:: region:: CodeExtent ;
2223use super :: Constraint ;
2324use middle:: infer:: SubregionOrigin ;
2425use middle:: infer:: region_inference:: RegionVarBindings ;
2526use util:: nodemap:: { FnvHashMap , FnvHashSet } ;
2627use util:: ppaux:: Repr ;
2728
29+ use std:: borrow:: Cow ;
2830use std:: collections:: hash_map:: Entry :: Vacant ;
2931use std:: old_io:: { self , File } ;
3032use 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 ) ]
124126enum 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
131138impl < ' 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+
189225impl < ' 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 }
0 commit comments