@@ -26,8 +26,8 @@ export def_lookup;
26
26
// Throughout the compiler, variables are generally dealt with using the
27
27
// node_ids of the reference sites and not the def_id of the definition
28
28
// site. Thus we store a set are the definitions along with a vec of one
29
- // referencing node_id per free variable. The set is useful for testing
30
- // membership, the list of referencing sites is what you want for most
29
+ // "canonical" referencing node_id per free variable. The set is useful for
30
+ // testing membership, the list of referencing sites is what you want for most
31
31
// other things.
32
32
type freevar_set = hashset[ ast:: node_id ] ;
33
33
type freevar_info = { defs : freevar_set , refs : @ast:: node_id [ ] } ;
@@ -41,67 +41,61 @@ type freevar_map = hashmap[ast::node_id, freevar_info];
41
41
fn collect_freevars ( def_map : & resolve:: def_map , sess : & session:: session ,
42
42
walker : & fn ( & visit:: vt[ ( ) ] ) ,
43
43
initial_decls : ast:: node_id [ ] ) -> freevar_info {
44
- type env =
45
- @{ mutable refs: ast:: node_id [ ] ,
46
- decls: hashset[ ast:: node_id] ,
47
- def_map: resolve:: def_map,
48
- sess: session:: session} ;
44
+ let decls = new_int_hash ( ) ;
45
+ for decl: ast:: node_id in initial_decls { set_add ( decls, decl) ; }
46
+ let refs = @mutable ~[ ] ;
49
47
50
- fn walk_fn ( e : env , f : & ast:: _fn , tps : & ast:: ty_param [ ] , sp : & span ,
51
- i : & ast:: fn_ident , nid : ast:: node_id ) {
52
- for a: ast:: arg in f. decl . inputs { e . decls . insert ( a. id , ( ) ) ; }
53
- }
54
- fn walk_expr ( e : env , expr : & @ast:: expr ) {
48
+ let walk_fn = lambda ( f: & ast:: _fn, tps: & ast:: ty_param[ ] , sp: & span,
49
+ i: & ast:: fn_ident, nid: ast:: node_id) {
50
+ for a: ast:: arg in f. decl . inputs { set_add ( decls , a. id ) ; }
51
+ } ;
52
+ let walk_expr = lambda ( expr: & @ast:: expr) {
55
53
alt expr. node {
56
54
ast:: expr_path ( path) {
57
- if !e . def_map . contains_key ( expr. id ) {
58
- e . sess . span_fatal ( expr. span ,
59
- "internal error in collect_freevars" ) ;
55
+ if !def_map. contains_key ( expr. id ) {
56
+ sess. span_fatal ( expr. span ,
57
+ "internal error in collect_freevars" ) ;
60
58
}
61
- alt e . def_map . get ( expr. id ) {
62
- ast:: def_arg ( did) { e . refs += ~[ expr. id ] ; }
63
- ast:: def_local ( did) { e . refs += ~[ expr. id ] ; }
64
- ast:: def_binding ( did) { e . refs += ~[ expr. id ] ; }
59
+ alt def_map. get ( expr. id ) {
60
+ ast:: def_arg ( did) { * refs += ~[ expr. id ] ; }
61
+ ast:: def_local ( did) { * refs += ~[ expr. id ] ; }
62
+ ast:: def_binding ( did) { * refs += ~[ expr. id ] ; }
65
63
_ { /* no-op */ }
66
64
}
67
65
}
68
66
_ { }
69
67
}
70
- }
71
- fn walk_local ( e : env , local : & @ast:: local ) {
68
+ } ;
69
+ let walk_local = lambda ( local: & @ast:: local) {
72
70
for each b: @ast:: pat in ast:: pat_bindings ( local. node . pat ) {
73
- set_add ( e . decls , b. id ) ;
71
+ set_add ( decls, b. id ) ;
74
72
}
75
- }
76
- fn walk_pat ( e : env , p : & @ast:: pat ) {
77
- alt p. node { ast:: pat_bind ( _) { set_add ( e. decls , p. id ) ; } _ { } }
78
- }
79
- let decls: hashset[ ast:: node_id ] = new_int_hash ( ) ;
80
- for decl: ast:: node_id in initial_decls { set_add ( decls, decl) ; }
73
+ } ;
74
+ let walk_pat = lambda ( p: & @ast:: pat) {
75
+ alt p. node { ast:: pat_bind ( _) { set_add ( decls, p. id ) ; } _ { } }
76
+ } ;
81
77
82
- let e: env =
83
- @{ mutable refs: ~[ ] , decls: decls, def_map: def_map, sess: sess} ;
84
78
walker ( visit:: mk_simple_visitor
85
- ( @{ visit_local: bind walk_local ( e , _ ) ,
86
- visit_pat: bind walk_pat ( e , _ ) ,
87
- visit_expr: bind walk_expr ( e , _ ) ,
88
- visit_fn: bind walk_fn ( e , _ , _ , _ , _ , _ )
79
+ ( @{ visit_local: walk_local,
80
+ visit_pat: walk_pat,
81
+ visit_expr: walk_expr,
82
+ visit_fn: walk_fn
89
83
with * visit:: default_simple_visitor ( ) } ) ) ;
90
84
91
85
// Calculate (refs - decls). This is the set of captured upvars.
92
86
// We build a vec of the node ids of the uses and a set of the
93
87
// node ids of the definitions.
94
- let refs = ~[ ] ;
88
+ let canonical_refs = ~[ ] ;
95
89
let defs = new_int_hash ( ) ;
96
- for ref_id_: ast:: node_id in e . refs {
90
+ for ref_id_: ast:: node_id in * refs {
97
91
let ref_id = ref_id_;
98
92
let def_id = ast:: def_id_of_def ( def_map. get ( ref_id) ) . node ;
99
93
if !decls. contains_key ( def_id) && !defs. contains_key ( def_id) {
100
- refs += ~[ ref_id] ;
94
+ canonical_refs += ~[ ref_id] ;
101
95
set_add ( defs, def_id) ;
102
96
}
103
97
}
104
- ret { defs : defs, refs : @refs } ;
98
+ ret { defs : defs, refs : @canonical_refs } ;
105
99
}
106
100
107
101
// Build a map from every function and for-each body to a set of the
@@ -111,46 +105,38 @@ fn collect_freevars(def_map: &resolve::def_map, sess: &session::session,
111
105
// one pass. This could be improved upon if it turns out to matter.
112
106
fn annotate_freevars ( sess : & session:: session , def_map : & resolve:: def_map ,
113
107
crate : & @ast:: crate ) -> freevar_map {
114
- type env =
115
- { freevars : freevar_map ,
116
- def_map : resolve:: def_map ,
117
- sess : session:: session } ;
108
+ let freevars = new_int_hash ( ) ;
118
109
119
- fn walk_fn ( e : env , f : & ast:: _fn , tps : & ast:: ty_param [ ] , sp : & span ,
120
- i : & ast:: fn_ident , nid : ast:: node_id ) {
121
- fn start_walk ( f : & ast:: _fn , tps : & ast:: ty_param [ ] , sp : & span ,
122
- i : & ast:: fn_ident , nid : ast:: node_id ,
123
- v : & visit:: vt [ ( ) ] ) {
110
+ let walk_fn = lambda ( f: & ast:: _fn, tps: & ast:: ty_param[ ] , sp: & span,
111
+ i: & ast:: fn_ident, nid: ast:: node_id) {
112
+ let start_walk = lambda ( v: & visit:: vt[ ( ) ] ) {
124
113
v. visit_fn ( f, tps, sp, i, nid, ( ) , v) ;
125
- }
126
- let walker = bind start_walk ( f, tps, sp, i, nid, _) ;
127
- let vars = collect_freevars ( e. def_map , e. sess , walker, ~[ ] ) ;
128
- e. freevars . insert ( nid, vars) ;
129
- }
130
- fn walk_expr ( e : env , expr : & @ast:: expr ) {
114
+ } ;
115
+ let vars = collect_freevars ( def_map, sess, start_walk, ~[ ] ) ;
116
+ freevars. insert ( nid, vars) ;
117
+ } ;
118
+ let walk_expr = lambda ( expr: & @ast:: expr) {
131
119
alt expr. node {
132
120
ast:: expr_for_each ( local, _, body) {
133
- fn start_walk ( b : & ast :: blk , v : & visit:: vt [ ( ) ] ) {
134
- v. visit_block ( b , ( ) , v) ;
135
- }
121
+ let start_walk = lambda ( v: & visit:: vt[ ( ) ] ) {
122
+ v. visit_block ( body , ( ) , v) ;
123
+ } ;
136
124
let bound = ast:: pat_binding_ids ( local. node . pat ) ;
137
125
let vars =
138
- collect_freevars ( e. def_map , e. sess , bind start_walk ( body, _) ,
139
- bound) ;
140
- e. freevars . insert ( body. node . id , vars) ;
126
+ collect_freevars ( def_map, sess, start_walk, bound) ;
127
+ freevars. insert ( body. node . id , vars) ;
141
128
}
142
129
_ { }
143
130
}
144
- }
131
+ } ;
145
132
146
- let e: env = { freevars: new_int_hash ( ) , def_map: def_map, sess: sess} ;
147
133
let visitor =
148
- visit:: mk_simple_visitor ( @{ visit_fn: bind walk_fn ( e , _ , _ , _ , _ , _ ) ,
149
- visit_expr: bind walk_expr ( e , _ )
134
+ visit:: mk_simple_visitor ( @{ visit_fn: walk_fn,
135
+ visit_expr: walk_expr
150
136
with * visit:: default_simple_visitor ( ) } ) ;
151
137
visit:: visit_crate ( * crate , ( ) , visitor) ;
152
138
153
- ret e . freevars ;
139
+ ret freevars;
154
140
}
155
141
156
142
fn get_freevar_info ( tcx : & ty:: ctxt , fid : ast:: node_id ) -> freevar_info {
0 commit comments