Skip to content

Commit eeb37b7

Browse files
committed
De-@ reachable.
1 parent 6c42ef3 commit eeb37b7

File tree

5 files changed

+69
-148
lines changed

5 files changed

+69
-148
lines changed

src/librustc/driver/driver.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ pub struct CrateAnalysis {
276276
public_items: middle::privacy::PublicItems,
277277
ty_cx: ty::ctxt,
278278
maps: astencode::Maps,
279-
reachable: @RefCell<NodeSet>,
279+
reachable: NodeSet,
280280
}
281281

282282
/// Run the resolution, typechecking, region checking and other
@@ -377,16 +377,13 @@ pub fn phase_3_run_analysis_passes(sess: Session,
377377
time(time_passes, "reachability checking", (), |_|
378378
reachable::find_reachable(&ty_cx, method_map, &exported_items));
379379

380-
{
381-
let reachable_map = reachable_map.borrow();
382-
time(time_passes, "death checking", (), |_| {
383-
middle::dead::check_crate(&ty_cx,
384-
method_map,
385-
&exported_items,
386-
reachable_map.get(),
387-
krate)
388-
});
389-
}
380+
time(time_passes, "death checking", (), |_| {
381+
middle::dead::check_crate(&ty_cx,
382+
method_map,
383+
&exported_items,
384+
&reachable_map,
385+
krate)
386+
});
390387

391388
time(time_passes, "lint checking", (), |_|
392389
lint::check_crate(&ty_cx, method_map, &exported_items, krate));

src/librustc/middle/reachable.rs

Lines changed: 41 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ use middle::typeck;
2020
use middle::privacy;
2121
use util::nodemap::NodeSet;
2222

23-
use std::cell::RefCell;
2423
use std::vec_ng::Vec;
2524
use collections::HashSet;
2625
use syntax::ast;
@@ -90,27 +89,19 @@ struct ReachableContext<'a> {
9089
// methods they've been resolved to.
9190
method_map: typeck::MethodMap,
9291
// The set of items which must be exported in the linkage sense.
93-
reachable_symbols: @RefCell<NodeSet>,
92+
reachable_symbols: NodeSet,
9493
// A worklist of item IDs. Each item ID in this worklist will be inlined
9594
// and will be scanned for further references.
96-
worklist: @RefCell<Vec<ast::NodeId> >,
95+
worklist: Vec<ast::NodeId>,
9796
}
9897

