@@ -3,7 +3,7 @@ use clippy_utils::source::snippet_opt;
3
3
use clippy_utils:: ty:: { has_drop, is_copy, is_type_diagnostic_item, walk_ptrs_ty_depth} ;
4
4
use clippy_utils:: { fn_has_unsatisfiable_preds, match_def_path, paths} ;
5
5
use if_chain:: if_chain;
6
- use rustc_data_structures:: { fx:: FxHashMap , transitive_relation :: TransitiveRelation } ;
6
+ use rustc_data_structures:: fx:: FxHashMap ;
7
7
use rustc_errors:: Applicability ;
8
8
use rustc_hir:: intravisit:: FnKind ;
9
9
use rustc_hir:: { def_id, Body , FnDecl , HirId } ;
@@ -512,7 +512,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeStorageLive {
512
512
/// For example, `b = &a; c = &a;` will make `b` and (transitively) `c`
513
513
/// possible borrowers of `a`.
514
514
struct PossibleBorrowerVisitor < ' a , ' tcx > {
515
- possible_borrower : TransitiveRelation < mir :: Local > ,
515
+ possible_borrower : TransitiveRelation ,
516
516
body : & ' a mir:: Body < ' tcx > ,
517
517
cx : & ' a LateContext < ' tcx > ,
518
518
possible_origin : FxHashMap < mir:: Local , HybridBitSet < mir:: Local > > ,
@@ -543,18 +543,10 @@ impl<'a, 'tcx> PossibleBorrowerVisitor<'a, 'tcx> {
543
543
continue ;
544
544
}
545
545
546
- let borrowers = self . possible_borrower . reachable_from ( & row) ;
546
+ let mut borrowers = self . possible_borrower . reachable_from ( row, self . body . local_decls . len ( ) ) ;
547
+ borrowers. remove ( mir:: Local :: from_usize ( 0 ) ) ;
547
548
if !borrowers. is_empty ( ) {
548
- let mut bs = HybridBitSet :: new_empty ( self . body . local_decls . len ( ) ) ;
549
- for & c in borrowers {
550
- if c != mir:: Local :: from_usize ( 0 ) {
551
- bs. insert ( c) ;
552
- }
553
- }
554
-
555
- if !bs. is_empty ( ) {
556
- map. insert ( row, bs) ;
557
- }
549
+ map. insert ( row, borrowers) ;
558
550
}
559
551
}
560
552
@@ -644,7 +636,7 @@ impl<'a, 'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'a, 'tcx> {
644
636
/// For exampel, `_1 = &mut _2` generate _1: {_2,...}
645
637
/// Known Problems: not sure all borrowed are tracked
646
638
struct PossibleOriginVisitor < ' a , ' tcx > {
647
- possible_origin : TransitiveRelation < mir :: Local > ,
639
+ possible_origin : TransitiveRelation ,
648
640
body : & ' a mir:: Body < ' tcx > ,
649
641
}
650
642
@@ -663,18 +655,10 @@ impl<'a, 'tcx> PossibleOriginVisitor<'a, 'tcx> {
663
655
continue ;
664
656
}
665
657
666
- let borrowers = self . possible_origin . reachable_from ( & row) ;
658
+ let mut borrowers = self . possible_origin . reachable_from ( row, self . body . local_decls . len ( ) ) ;
659
+ borrowers. remove ( mir:: Local :: from_usize ( 0 ) ) ;
667
660
if !borrowers. is_empty ( ) {
668
- let mut bs = HybridBitSet :: new_empty ( self . body . local_decls . len ( ) ) ;
669
- for & c in borrowers {
670
- if c != mir:: Local :: from_usize ( 0 ) {
671
- bs. insert ( c) ;
672
- }
673
- }
674
-
675
- if !bs. is_empty ( ) {
676
- map. insert ( row, bs) ;
677
- }
661
+ map. insert ( row, borrowers) ;
678
662
}
679
663
}
680
664
map
@@ -766,3 +750,28 @@ impl PossibleBorrowerMap<'_, '_> {
766
750
self . maybe_live . contains ( local)
767
751
}
768
752
}
753
+
754
+ #[ derive( Default ) ]
755
+ struct TransitiveRelation {
756
+ relations : FxHashMap < mir:: Local , Vec < mir:: Local > > ,
757
+ }
758
+ impl TransitiveRelation {
759
+ fn add ( & mut self , a : mir:: Local , b : mir:: Local ) {
760
+ self . relations . entry ( a) . or_default ( ) . push ( b) ;
761
+ }
762
+
763
+ fn reachable_from ( & self , a : mir:: Local , domain_size : usize ) -> HybridBitSet < mir:: Local > {
764
+ let mut seen = HybridBitSet :: new_empty ( domain_size) ;
765
+ let mut stack = vec ! [ a] ;
766
+ while let Some ( u) = stack. pop ( ) {
767
+ if let Some ( edges) = self . relations . get ( & u) {
768
+ for & v in edges {
769
+ if seen. insert ( v) {
770
+ stack. push ( v) ;
771
+ }
772
+ }
773
+ }
774
+ }
775
+ seen
776
+ }
777
+ }
0 commit comments