@@ -3,7 +3,7 @@ use clippy_utils::source::snippet_opt;
33use clippy_utils:: ty:: { has_drop, is_copy, is_type_diagnostic_item, walk_ptrs_ty_depth} ;
44use clippy_utils:: { fn_has_unsatisfiable_preds, match_def_path, paths} ;
55use if_chain:: if_chain;
6- use rustc_data_structures:: { fx:: FxHashMap , transitive_relation :: TransitiveRelation } ;
6+ use rustc_data_structures:: fx:: FxHashMap ;
77use rustc_errors:: Applicability ;
88use rustc_hir:: intravisit:: FnKind ;
99use rustc_hir:: { def_id, Body , FnDecl , HirId } ;
@@ -512,7 +512,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeStorageLive {
512512/// For example, `b = &a; c = &a;` will make `b` and (transitively) `c`
513513/// possible borrowers of `a`.
514514struct PossibleBorrowerVisitor < ' a , ' tcx > {
515- possible_borrower : TransitiveRelation < mir :: Local > ,
515+ possible_borrower : TransitiveRelation ,
516516 body : & ' a mir:: Body < ' tcx > ,
517517 cx : & ' a LateContext < ' tcx > ,
518518 possible_origin : FxHashMap < mir:: Local , HybridBitSet < mir:: Local > > ,
@@ -543,18 +543,10 @@ impl<'a, 'tcx> PossibleBorrowerVisitor<'a, 'tcx> {
543543 continue ;
544544 }
545545
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 ) ) ;
547548 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) ;
558550 }
559551 }
560552
@@ -644,7 +636,7 @@ impl<'a, 'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'a, 'tcx> {
644636/// For exampel, `_1 = &mut _2` generate _1: {_2,...}
645637/// Known Problems: not sure all borrowed are tracked
646638struct PossibleOriginVisitor < ' a , ' tcx > {
647- possible_origin : TransitiveRelation < mir :: Local > ,
639+ possible_origin : TransitiveRelation ,
648640 body : & ' a mir:: Body < ' tcx > ,
649641}
650642
@@ -663,18 +655,10 @@ impl<'a, 'tcx> PossibleOriginVisitor<'a, 'tcx> {
663655 continue ;
664656 }
665657
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 ) ) ;
667660 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) ;
678662 }
679663 }
680664 map
@@ -766,3 +750,28 @@ impl PossibleBorrowerMap<'_, '_> {
766750 self . maybe_live . contains ( local)
767751 }
768752}
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