Skip to content

Commit 69e822d

Browse files
committed
port reachable.rs from oldvisit to <V:Visitor> trait.
1 parent 18be88f commit 69e822d

File tree

1 file changed

+118
-89
lines changed

1 file changed

+118
-89
lines changed

src/librustc/middle/reachable.rs

Lines changed: 118 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ use syntax::ast_map;
2424
use syntax::ast_util::def_id_of_def;
2525
use syntax::attr;
2626
use syntax::parse::token;
27-
use syntax::oldvisit::Visitor;
28-
use syntax::oldvisit;
27+
use syntax::visit::Visitor;
28+
use syntax::visit;
2929

3030
// Returns true if the given set of attributes contains the `#[inline]`
3131
// attribute.
@@ -94,48 +94,37 @@ struct ReachableContext {
9494
worklist: @mut ~[NodeId],
9595
}
9696

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) {
108105

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>)| {
117106
match item.node {
118107
item_fn(*) => {
119108
if privacy_context == PublicContext {
120-
reachable_symbols.insert(item.id);
109+
self.reachable_symbols.insert(item.id);
121110
}
122111
if item_might_be_inlined(item) {
123-
worklist.push(item.id)
112+
self.worklist.push(item.id)
124113
}
125114
}
126115
item_struct(ref struct_def, _) => {
127116
match struct_def.ctor_id {
128117
Some(ctor_id) if
129118
privacy_context == PublicContext => {
130-
reachable_symbols.insert(ctor_id);
119+
self.reachable_symbols.insert(ctor_id);
131120
}
132121
Some(_) | None => {}
133122
}
134123
}
135124
item_enum(ref enum_def, _) => {
136125
if privacy_context == PublicContext {
137126
for variant in enum_def.variants.iter() {
138-
reachable_symbols.insert(variant.node.id);
127+
self.reachable_symbols.insert(variant.node.id);
139128
}
140129
}
141130
}
@@ -155,7 +144,7 @@ impl ReachableContext {
155144
// Mark all public methods as reachable.
156145
for &method in methods.iter() {
157146
if should_be_considered_public(method) {
158-
reachable_symbols.insert(method.id);
147+
self.reachable_symbols.insert(method.id);
159148
}
160149
}
161150

@@ -164,7 +153,7 @@ impl ReachableContext {
164153
// symbols to the worklist.
165154
for &method in methods.iter() {
166155
if should_be_considered_public(method) {
167-
worklist.push(method.id)
156+
self.worklist.push(method.id)
168157
}
169158
}
170159
} else {
@@ -176,7 +165,7 @@ impl ReachableContext {
176165
if generics_require_inlining(generics) ||
177166
attributes_specify_inlining(*attrs) ||
178167
should_be_considered_public(*method) {
179-
worklist.push(method.id)
168+
self.worklist.push(method.id)
180169
}
181170
}
182171
}
@@ -187,8 +176,8 @@ impl ReachableContext {
187176
for trait_method in trait_methods.iter() {
188177
match *trait_method {
189178
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)
192181
}
193182
required(_) => {}
194183
}
@@ -199,15 +188,97 @@ impl ReachableContext {
199188
}
200189

201190
if item.vis == public && privacy_context == PublicContext {
202-
oldvisit::visit_item(item, (PublicContext, visitor))
191+
visit::walk_item(self, item, PublicContext)
203192
} else {
204-
oldvisit::visit_item(item, (PrivateContext, visitor))
193+
visit::walk_item(self, item, PrivateContext)
205194
}
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 {
209207

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);
211282
}
212283

213284
// Returns true if the given def ID represents a local item that is
@@ -269,63 +340,21 @@ impl ReachableContext {
269340
}
270341

271342
// Helper function to set up a visitor for `propagate()` below.
272-
fn init_visitor(&self) -> oldvisit::vt<()> {
343+
fn init_visitor(&self) -> MarkSymbolVisitor {
273344
let (worklist, method_map) = (self.worklist, self.method_map);
274345
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-
}
319346

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+
}
324353
}
325354

326355
// Step 2: Mark all symbols that the symbols on the worklist touch.
327356
fn propagate(&self) {
328-
let visitor = self.init_visitor();
357+
let mut visitor = self.init_visitor();
329358
let mut scanned = HashSet::new();
330359
while self.worklist.len() > 0 {
331360
let search_item = self.worklist.pop();
@@ -342,7 +371,7 @@ impl ReachableContext {
342371
Some(&ast_map::node_item(item, _)) => {
343372
match item.node {
344373
item_fn(_, _, _, _, ref search_block) => {
345-
oldvisit::visit_block(search_block, ((), visitor))
374+
visit::walk_block(&mut visitor, search_block, ())
346375
}
347376
_ => {
348377
self.tcx.sess.span_bug(item.span,
@@ -359,12 +388,12 @@ impl ReachableContext {
359388
worklist?!")
360389
}
361390
provided(ref method) => {
362-
oldvisit::visit_block(&method.body, ((), visitor))
391+
visit::walk_block(&mut visitor, &method.body, ())
363392
}
364393
}
365394
}
366395
Some(&ast_map::node_method(ref method, _, _)) => {
367-
oldvisit::visit_block(&method.body, ((), visitor))
396+
visit::walk_block(&mut visitor, &method.body, ())
368397
}
369398
Some(_) => {
370399
let ident_interner = token::get_ident_interner();

0 commit comments

Comments
 (0)