@@ -55,6 +55,11 @@ struct MarkSymbolVisitor<'a> {
55
55
live_symbols : Box < HashSet < ast:: NodeId > > ,
56
56
}
57
57
58
+ #[ deriving( Clone ) ]
59
+ struct MarkSymbolVisitorContext {
60
+ struct_has_extern_repr : bool
61
+ }
62
+
58
63
impl < ' a > MarkSymbolVisitor < ' a > {
59
64
fn new ( tcx : & ' a ty:: ctxt ,
60
65
worklist : Vec < ast:: NodeId > ) -> MarkSymbolVisitor < ' a > {
@@ -170,48 +175,61 @@ impl<'a> MarkSymbolVisitor<'a> {
170
175
}
171
176
172
177
fn visit_node ( & mut self , node : & ast_map:: Node ) {
178
+ let ctxt = MarkSymbolVisitorContext {
179
+ struct_has_extern_repr : false
180
+ } ;
173
181
match * node {
174
182
ast_map:: NodeItem ( item) => {
175
183
match item. node {
176
- ast:: ItemStruct ( struct_def , _ ) => {
184
+ ast:: ItemStruct ( .. ) => {
177
185
let has_extern_repr = item. attrs . iter ( ) . fold ( attr:: ReprAny , |acc, attr| {
178
186
attr:: find_repr_attr ( self . tcx . sess . diagnostic ( ) , attr, acc)
179
187
} ) == attr:: ReprExtern ;
180
- let live_fields = struct_def. fields . iter ( ) . filter ( |f| {
181
- has_extern_repr || match f. node . kind {
182
- ast:: NamedField ( _, ast:: Public ) => true ,
183
- _ => false
184
- }
188
+
189
+ visit:: walk_item ( self , & * item, MarkSymbolVisitorContext {
190
+ struct_has_extern_repr : has_extern_repr,
191
+ ..( ctxt)
185
192
} ) ;
186
- self . live_symbols . extend ( live_fields. map ( |f| f. node . id ) ) ;
187
- visit:: walk_item ( self , & * item, ( ) ) ;
188
193
}
189
194
ast:: ItemFn ( ..)
190
- | ast:: ItemTy ( ..)
191
195
| ast:: ItemEnum ( ..)
196
+ | ast:: ItemTy ( ..)
192
197
| ast:: ItemStatic ( ..) => {
193
- visit:: walk_item ( self , & * item, ( ) ) ;
198
+ visit:: walk_item ( self , & * item, ctxt ) ;
194
199
}
195
200
_ => ( )
196
201
}
197
202
}
198
203
ast_map:: NodeTraitMethod ( trait_method) => {
199
- visit:: walk_trait_method ( self , & * trait_method, ( ) ) ;
204
+ visit:: walk_trait_method ( self , & * trait_method, ctxt ) ;
200
205
}
201
206
ast_map:: NodeMethod ( method) => {
202
- visit:: walk_block ( self , & * method. body , ( ) ) ;
207
+ visit:: walk_block ( self , & * method. body , ctxt ) ;
203
208
}
204
209
ast_map:: NodeForeignItem ( foreign_item) => {
205
- visit:: walk_foreign_item ( self , & * foreign_item, ( ) ) ;
210
+ visit:: walk_foreign_item ( self , & * foreign_item, ctxt ) ;
206
211
}
207
212
_ => ( )
208
213
}
209
214
}
210
215
}
211
216
212
- impl < ' a > Visitor < ( ) > for MarkSymbolVisitor < ' a > {
217
+ impl < ' a > Visitor < MarkSymbolVisitorContext > for MarkSymbolVisitor < ' a > {
218
+
219
+ fn visit_struct_def ( & mut self , def : & ast:: StructDef , _: ast:: Ident , _: & ast:: Generics ,
220
+ _: ast:: NodeId , ctxt : MarkSymbolVisitorContext ) {
221
+ let live_fields = def. fields . iter ( ) . filter ( |f| {
222
+ ctxt. struct_has_extern_repr || match f. node . kind {
223
+ ast:: NamedField ( _, ast:: Public ) => true ,
224
+ _ => false
225
+ }
226
+ } ) ;
227
+ self . live_symbols . extend ( live_fields. map ( |f| f. node . id ) ) ;
228
+
229
+ visit:: walk_struct_def ( self , def, ctxt) ;
230
+ }
213
231
214
- fn visit_expr ( & mut self , expr : & ast:: Expr , _ : ( ) ) {
232
+ fn visit_expr ( & mut self , expr : & ast:: Expr , ctxt : MarkSymbolVisitorContext ) {
215
233
match expr. node {
216
234
ast:: ExprMethodCall ( ..) => {
217
235
self . lookup_and_handle_method ( expr. id , expr. span ) ;
@@ -222,26 +240,26 @@ impl<'a> Visitor<()> for MarkSymbolVisitor<'a> {
222
240
_ => ( )
223
241
}
224
242
225
- visit:: walk_expr ( self , expr, ( ) )
243
+ visit:: walk_expr ( self , expr, ctxt ) ;
226
244
}
227
245
228
- fn visit_pat ( & mut self , pat : & ast:: Pat , _ : ( ) ) {
246
+ fn visit_pat ( & mut self , pat : & ast:: Pat , ctxt : MarkSymbolVisitorContext ) {
229
247
match pat. node {
230
248
ast:: PatStruct ( _, ref fields, _) => {
231
249
self . handle_field_pattern_match ( pat, fields. as_slice ( ) ) ;
232
250
}
233
251
_ => ( )
234
252
}
235
253
236
- visit:: walk_pat ( self , pat, ( ) )
254
+ visit:: walk_pat ( self , pat, ctxt ) ;
237
255
}
238
256
239
- fn visit_path ( & mut self , path : & ast:: Path , id : ast:: NodeId , _ : ( ) ) {
257
+ fn visit_path ( & mut self , path : & ast:: Path , id : ast:: NodeId , ctxt : MarkSymbolVisitorContext ) {
240
258
self . lookup_and_handle_definition ( & id) ;
241
- visit:: walk_path ( self , path, ( ) ) ;
259
+ visit:: walk_path ( self , path, ctxt ) ;
242
260
}
243
261
244
- fn visit_item ( & mut self , _: & ast:: Item , _: ( ) ) {
262
+ fn visit_item ( & mut self , _: & ast:: Item , _: MarkSymbolVisitorContext ) {
245
263
// Do not recurse into items. These items will be added to the
246
264
// worklist and recursed into manually if necessary.
247
265
}
0 commit comments