X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=clippy_lints%2Fsrc%2Fredundant_clone.rs;h=954e702a1f8875e49db76c5c80f5a795762c5703;hb=03960ebab26a1b1d2d43540f47aca6670bdc1e54;hp=b3988973256c4c16cad3c8306c6e43cf4916b062;hpb=2955db493ef9ceaf4cc9bcd3b83680c0206d001d;p=rust.git diff --git a/clippy_lints/src/redundant_clone.rs b/clippy_lints/src/redundant_clone.rs index b3988973256..954e702a1f8 100644 --- a/clippy_lints/src/redundant_clone.rs +++ b/clippy_lints/src/redundant_clone.rs @@ -3,7 +3,7 @@ use clippy_utils::ty::{has_drop, is_copy, is_type_diagnostic_item, walk_ptrs_ty_depth}; use clippy_utils::{fn_has_unsatisfiable_preds, match_def_path, paths}; use if_chain::if_chain; -use rustc_data_structures::{fx::FxHashMap, transitive_relation::TransitiveRelation}; +use rustc_data_structures::fx::FxHashMap; use rustc_errors::Applicability; use rustc_hir::intravisit::FnKind; use rustc_hir::{def_id, Body, FnDecl, HirId}; @@ -71,7 +71,7 @@ macro_rules! unwrap_or_continue { declare_lint_pass!(RedundantClone => [REDUNDANT_CLONE]); impl<'tcx> LateLintPass<'tcx> for RedundantClone { - #[allow(clippy::too_many_lines)] + #[expect(clippy::too_many_lines)] fn check_fn( &mut self, cx: &LateContext<'tcx>, @@ -512,7 +512,7 @@ fn call_return_effect( /// For example, `b = &a; c = &a;` will make `b` and (transitively) `c` /// possible borrowers of `a`. struct PossibleBorrowerVisitor<'a, 'tcx> { - possible_borrower: TransitiveRelation, + possible_borrower: TransitiveRelation, body: &'a mir::Body<'tcx>, cx: &'a LateContext<'tcx>, possible_origin: FxHashMap>, @@ -543,18 +543,10 @@ fn into_map( continue; } - let borrowers = self.possible_borrower.reachable_from(&row); + let mut borrowers = self.possible_borrower.reachable_from(row, self.body.local_decls.len()); + borrowers.remove(mir::Local::from_usize(0)); if !borrowers.is_empty() { - let mut bs = HybridBitSet::new_empty(self.body.local_decls.len()); - for &c in borrowers { - if c != mir::Local::from_usize(0) { - bs.insert(c); - } - } - - if !bs.is_empty() { - map.insert(row, bs); - } + map.insert(row, borrowers); } } @@ -644,7 +636,7 @@ fn visit_terminator(&mut self, terminator: &mir::Terminator<'_>, _loc: mir::Loca /// For exampel, `_1 = &mut _2` generate _1: {_2,...} /// Known Problems: not sure all borrowed are tracked struct PossibleOriginVisitor<'a, 'tcx> { - possible_origin: TransitiveRelation, + possible_origin: TransitiveRelation, body: &'a mir::Body<'tcx>, } @@ -663,18 +655,10 @@ fn into_map(self, cx: &LateContext<'tcx>) -> FxHashMap bool { self.maybe_live.contains(local) } } + +#[derive(Default)] +struct TransitiveRelation { + relations: FxHashMap>, +} +impl TransitiveRelation { + fn add(&mut self, a: mir::Local, b: mir::Local) { + self.relations.entry(a).or_default().push(b); + } + + fn reachable_from(&self, a: mir::Local, domain_size: usize) -> HybridBitSet { + let mut seen = HybridBitSet::new_empty(domain_size); + let mut stack = vec![a]; + while let Some(u) = stack.pop() { + if let Some(edges) = self.relations.get(&u) { + for &v in edges { + if seen.insert(v) { + stack.push(v); + } + } + } + } + seen + } +}