3535use std:: fmt:: { Debug , Formatter } ;
3636
3737use rustc_data_structures:: fx:: FxHashMap ;
38+ use rustc_index:: bit_set:: BitSet ;
3839use rustc_index:: vec:: IndexVec ;
3940use rustc_middle:: mir:: visit:: { MutatingUseContext , PlaceContext , Visitor } ;
4041use rustc_middle:: mir:: * ;
@@ -589,7 +590,7 @@ impl Map {
589590 ) -> Self {
590591 let mut map = Self :: new ( ) ;
591592 let exclude = excluded_locals ( body) ;
592- map. register_with_filter ( tcx, body, filter, & exclude) ;
593+ map. register_with_filter ( tcx, body, filter, exclude) ;
593594 debug ! ( "registered {} places ({} nodes in total)" , map. value_count, map. places. len( ) ) ;
594595 map
595596 }
@@ -600,12 +601,12 @@ impl Map {
600601 tcx : TyCtxt < ' tcx > ,
601602 body : & Body < ' tcx > ,
602603 mut filter : impl FnMut ( Ty < ' tcx > ) -> bool ,
603- exclude : & IndexVec < Local , bool > ,
604+ exclude : BitSet < Local > ,
604605 ) {
605606 // We use this vector as stack, pushing and popping projections.
606607 let mut projection = Vec :: new ( ) ;
607608 for ( local, decl) in body. local_decls . iter_enumerated ( ) {
608- if !exclude[ local] {
609+ if !exclude. contains ( local) {
609610 self . register_with_filter_rec ( tcx, local, & mut projection, decl. ty , & mut filter) ;
610611 }
611612 }
@@ -823,26 +824,27 @@ pub fn iter_fields<'tcx>(
823824}
824825
825826/// Returns all locals with projections that have their reference or address taken.
826- pub fn excluded_locals ( body : & Body < ' _ > ) -> IndexVec < Local , bool > {
827+ pub fn excluded_locals ( body : & Body < ' _ > ) -> BitSet < Local > {
827828 struct Collector {
828- result : IndexVec < Local , bool > ,
829+ result : BitSet < Local > ,
829830 }
830831
831832 impl < ' tcx > Visitor < ' tcx > for Collector {
832833 fn visit_place ( & mut self , place : & Place < ' tcx > , context : PlaceContext , _location : Location ) {
833- if context. is_borrow ( )
834+ if ( context. is_borrow ( )
834835 || context. is_address_of ( )
835836 || context. is_drop ( )
836- || context == PlaceContext :: MutatingUse ( MutatingUseContext :: AsmOutput )
837+ || context == PlaceContext :: MutatingUse ( MutatingUseContext :: AsmOutput ) )
838+ && !place. is_indirect ( )
837839 {
838840 // A pointer to a place could be used to access other places with the same local,
839841 // hence we have to exclude the local completely.
840- self . result [ place. local ] = true ;
842+ self . result . insert ( place. local ) ;
841843 }
842844 }
843845 }
844846
845- let mut collector = Collector { result : IndexVec :: from_elem ( false , & body. local_decls ) } ;
847+ let mut collector = Collector { result : BitSet :: new_empty ( body. local_decls . len ( ) ) } ;
846848 collector. visit_body ( body) ;
847849 collector. result
848850}
0 commit comments