@@ -36,13 +36,13 @@ struct LoopScope {
36
36
pub fn construct ( tcx : & ty:: ctxt ,
37
37
blk : & ast:: Block ) -> CFG {
38
38
let mut graph = graph:: Graph :: new ( ) ;
39
- let entry = add_initial_dummy_node ( & mut graph) ;
39
+ let entry = graph. add_node ( CFGNodeData :: Entry ) ;
40
40
41
41
// `fn_exit` is target of return exprs, which lies somewhere
42
42
// outside input `blk`. (Distinguishing `fn_exit` and `block_exit`
43
43
// also resolves chicken-and-egg problem that arises if you try to
44
44
// have return exprs jump to `block_exit` during construction.)
45
- let fn_exit = add_initial_dummy_node ( & mut graph) ;
45
+ let fn_exit = graph. add_node ( CFGNodeData :: Exit ) ;
46
46
let block_exit;
47
47
48
48
let mut cfg_builder = CFGBuilder {
@@ -61,10 +61,6 @@ pub fn construct(tcx: &ty::ctxt,
61
61
exit : fn_exit}
62
62
}
63
63
64
- fn add_initial_dummy_node ( g : & mut CFGGraph ) -> CFGIndex {
65
- g. add_node ( CFGNodeData { id : ast:: DUMMY_NODE_ID } )
66
- }
67
-
68
64
impl < ' a , ' tcx > CFGBuilder < ' a , ' tcx > {
69
65
fn block ( & mut self , blk : & ast:: Block , pred : CFGIndex ) -> CFGIndex {
70
66
let mut stmts_exit = pred;
@@ -74,19 +70,19 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
74
70
75
71
let expr_exit = self . opt_expr ( & blk. expr , stmts_exit) ;
76
72
77
- self . add_node ( blk. id , & [ expr_exit] )
73
+ self . add_ast_node ( blk. id , & [ expr_exit] )
78
74
}
79
75
80
76
fn stmt ( & mut self , stmt : & ast:: Stmt , pred : CFGIndex ) -> CFGIndex {
81
77
match stmt. node {
82
78
ast:: StmtDecl ( ref decl, id) => {
83
79
let exit = self . decl ( & * * decl, pred) ;
84
- self . add_node ( id, & [ exit] )
80
+ self . add_ast_node ( id, & [ exit] )
85
81
}
86
82
87
83
ast:: StmtExpr ( ref expr, id) | ast:: StmtSemi ( ref expr, id) => {
88
84
let exit = self . expr ( & * * expr, pred) ;
89
- self . add_node ( id, & [ exit] )
85
+ self . add_ast_node ( id, & [ exit] )
90
86
}
91
87
92
88
ast:: StmtMac ( ..) => {
@@ -115,33 +111,33 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
115
111
ast:: PatLit ( ..) |
116
112
ast:: PatRange ( ..) |
117
113
ast:: PatWild ( _) => {
118
- self . add_node ( pat. id , & [ pred] )
114
+ self . add_ast_node ( pat. id , & [ pred] )
119
115
}
120
116
121
117
ast:: PatBox ( ref subpat) |
122
118
ast:: PatRegion ( ref subpat, _) |
123
119
ast:: PatIdent ( _, _, Some ( ref subpat) ) => {
124
120
let subpat_exit = self . pat ( & * * subpat, pred) ;
125
- self . add_node ( pat. id , & [ subpat_exit] )
121
+ self . add_ast_node ( pat. id , & [ subpat_exit] )
126
122
}
127
123
128
124
ast:: PatEnum ( _, Some ( ref subpats) ) |
129
125
ast:: PatTup ( ref subpats) => {
130
126
let pats_exit = self . pats_all ( subpats. iter ( ) , pred) ;
131
- self . add_node ( pat. id , & [ pats_exit] )
127
+ self . add_ast_node ( pat. id , & [ pats_exit] )
132
128
}
133
129
134
130
ast:: PatStruct ( _, ref subpats, _) => {
135
131
let pats_exit =
136
132
self . pats_all ( subpats. iter ( ) . map ( |f| & f. node . pat ) , pred) ;
137
- self . add_node ( pat. id , & [ pats_exit] )
133
+ self . add_ast_node ( pat. id , & [ pats_exit] )
138
134
}
139
135
140
136
ast:: PatVec ( ref pre, ref vec, ref post) => {
141
137
let pre_exit = self . pats_all ( pre. iter ( ) , pred) ;
142
138
let vec_exit = self . pats_all ( vec. iter ( ) , pre_exit) ;
143
139
let post_exit = self . pats_all ( post. iter ( ) , vec_exit) ;
144
- self . add_node ( pat. id , & [ post_exit] )
140
+ self . add_ast_node ( pat. id , & [ post_exit] )
145
141
}
146
142
147
143
ast:: PatMac ( _) => {
@@ -178,7 +174,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
178
174
match expr. node {
179
175
ast:: ExprBlock ( ref blk) => {
180
176
let blk_exit = self . block ( & * * blk, pred) ;
181
- self . add_node ( expr. id , & [ blk_exit] )
177
+ self . add_ast_node ( expr. id , & [ blk_exit] )
182
178
}
183
179
184
180
ast:: ExprIf ( ref cond, ref then, None ) => {
@@ -198,7 +194,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
198
194
//
199
195
let cond_exit = self . expr ( & * * cond, pred) ; // 1
200
196
let then_exit = self . block ( & * * then, cond_exit) ; // 2
201
- self . add_node ( expr. id , & [ cond_exit, then_exit] ) // 3,4
197
+ self . add_ast_node ( expr. id , & [ cond_exit, then_exit] ) // 3,4
202
198
}
203
199
204
200
ast:: ExprIf ( ref cond, ref then, Some ( ref otherwise) ) => {
@@ -219,7 +215,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
219
215
let cond_exit = self . expr ( & * * cond, pred) ; // 1
220
216
let then_exit = self . block ( & * * then, cond_exit) ; // 2
221
217
let else_exit = self . expr ( & * * otherwise, cond_exit) ; // 3
222
- self . add_node ( expr. id , & [ then_exit, else_exit] ) // 4, 5
218
+ self . add_ast_node ( expr. id , & [ then_exit, else_exit] ) // 4, 5
223
219
}
224
220
225
221
ast:: ExprIfLet ( ..) => {
@@ -247,7 +243,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
247
243
// Is the condition considered part of the loop?
248
244
let loopback = self . add_dummy_node ( & [ pred] ) ; // 1
249
245
let cond_exit = self . expr ( & * * cond, loopback) ; // 2
250
- let expr_exit = self . add_node ( expr. id , & [ cond_exit] ) ; // 3
246
+ let expr_exit = self . add_ast_node ( expr. id , & [ cond_exit] ) ; // 3
251
247
self . loop_scopes . push ( LoopScope {
252
248
loop_id : expr. id ,
253
249
continue_index : loopback,
@@ -283,7 +279,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
283
279
// may cause additional edges.
284
280
285
281
let loopback = self . add_dummy_node ( & [ pred] ) ; // 1
286
- let expr_exit = self . add_node ( expr. id , & [ ] ) ; // 2
282
+ let expr_exit = self . add_ast_node ( expr. id , & [ ] ) ; // 2
287
283
self . loop_scopes . push ( LoopScope {
288
284
loop_id : expr. id ,
289
285
continue_index : loopback,
@@ -323,7 +319,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
323
319
//
324
320
let discr_exit = self . expr ( & * * discr, pred) ; // 1
325
321
326
- let expr_exit = self . add_node ( expr. id , & [ ] ) ;
322
+ let expr_exit = self . add_ast_node ( expr. id , & [ ] ) ;
327
323
let mut cond_exit = discr_exit;
328
324
for arm in arms {
329
325
cond_exit = self . add_dummy_node ( & [ cond_exit] ) ; // 2
@@ -354,30 +350,30 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
354
350
//
355
351
let l_exit = self . expr ( & * * l, pred) ; // 1
356
352
let r_exit = self . expr ( & * * r, l_exit) ; // 2
357
- self . add_node ( expr. id , & [ l_exit, r_exit] ) // 3,4
353
+ self . add_ast_node ( expr. id , & [ l_exit, r_exit] ) // 3,4
358
354
}
359
355
360
356
ast:: ExprRet ( ref v) => {
361
357
let v_exit = self . opt_expr ( v, pred) ;
362
- let b = self . add_node ( expr. id , & [ v_exit] ) ;
358
+ let b = self . add_ast_node ( expr. id , & [ v_exit] ) ;
363
359
self . add_returning_edge ( expr, b) ;
364
- self . add_node ( ast :: DUMMY_NODE_ID , & [ ] )
360
+ self . add_unreachable_node ( )
365
361
}
366
362
367
363
ast:: ExprBreak ( label) => {
368
364
let loop_scope = self . find_scope ( expr, label) ;
369
- let b = self . add_node ( expr. id , & [ pred] ) ;
365
+ let b = self . add_ast_node ( expr. id , & [ pred] ) ;
370
366
self . add_exiting_edge ( expr, b,
371
367
loop_scope, loop_scope. break_index ) ;
372
- self . add_node ( ast :: DUMMY_NODE_ID , & [ ] )
368
+ self . add_unreachable_node ( )
373
369
}
374
370
375
371
ast:: ExprAgain ( label) => {
376
372
let loop_scope = self . find_scope ( expr, label) ;
377
- let a = self . add_node ( expr. id , & [ pred] ) ;
373
+ let a = self . add_ast_node ( expr. id , & [ pred] ) ;
378
374
self . add_exiting_edge ( expr, a,
379
375
loop_scope, loop_scope. continue_index ) ;
380
- self . add_node ( ast :: DUMMY_NODE_ID , & [ ] )
376
+ self . add_unreachable_node ( )
381
377
}
382
378
383
379
ast:: ExprVec ( ref elems) => {
@@ -454,7 +450,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
454
450
let & ( _, ref expr, _) = a;
455
451
& * * expr
456
452
} ) , post_inputs) ;
457
- self . add_node ( expr. id , & [ post_outputs] )
453
+ self . add_ast_node ( expr. id , & [ post_outputs] )
458
454
}
459
455
460
456
ast:: ExprMac ( ..) |
@@ -481,7 +477,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
481
477
let func_or_rcvr_exit = self . expr ( func_or_rcvr, pred) ;
482
478
let ret = self . straightline ( call_expr, func_or_rcvr_exit, args) ;
483
479
if return_ty. diverges ( ) {
484
- self . add_node ( ast :: DUMMY_NODE_ID , & [ ] )
480
+ self . add_unreachable_node ( )
485
481
} else {
486
482
ret
487
483
}
@@ -508,17 +504,26 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
508
504
//! Handles case of an expression that evaluates `subexprs` in order
509
505
510
506
let subexprs_exit = self . exprs ( subexprs, pred) ;
511
- self . add_node ( expr. id , & [ subexprs_exit] )
507
+ self . add_ast_node ( expr. id , & [ subexprs_exit] )
512
508
}
513
509
514
510
fn add_dummy_node ( & mut self , preds : & [ CFGIndex ] ) -> CFGIndex {
515
- self . add_node ( ast :: DUMMY_NODE_ID , preds)
511
+ self . add_node ( CFGNodeData :: Dummy , preds)
516
512
}
517
513
518
- fn add_node ( & mut self , id : ast:: NodeId , preds : & [ CFGIndex ] ) -> CFGIndex {
514
+ fn add_ast_node ( & mut self , id : ast:: NodeId , preds : & [ CFGIndex ] ) -> CFGIndex {
519
515
assert ! ( !self . exit_map. contains_key( & id) ) ;
520
- let node = self . graph . add_node ( CFGNodeData { id : id} ) ;
521
- if id != ast:: DUMMY_NODE_ID {
516
+ assert ! ( id != ast:: DUMMY_NODE_ID ) ;
517
+ self . add_node ( CFGNodeData :: AST ( id) , preds)
518
+ }
519
+
520
+ fn add_unreachable_node ( & mut self ) -> CFGIndex {
521
+ self . add_node ( CFGNodeData :: Unreachable , & [ ] )
522
+ }
523
+
524
+ fn add_node ( & mut self , data : CFGNodeData , preds : & [ CFGIndex ] ) -> CFGIndex {
525
+ let node = self . graph . add_node ( data) ;
526
+ if let CFGNodeData :: AST ( id) = data {
522
527
assert ! ( !self . exit_map. contains_key( & id) ) ;
523
528
self . exit_map . insert ( id, node) ;
524
529
}
0 commit comments