@@ -28,16 +28,24 @@ type binding = {node_id: ast::node_id,
28
28
name : ~str ,
29
29
br : ty:: bound_region } ;
30
30
31
- /// Mapping from a block/expr/binding to the innermost scope that
32
- /// bounds its lifetime. For a block/expression, this is the lifetime
33
- /// in which it will be evaluated. For a binding, this is the lifetime
34
- /// in which is in scope.
31
+ /**
32
+ Encodes the bounding lifetime for a given AST node:
33
+
34
+ - Expressions are mapped to the expression or block encoding the maximum
35
+ (static) lifetime of a value produced by that expression. This is
36
+ generally the innermost call, statement, match, or block.
37
+
38
+ - Variables and bindings are mapped to the block in which they are declared.
39
+
40
+ */
35
41
type region_map = hashmap < ast:: node_id , ast:: node_id > ;
36
42
37
- type ctxt = {
38
- sess : session ,
39
- def_map : resolve3:: DefMap ,
40
- region_map : region_map ,
43
+ struct ctxt {
44
+ sess : session ;
45
+ def_map: resolve3:: DefMap ;
46
+
47
+ // Generated maps:
48
+ region_map: region_map;
41
49
42
50
// Generally speaking, expressions are parented to their innermost
43
51
// enclosing block. But some kinds of expressions serve as
@@ -46,9 +54,9 @@ type ctxt = {
46
54
// the condition in a while loop is always a parent. In those
47
55
// cases, we add the node id of such an expression to this set so
48
56
// that when we visit it we can view it as a parent.
49
- root_exprs : hashmap < ast:: node_id , ( ) > ,
57
+ root_exprs: hashmap<ast:: node_id, ( ) >;
50
58
51
- // The parent scope is the innermost block, call, or alt
59
+ // The parent scope is the innermost block, statement, call, or alt
52
60
// expression during the execution of which the current expression
53
61
// will be evaluated. Generally speaking, the innermost parent
54
62
// scope is also the closest suitable ancestor in the AST tree.
@@ -79,8 +87,8 @@ type ctxt = {
79
87
// Here, the first argument `&**x` will be a borrow of the `~int`,
80
88
// but the second argument overwrites that very value! Bad.
81
89
// (This test is borrowck-pure-scope-in-call.rs, btw)
82
- parent : parent
83
- } ;
90
+ parent: parent;
91
+ }
84
92
85
93
/// Returns true if `subscope` is equal to or is lexically nested inside
86
94
/// `superscope` and false otherwise.
@@ -186,12 +194,9 @@ fn parent_id(cx: ctxt, span: span) -> ast::node_id {
186
194
187
195
/// Records the current parent (if any) as the parent of `child_id`.
188
196
fn record_parent ( cx : ctxt , child_id : ast:: node_id ) {
189
- match cx. parent {
190
- none => { /* no-op */ }
191
- some( parent_id) => {
197
+ for cx. parent. each |parent_id| {
192
198
debug ! { "parent of node %d is node %d" , child_id, parent_id} ;
193
199
cx. region_map . insert ( child_id, parent_id) ;
194
- }
195
200
}
196
201
}
197
202
@@ -200,7 +205,7 @@ fn resolve_block(blk: ast::blk, cx: ctxt, visitor: visit::vt<ctxt>) {
200
205
record_parent ( cx, blk. node . id ) ;
201
206
202
207
// Descend.
203
- let new_cx: ctxt = { parent : some( blk. node . id ) with cx} ;
208
+ let new_cx: ctxt = ctxt { parent : some ( blk. node . id ) with cx} ;
204
209
visit:: visit_block ( blk, new_cx, visitor) ;
205
210
}
206
211
@@ -228,6 +233,21 @@ fn resolve_pat(pat: @ast::pat, cx: ctxt, visitor: visit::vt<ctxt>) {
228
233
visit:: visit_pat ( pat, cx, visitor) ;
229
234
}
230
235
236
+ fn resolve_stmt ( stmt : @ast:: stmt , cx : ctxt , visitor : visit:: vt < ctxt > ) {
237
+ match stmt. node {
238
+ ast:: stmt_decl( * ) => {
239
+ visit:: visit_stmt ( stmt, cx, visitor) ;
240
+ }
241
+ ast:: stmt_expr( expr, stmt_id) |
242
+ ast:: stmt_semi( expr, stmt_id) => {
243
+ record_parent ( cx, stmt_id) ;
244
+ let mut expr_cx = cx;
245
+ expr_cx. parent = some ( stmt_id) ;
246
+ visit:: visit_stmt ( stmt, expr_cx, visitor) ;
247
+ }
248
+ }
249
+ }
250
+
231
251
fn resolve_expr ( expr : @ast:: expr , cx : ctxt , visitor : visit:: vt < ctxt > ) {
232
252
record_parent ( cx, expr. id ) ;
233
253
@@ -270,7 +290,7 @@ fn resolve_local(local: @ast::local, cx: ctxt, visitor: visit::vt<ctxt>) {
270
290
271
291
fn resolve_item ( item : @ast:: item , cx : ctxt , visitor : visit:: vt < ctxt > ) {
272
292
// Items create a new outer block scope as far as we're concerned.
273
- let new_cx: ctxt = { parent: none with cx} ;
293
+ let new_cx: ctxt = ctxt { parent : none with cx} ;
274
294
visit:: visit_item ( item, new_cx, visitor) ;
275
295
}
276
296
@@ -282,7 +302,7 @@ fn resolve_fn(fk: visit::fn_kind, decl: ast::fn_decl, body: ast::blk,
282
302
visit:: fk_item_fn( * ) | visit:: fk_method( * ) |
283
303
visit:: fk_ctor( * ) | visit:: fk_dtor( * ) => {
284
304
// Top-level functions are a root scope.
285
- { parent : some( id) with cx}
305
+ ctxt { parent : some ( id) with cx}
286
306
}
287
307
288
308
visit:: fk_anon( * ) | visit:: fk_fn_block( * ) => {
@@ -304,17 +324,18 @@ fn resolve_fn(fk: visit::fn_kind, decl: ast::fn_decl, body: ast::blk,
304
324
305
325
fn resolve_crate ( sess : session , def_map : resolve3:: DefMap ,
306
326
crate : @ast:: crate ) -> region_map {
307
- let cx: ctxt = { sess: sess,
308
- def_map: def_map,
309
- region_map: int_hash ( ) ,
310
- root_exprs: int_hash ( ) ,
311
- parent: none} ;
327
+ let cx: ctxt = ctxt { sess : sess,
328
+ def_map : def_map,
329
+ region_map : int_hash ( ) ,
330
+ root_exprs : int_hash ( ) ,
331
+ parent : none} ;
312
332
let visitor = visit:: mk_vt ( @{
313
333
visit_block: resolve_block,
314
334
visit_item: resolve_item,
315
335
visit_fn: resolve_fn,
316
336
visit_arm: resolve_arm,
317
337
visit_pat: resolve_pat,
338
+ visit_stmt: resolve_stmt,
318
339
visit_expr: resolve_expr,
319
340
visit_local: resolve_local
320
341
with * visit:: default_visitor ( )
0 commit comments