@@ -20,7 +20,6 @@ use middle::typeck;
2020use middle:: privacy;
2121use util:: nodemap:: NodeSet ;
2222
23- use std:: cell:: RefCell ;
2423use std:: vec_ng:: Vec ;
2524use collections:: HashSet ;
2625use 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> {
390342pub 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