Skip to content

Commit c5faf99

Browse files
committed
Auto merge of rust-lang#8414 - MiSawa:fix/optimize-redundant-clone, r=oli-obk
Optimize `redundant_clone` Fixes rust-lang#8412 changelog: none
2 parents d56f457 + 6d2a042 commit c5faf99

File tree

1 file changed

+34
-25
lines changed

1 file changed

+34
-25
lines changed

clippy_lints/src/redundant_clone.rs

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use clippy_utils::source::snippet_opt;
33
use clippy_utils::ty::{has_drop, is_copy, is_type_diagnostic_item, walk_ptrs_ty_depth};
44
use clippy_utils::{fn_has_unsatisfiable_preds, match_def_path, paths};
55
use if_chain::if_chain;
6-
use rustc_data_structures::{fx::FxHashMap, transitive_relation::TransitiveRelation};
6+
use rustc_data_structures::fx::FxHashMap;
77
use rustc_errors::Applicability;
88
use rustc_hir::intravisit::FnKind;
99
use 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`.
514514
struct 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
646638
struct 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

Comments
 (0)