99-
struct MarkSymbolVisitor<'a> {
100-
worklist: @RefCell<Vec<ast::NodeId>>,
101-
method_map: typeck::MethodMap,
102-
tcx: &'a ty::ctxt,
103-
reachable_symbols: @RefCell<NodeSet>,
104-
}
105-
106-
impl<'a> Visitor<()> for MarkSymbolVisitor<'a> {
98+
impl<'a> Visitor<()> for ReachableContext<'a> {
10799

108100
fn visit_expr(&mut self, expr: &ast::Expr, _: ()) {
109101

110102
match expr.node {
111103
ast::ExprPath(_) => {
112-
let def_map = self.tcx.def_map.borrow();
113-
let def = match def_map.get().find(&expr.id) {
104+
let def = match self.tcx.def_map.borrow().get().find(&expr.id) {
114105
Some(&def) => def,
115106
None => {
116107
self.tcx.sess.span_bug(expr.span,
@@ -120,29 +111,22 @@ impl<'a> Visitor<()> for MarkSymbolVisitor<'a> {
120111

121112
let def_id = def_id_of_def(def);
122113
if is_local(def_id) {
123-
if ReachableContext::
124-
def_id_represents_local_inlined_item(self.tcx, def_id) {
125-
{
126-
let mut worklist = self.worklist.borrow_mut();
127-
worklist.get().push(def_id.node)
128-
}
114+
if self.def_id_represents_local_inlined_item(def_id) {
115+
self.worklist.push(def_id.node)
129116
} else {
130117
match def {
131118
// If this path leads to a static, then we may have
132119
// to do some work to figure out whether the static
133120
// is indeed reachable (address_insignificant
134121
// statics are *never* reachable).
135122
ast::DefStatic(..) => {
136-
let mut worklist = self.worklist.borrow_mut();
137-
worklist.get().push(def_id.node);
123+
self.worklist.push(def_id.node);
138124
}
139125

140126
// If this wasn't a static, then this destination is
141127
// surely reachable.
142128
_ => {
143-
let mut reachable_symbols =
144-
self.reachable_symbols.borrow_mut();
145-
reachable_symbols.get().insert(def_id.node);
129+
self.reachable_symbols.insert(def_id.node);
146130
}
147131
}
148132
}
@@ -153,13 +137,10 @@ impl<'a> Visitor<()> for MarkSymbolVisitor<'a> {
153137
match self.method_map.borrow().get().get(&method_call).origin {
154138
typeck::MethodStatic(def_id) => {
155139
if is_local(def_id) {
156-
if ReachableContext::
157-
def_id_represents_local_inlined_item(
158-
self.tcx,
159-
def_id) {
160-
self.worklist.borrow_mut().get().push(def_id.node)
140+
if self.def_id_represents_local_inlined_item(def_id) {
141+
self.worklist.push(def_id.node)
161142
}
162-
self.reachable_symbols.borrow_mut().get().insert(def_id.node);
143+
self.reachable_symbols.insert(def_id.node);
163144
}
164145
}
165146
_ => {}
@@ -183,21 +164,20 @@ impl<'a> ReachableContext<'a> {
183164
ReachableContext {
184165
tcx: tcx,
185166
method_map: method_map,
186-
reachable_symbols: @RefCell::new(NodeSet::new()),
187-
worklist: @RefCell::new(Vec::new()),
167+
reachable_symbols: NodeSet::new(),
168+
worklist: Vec::new(),
188169
}
189170
}
190171

191172
// Returns true if the given def ID represents a local item that is
192173
// eligible for inlining and false otherwise.
193-
fn def_id_represents_local_inlined_item(tcx: &ty::ctxt, def_id: ast::DefId)
194-
-> bool {
174+
fn def_id_represents_local_inlined_item(&self, def_id: ast::DefId) -> bool {
195175
if def_id.krate != ast::LOCAL_CRATE {
196176
return false
197177
}
198178

199179
let node_id = def_id.node;
200-
match tcx.map.find(node_id) {
180+
match self.tcx.map.find(node_id) {
201181
Some(ast_map::NodeItem(item)) => {
202182
match item.node {
203183
ast::ItemFn(..) => item_might_be_inlined(item),
@@ -215,11 +195,11 @@ impl<'a> ReachableContext<'a> {
215195
attributes_specify_inlining(method.attrs.as_slice()) {
216196
true
217197
} else {
218-
let impl_did = tcx.map.get_parent_did(node_id);
198+
let impl_did = self.tcx.map.get_parent_did(node_id);
219199
// Check the impl. If the generics on the self type of the
220200
// impl require inlining, this method does too.
221201
assert!(impl_did.krate == ast::LOCAL_CRATE);
222-
match tcx.map.expect_item(impl_did.node).node {
202+
match self.tcx.map.expect_item(impl_did.node).node {
223203
ast::ItemImpl(ref generics, _, _, _) => {
224204
generics_require_inlining(generics)
225205
}
@@ -232,40 +212,21 @@ impl<'a> ReachableContext<'a> {
232212
}
233213
}
234214

235-
// Helper function to set up a visitor for `propagate()` below.
236-
fn init_visitor(&self) -> MarkSymbolVisitor<'a> {
237-
let (worklist, method_map) = (self.worklist, self.method_map);
238-
let (tcx, reachable_symbols) = (self.tcx, self.reachable_symbols);
239-
240-
MarkSymbolVisitor {
241-
worklist: worklist,
242-
method_map: method_map,
243-
tcx: tcx,
244-
reachable_symbols: reachable_symbols,
245-
}
246-
}
247-
248215
// Step 2: Mark all symbols that the symbols on the worklist touch.
249-
fn propagate(&self) {
250-
let mut visitor = self.init_visitor();
216+
fn propagate(&mut self) {
251217
let mut scanned = HashSet::new();
252218
loop {
253-
let search_item = {
254-
let mut worklist = self.worklist.borrow_mut();
255-
if worklist.get().len() == 0 {
256-
break
257-
}
258-
let search_item = worklist.get().pop().unwrap();
259-
if scanned.contains(&search_item) {
260-
continue
261-
}
262-
search_item
263-
};
219+
if self.worklist.len() == 0 {
220+
break
221+
}
222+
let search_item = self.worklist.pop().unwrap();
223+
if scanned.contains(&search_item) {
224+
continue
225+
}
264226

265227
scanned.insert(search_item);
266228
match self.tcx.map.find(search_item) {
267-
Some(ref item) => self.propagate_node(item, search_item,
268-
&mut visitor),
229+
Some(ref item) => self.propagate_node(item, search_item),
269230
None if search_item == ast::CRATE_NODE_ID => {}
270231
None => {
271232
self.tcx.sess.bug(format!("found unmapped ID in worklist: \
@@ -276,9 +237,8 @@ impl<'a> ReachableContext<'a> {
276237
}
277238
}
278239

279-
fn propagate_node(&self, node: &ast_map::Node,
280-
search_item: ast::NodeId,
281-
visitor: &mut MarkSymbolVisitor) {
240+
fn propagate_node(&mut self, node: &ast_map::Node,
241+
search_item: ast::NodeId) {
282242
if !self.tcx.sess.building_library.get() {
283243
// If we are building an executable, then there's no need to flag
284244
// anything as external except for `extern fn` types. These
@@ -289,9 +249,7 @@ impl<'a> ReachableContext<'a> {
289249
ast_map::NodeItem(item) => {
290250
match item.node {
291251
ast::ItemFn(_, ast::ExternFn, _, _, _) => {
292-
let mut reachable_symbols =
293-
self.reachable_symbols.borrow_mut();
294-
reachable_symbols.get().insert(search_item);
252+
self.reachable_symbols.insert(search_item);
295253
}
296254
_ => {}
297255
}
@@ -303,16 +261,15 @@ impl<'a> ReachableContext<'a> {
303261
// continue to participate in linkage after this product is
304262
// produced. In this case, we traverse the ast node, recursing on
305263
// all reachable nodes from this one.
306-
let mut reachable_symbols = self.reachable_symbols.borrow_mut();
307-
reachable_symbols.get().insert(search_item);
264+
self.reachable_symbols.insert(search_item);
308265
}
309266

310267
match *node {
311268
ast_map::NodeItem(item) => {
312269
match item.node {
313270
ast::ItemFn(_, _, _, _, search_block) => {
314271
if item_might_be_inlined(item) {
315-
visit::walk_block(visitor, search_block, ())
272+
visit::walk_block(self, search_block, ())
316273
}
317274
}
318275

@@ -321,9 +278,7 @@ impl<'a> ReachableContext<'a> {
321278
ast::ItemStatic(..) => {
322279
if attr::contains_name(item.attrs.as_slice(),
323280
"address_insignificant") {
324-
let mut reachable_symbols =
325-
self.reachable_symbols.borrow_mut();
326-
reachable_symbols.get().remove(&search_item);
281+
self.reachable_symbols.remove(&search_item);
327282
}
328283
}
329284

@@ -348,14 +303,14 @@ impl<'a> ReachableContext<'a> {
348303
// Keep going, nothing to get exported
349304
}
350305
ast::Provided(ref method) => {
351-
visit::walk_block(visitor, method.body, ())
306+
visit::walk_block(self, method.body, ())
352307
}
353308
}
354309
}
355310
ast_map::NodeMethod(method) => {
356311
let did = self.tcx.map.get_parent_did(search_item);
357312
if method_might_be_inlined(self.tcx, method, did) {
358-
visit::walk_block(visitor, method.body, ())
313+
visit::walk_block(self, method.body, ())
359314
}
360315
}
361316
// Nothing to recurse on for these
@@ -375,13 +330,10 @@ impl<'a> ReachableContext<'a> {
375330
// FIXME(pcwalton): This is a conservative overapproximation, but fixing
376331
// this properly would result in the necessity of computing *type*
377332
// reachability, which might result in a compile time loss.
378-
fn mark_destructors_reachable(&self) {
379-
let destructor_for_type = self.tcx.destructor_for_type.borrow();
380-
for (_, destructor_def_id) in destructor_for_type.get().iter() {
333+
fn mark_destructors_reachable(&mut self) {
334+
for (_, destructor_def_id) in self.tcx.destructor_for_type.borrow().get().iter() {
381335
if destructor_def_id.krate == ast::LOCAL_CRATE {
382-
let mut reachable_symbols = self.reachable_symbols
383-
.borrow_mut();
384-
reachable_symbols.get().insert(destructor_def_id.node);
336+
self.reachable_symbols.insert(destructor_def_id.node);
385337
}
386338
}
387339
}
@@ -390,27 +342,25 @@ impl<'a> ReachableContext<'a> {
390342
pub fn find_reachable(tcx: &ty::ctxt,
391343
method_map: typeck::MethodMap,
392344
exported_items: &privacy::ExportedItems)
393-
-> @RefCell<NodeSet> {
394-
let reachable_context = ReachableContext::new(tcx, method_map);
345+
-> NodeSet {
346+
let mut reachable_context = ReachableContext::new(tcx, method_map);
395347

396348
// Step 1: Seed the worklist with all nodes which were found to be public as
397349
// a result of the privacy pass along with all local lang items. If
398350
// other crates link to us, they're going to expect to be able to
399351
// use the lang items, so we need to be sure to mark them as
400352
// exported.
401-
let mut worklist = reachable_context.worklist.borrow_mut();
402353
for &id in exported_items.iter() {
403-
worklist.get().push(id);
354+
reachable_context.worklist.push(id);
404355
}
405356
for (_, item) in tcx.lang_items.items() {
406357
match *item {
407358
Some(did) if is_local(did) => {
408-
worklist.get().push(did.node);
359+
reachable_context.worklist.push(did.node);
409360
}
410361
_ => {}
411362
}
412363
}
413-
drop(worklist);
414364

415365
// Step 2: Mark all symbols that the symbols on the worklist touch.
416366
reachable_context.propagate();

0 commit comments

Comments
 (0)