@@ -24,8 +24,8 @@ use syntax::ast_map;
24
24
use syntax:: ast_util:: def_id_of_def;
25
25
use syntax:: attr;
26
26
use syntax:: parse:: token;
27
- use syntax:: oldvisit :: Visitor ;
28
- use syntax:: oldvisit ;
27
+ use syntax:: visit :: Visitor ;
28
+ use syntax:: visit ;
29
29
30
30
// Returns true if the given set of attributes contains the `#[inline]`
31
31
// attribute.
@@ -94,48 +94,37 @@ struct ReachableContext {
94
94
worklist : @mut ~[ NodeId ] ,
95
95
}
96
96
97
- impl ReachableContext {
98
- // Creates a new reachability computation context.
99
- fn new ( tcx : ty:: ctxt , method_map : typeck:: method_map )
100
- -> ReachableContext {
101
- ReachableContext {
102
- tcx : tcx,
103
- method_map : method_map,
104
- reachable_symbols : @mut HashSet :: new ( ) ,
105
- worklist : @mut ~[ ] ,
106
- }
107
- }
97
+ struct ReachableVisitor {
98
+ reachable_symbols : @mut HashSet < NodeId > ,
99
+ worklist : @mut ~[ NodeId ] ,
100
+ }
101
+
102
+ impl Visitor < PrivacyContext > for ReachableVisitor {
103
+
104
+ fn visit_item ( & mut self , item: @item, privacy_context : PrivacyContext ) {
108
105
109
- // Step 1: Mark all public symbols, and add all public symbols that might
110
- // be inlined to a worklist.
111
- fn mark_public_symbols ( & self , crate : @Crate ) {
112
- let reachable_symbols = self . reachable_symbols ;
113
- let worklist = self . worklist ;
114
- let visitor = oldvisit:: mk_vt ( @Visitor {
115
- visit_item : |item, ( privacy_context, visitor) :
116
- ( PrivacyContext , oldvisit:: vt < PrivacyContext > ) | {
117
106
match item. node {
118
107
item_fn( * ) => {
119
108
if privacy_context == PublicContext {
120
- reachable_symbols. insert ( item. id ) ;
109
+ self . reachable_symbols . insert ( item. id ) ;
121
110
}
122
111
if item_might_be_inlined ( item) {
123
- worklist. push ( item. id )
112
+ self . worklist . push ( item. id )
124
113
}
125
114
}
126
115
item_struct( ref struct_def, _) => {
127
116
match struct_def. ctor_id {
128
117
Some ( ctor_id) if
129
118
privacy_context == PublicContext => {
130
- reachable_symbols. insert ( ctor_id) ;
119
+ self . reachable_symbols . insert ( ctor_id) ;
131
120
}
132
121
Some ( _) | None => { }
133
122
}
134
123
}
135
124
item_enum( ref enum_def, _) => {
136
125
if privacy_context == PublicContext {
137
126
for variant in enum_def. variants . iter ( ) {
138
- reachable_symbols. insert ( variant. node . id ) ;
127
+ self . reachable_symbols . insert ( variant. node . id ) ;
139
128
}
140
129
}
141
130
}
@@ -155,7 +144,7 @@ impl ReachableContext {
155
144
// Mark all public methods as reachable.
156
145
for & method in methods. iter ( ) {
157
146
if should_be_considered_public ( method) {
158
- reachable_symbols. insert ( method. id ) ;
147
+ self . reachable_symbols . insert ( method. id ) ;
159
148
}
160
149
}
161
150
@@ -164,7 +153,7 @@ impl ReachableContext {
164
153
// symbols to the worklist.
165
154
for & method in methods. iter ( ) {
166
155
if should_be_considered_public ( method) {
167
- worklist. push ( method. id )
156
+ self . worklist . push ( method. id )
168
157
}
169
158
}
170
159
} else {
@@ -176,7 +165,7 @@ impl ReachableContext {
176
165
if generics_require_inlining ( generics) ||
177
166
attributes_specify_inlining ( * attrs) ||
178
167
should_be_considered_public ( * method) {
179
- worklist. push ( method. id )
168
+ self . worklist . push ( method. id )
180
169
}
181
170
}
182
171
}
@@ -187,8 +176,8 @@ impl ReachableContext {
187
176
for trait_method in trait_methods. iter ( ) {
188
177
match * trait_method {
189
178
provided( method) => {
190
- reachable_symbols. insert ( method. id ) ;
191
- worklist. push ( method. id )
179
+ self . reachable_symbols . insert ( method. id ) ;
180
+ self . worklist . push ( method. id )
192
181
}
193
182
required( _) => { }
194
183
}
@@ -199,15 +188,97 @@ impl ReachableContext {
199
188
}
200
189
201
190
if item. vis == public && privacy_context == PublicContext {
202
- oldvisit :: visit_item ( item , ( PublicContext , visitor ) )
191
+ visit :: walk_item ( self , item , PublicContext )
203
192
} else {
204
- oldvisit :: visit_item ( item , ( PrivateContext , visitor ) )
193
+ visit :: walk_item ( self , item , PrivateContext )
205
194
}
206
- } ,
207
- .. * oldvisit:: default_visitor ( )
208
- } ) ;
195
+ }
196
+
197
+ }
198
+
199
+ struct MarkSymbolVisitor {
200
+ worklist : @mut ~[ NodeId ] ,
201
+ method_map : typeck:: method_map ,
202
+ tcx : ty:: ctxt ,
203
+ reachable_symbols : @mut HashSet < NodeId > ,
204
+ }
205
+
206
+ impl Visitor < ( ) > for MarkSymbolVisitor {
209
207
210
- oldvisit:: visit_crate ( crate , ( PublicContext , visitor) )
208
+ fn visit_expr ( & mut self , expr : @expr, _: ( ) ) {
209
+
210
+ match expr. node {
211
+ expr_path( _) => {
212
+ let def = match self . tcx . def_map . find ( & expr. id ) {
213
+ Some ( & def) => def,
214
+ None => {
215
+ self . tcx . sess . span_bug ( expr. span ,
216
+ "def ID not in def map?!" )
217
+ }
218
+ } ;
219
+
220
+ let def_id = def_id_of_def ( def) ;
221
+ if ReachableContext ::
222
+ def_id_represents_local_inlined_item ( self . tcx ,
223
+ def_id) {
224
+ self . worklist . push ( def_id. node )
225
+ }
226
+ self . reachable_symbols . insert ( def_id. node ) ;
227
+ }
228
+ expr_method_call( * ) => {
229
+ match self . method_map . find ( & expr. id ) {
230
+ Some ( & typeck:: method_map_entry {
231
+ origin : typeck:: method_static( def_id) ,
232
+ _
233
+ } ) => {
234
+ if ReachableContext ::
235
+ def_id_represents_local_inlined_item (
236
+ self . tcx ,
237
+ def_id) {
238
+ self . worklist . push ( def_id. node )
239
+ }
240
+ self . reachable_symbols . insert ( def_id. node ) ;
241
+ }
242
+ Some ( _) => { }
243
+ None => {
244
+ self . tcx . sess . span_bug ( expr. span ,
245
+ "method call expression \
246
+ not in method map?!")
247
+ }
248
+ }
249
+ }
250
+ _ => { }
251
+ }
252
+
253
+ visit:: walk_expr ( self , expr, ( ) )
254
+ }
255
+ }
256
+
257
+ impl ReachableContext {
258
+ // Creates a new reachability computation context.
259
+ fn new ( tcx : ty:: ctxt , method_map : typeck:: method_map )
260
+ -> ReachableContext {
261
+ ReachableContext {
262
+ tcx : tcx,
263
+ method_map : method_map,
264
+ reachable_symbols : @mut HashSet :: new ( ) ,
265
+ worklist : @mut ~[ ] ,
266
+ }
267
+ }
268
+
269
+ // Step 1: Mark all public symbols, and add all public symbols that might
270
+ // be inlined to a worklist.
271
+ fn mark_public_symbols ( & self , crate : @Crate ) {
272
+ let reachable_symbols = self . reachable_symbols ;
273
+ let worklist = self . worklist ;
274
+
275
+ let mut visitor = ReachableVisitor {
276
+ reachable_symbols : reachable_symbols,
277
+ worklist : worklist,
278
+ } ;
279
+
280
+
281
+ visit:: walk_crate ( & mut visitor, crate , PublicContext ) ;
211
282
}
212
283
213
284
// Returns true if the given def ID represents a local item that is
@@ -269,63 +340,21 @@ impl ReachableContext {
269
340
}
270
341
271
342
// Helper function to set up a visitor for `propagate()` below.
272
- fn init_visitor ( & self ) -> oldvisit :: vt < ( ) > {
343
+ fn init_visitor ( & self ) -> MarkSymbolVisitor {
273
344
let ( worklist, method_map) = ( self . worklist , self . method_map ) ;
274
345
let ( tcx, reachable_symbols) = ( self . tcx , self . reachable_symbols ) ;
275
- oldvisit:: mk_vt ( @oldvisit:: Visitor {
276
- visit_expr : |expr, ( _, visitor) | {
277
- match expr. node {
278
- expr_path( _) => {
279
- let def = match tcx. def_map . find ( & expr. id ) {
280
- Some ( & def) => def,
281
- None => {
282
- tcx. sess . span_bug ( expr. span ,
283
- "def ID not in def map?!" )
284
- }
285
- } ;
286
-
287
- let def_id = def_id_of_def ( def) ;
288
- if ReachableContext ::
289
- def_id_represents_local_inlined_item ( tcx,
290
- def_id) {
291
- worklist. push ( def_id. node )
292
- }
293
- reachable_symbols. insert ( def_id. node ) ;
294
- }
295
- expr_method_call( * ) => {
296
- match method_map. find ( & expr. id ) {
297
- Some ( & typeck:: method_map_entry {
298
- origin : typeck:: method_static( def_id) ,
299
- _
300
- } ) => {
301
- if ReachableContext ::
302
- def_id_represents_local_inlined_item (
303
- tcx,
304
- def_id) {
305
- worklist. push ( def_id. node )
306
- }
307
- reachable_symbols. insert ( def_id. node ) ;
308
- }
309
- Some ( _) => { }
310
- None => {
311
- tcx. sess . span_bug ( expr. span ,
312
- "method call expression \
313
- not in method map?!")
314
- }
315
- }
316
- }
317
- _ => { }
318
- }
319
346
320
- oldvisit:: visit_expr ( expr, ( ( ) , visitor) )
321
- } ,
322
- ..* oldvisit:: default_visitor ( )
323
- } )
347
+ MarkSymbolVisitor {
348
+ worklist : worklist,
349
+ method_map : method_map,
350
+ tcx : tcx,
351
+ reachable_symbols : reachable_symbols,
352
+ }
324
353
}
325
354
326
355
// Step 2: Mark all symbols that the symbols on the worklist touch.
327
356
fn propagate ( & self ) {
328
- let visitor = self . init_visitor ( ) ;
357
+ let mut visitor = self . init_visitor ( ) ;
329
358
let mut scanned = HashSet :: new ( ) ;
330
359
while self . worklist . len ( ) > 0 {
331
360
let search_item = self . worklist . pop ( ) ;
@@ -342,7 +371,7 @@ impl ReachableContext {
342
371
Some ( & ast_map:: node_item( item, _) ) => {
343
372
match item. node {
344
373
item_fn( _, _, _, _, ref search_block) => {
345
- oldvisit :: visit_block ( search_block , ( ( ) , visitor ) )
374
+ visit :: walk_block ( & mut visitor , search_block , ( ) )
346
375
}
347
376
_ => {
348
377
self . tcx . sess . span_bug ( item. span ,
@@ -359,12 +388,12 @@ impl ReachableContext {
359
388
worklist?!")
360
389
}
361
390
provided( ref method) => {
362
- oldvisit :: visit_block ( & method. body , ( ( ) , visitor ) )
391
+ visit :: walk_block ( & mut visitor , & method. body , ( ) )
363
392
}
364
393
}
365
394
}
366
395
Some ( & ast_map:: node_method( ref method, _, _) ) => {
367
- oldvisit :: visit_block ( & method. body , ( ( ) , visitor ) )
396
+ visit :: walk_block ( & mut visitor , & method. body , ( ) )
368
397
}
369
398
Some ( _) => {
370
399
let ident_interner = token:: get_ident_interner ( ) ;
0 commit comments