35
35
use std:: fmt:: { Debug , Formatter } ;
36
36
37
37
use rustc_data_structures:: fx:: FxHashMap ;
38
+ use rustc_index:: bit_set:: BitSet ;
38
39
use rustc_index:: vec:: IndexVec ;
39
40
use rustc_middle:: mir:: visit:: { MutatingUseContext , PlaceContext , Visitor } ;
40
41
use rustc_middle:: mir:: * ;
@@ -589,7 +590,7 @@ impl Map {
589
590
) -> Self {
590
591
let mut map = Self :: new ( ) ;
591
592
let exclude = excluded_locals ( body) ;
592
- map. register_with_filter ( tcx, body, filter, & exclude) ;
593
+ map. register_with_filter ( tcx, body, filter, exclude) ;
593
594
debug ! ( "registered {} places ({} nodes in total)" , map. value_count, map. places. len( ) ) ;
594
595
map
595
596
}
@@ -600,12 +601,12 @@ impl Map {
600
601
tcx : TyCtxt < ' tcx > ,
601
602
body : & Body < ' tcx > ,
602
603
mut filter : impl FnMut ( Ty < ' tcx > ) -> bool ,
603
- exclude : & IndexVec < Local , bool > ,
604
+ exclude : BitSet < Local > ,
604
605
) {
605
606
// We use this vector as stack, pushing and popping projections.
606
607
let mut projection = Vec :: new ( ) ;
607
608
for ( local, decl) in body. local_decls . iter_enumerated ( ) {
608
- if !exclude[ local] {
609
+ if !exclude. contains ( local) {
609
610
self . register_with_filter_rec ( tcx, local, & mut projection, decl. ty , & mut filter) ;
610
611
}
611
612
}
@@ -823,26 +824,27 @@ pub fn iter_fields<'tcx>(
823
824
}
824
825
825
826
/// 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 > {
827
828
struct Collector {
828
- result : IndexVec < Local , bool > ,
829
+ result : BitSet < Local > ,
829
830
}
830
831
831
832
impl < ' tcx > Visitor < ' tcx > for Collector {
832
833
fn visit_place ( & mut self , place : & Place < ' tcx > , context : PlaceContext , _location : Location ) {
833
- if context. is_borrow ( )
834
+ if ( context. is_borrow ( )
834
835
|| context. is_address_of ( )
835
836
|| context. is_drop ( )
836
- || context == PlaceContext :: MutatingUse ( MutatingUseContext :: AsmOutput )
837
+ || context == PlaceContext :: MutatingUse ( MutatingUseContext :: AsmOutput ) )
838
+ && !place. is_indirect ( )
837
839
{
838
840
// A pointer to a place could be used to access other places with the same local,
839
841
// hence we have to exclude the local completely.
840
- self . result [ place. local ] = true ;
842
+ self . result . insert ( place. local ) ;
841
843
}
842
844
}
843
845
}
844
846
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 ( ) ) } ;
846
848
collector. visit_body ( body) ;
847
849
collector. result
848
850
}
0 commit comments