about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-02-20 12:16:48 +0000
committerbors <bors@rust-lang.org>2020-02-20 12:16:48 +0000
commit5fbec44fd9066b3d4e27dc6d045d4ff4848ae82e (patch)
tree9620ee738c140c07685a1e9cc8d23f2191e165b3
parent06f0ab03ef63869eb159cf7d57d5d5e826ff10ca (diff)
parent9d254545f386552e27033f9e395cfb21fcd0f569 (diff)
downloadrust-5fbec44fd9066b3d4e27dc6d045d4ff4848ae82e.tar.gz
rust-5fbec44fd9066b3d4e27dc6d045d4ff4848ae82e.zip
Auto merge of #5198 - sinkuu:redundant_clone_df, r=flip1995
redundant_clone: Migrate to new dataflow framework

Migration to [the new dataflow framework](https://github.com/rust-lang/rust/pull/65672) is ongoing in rustc. This PR updates the dataflow impl in `redundant_clone` lint.

---

changelog: none
-rw-r--r--clippy_lints/src/redundant_clone.rs89
1 files changed, 40 insertions, 49 deletions
diff --git a/clippy_lints/src/redundant_clone.rs b/clippy_lints/src/redundant_clone.rs
index 66faecbef2a..e419ae09a3f 100644
--- a/clippy_lints/src/redundant_clone.rs
+++ b/clippy_lints/src/redundant_clone.rs
@@ -15,9 +15,8 @@ use rustc_hir::intravisit::FnKind;
 use rustc_hir::{def_id, Body, FnDecl, HirId};
 use rustc_index::bit_set::{BitSet, HybridBitSet};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_mir::dataflow::{
-    do_dataflow, BitDenotation, BottomValue, DataflowResults, DataflowResultsCursor, DebugFormatted, GenKillSet,
-};
+use rustc_mir::dataflow::generic::{Analysis, AnalysisDomain, GenKill, GenKillAnalysis, ResultsCursor};
+use rustc_mir::dataflow::BottomValue;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::source_map::{BytePos, Span};
 use std::convert::TryFrom;
@@ -83,16 +82,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantClone {
         let mir = cx.tcx.optimized_mir(def_id);
         let mir_read_only = mir.unwrap_read_only();
 
-        let dead_unwinds = BitSet::new_empty(mir.basic_blocks().len());
-        let maybe_storage_live_result = do_dataflow(
-            cx.tcx,
-            mir,
-            def_id,
-            &[],
-            &dead_unwinds,
-            MaybeStorageLive::new(mir),
-            |bd, p| DebugFormatted::new(&bd.body.local_decls[p]),
-        );
+        let maybe_storage_live_result = MaybeStorageLive
+            .into_engine(cx.tcx, mir, def_id)
+            .iterate_to_fixpoint()
+            .into_results_cursor(mir);
         let mut possible_borrower = {
             let mut vis = PossibleBorrowerVisitor::new(cx, mir);
             vis.visit_body(mir_read_only);
@@ -377,34 +370,25 @@ impl<'tcx> mir::visit::Visitor<'tcx> for LocalUseVisitor {
 
 /// Determines liveness of each local purely based on `StorageLive`/`Dead`.
 #[derive(Copy, Clone)]
-struct MaybeStorageLive<'a, 'tcx> {
-    body: &'a mir::Body<'tcx>,
-}
-
-impl<'a, 'tcx> MaybeStorageLive<'a, 'tcx> {
-    fn new(body: &'a mir::Body<'tcx>) -> Self {
-        MaybeStorageLive { body }
-    }
-}
+struct MaybeStorageLive;
 
-impl<'a, 'tcx> BitDenotation<'tcx> for MaybeStorageLive<'a, 'tcx> {
+impl<'tcx> AnalysisDomain<'tcx> for MaybeStorageLive {
     type Idx = mir::Local;
-    fn name() -> &'static str {
-        "maybe_storage_live"
-    }
-    fn bits_per_block(&self) -> usize {
-        self.body.local_decls.len()
+    const NAME: &'static str = "maybe_storage_live";
+
+    fn bits_per_block(&self, body: &mir::Body<'tcx>) -> usize {
+        body.local_decls.len()
     }
 
-    fn start_block_effect(&self, on_entry: &mut BitSet<mir::Local>) {
-        for arg in self.body.args_iter() {
-            on_entry.insert(arg);
+    fn initialize_start_block(&self, body: &mir::Body<'tcx>, state: &mut BitSet<Self::Idx>) {
+        for arg in body.args_iter() {
+            state.insert(arg);
         }
     }
+}
 
-    fn statement_effect(&self, trans: &mut GenKillSet<mir::Local>, loc: mir::Location) {
-        let stmt = &self.body[loc.block].statements[loc.statement_index];
-
+impl<'tcx> GenKillAnalysis<'tcx> for MaybeStorageLive {
+    fn statement_effect(&self, trans: &mut impl GenKill<Self::Idx>, stmt: &mir::Statement<'tcx>, _: mir::Location) {
         match stmt.kind {
             mir::StatementKind::StorageLive(l) => trans.gen(l),
             mir::StatementKind::StorageDead(l) => trans.kill(l),
@@ -412,20 +396,27 @@ impl<'a, 'tcx> BitDenotation<'tcx> for MaybeStorageLive<'a, 'tcx> {
         }
     }
 
-    fn terminator_effect(&self, _trans: &mut GenKillSet<mir::Local>, _loc: mir::Location) {}
+    fn terminator_effect(
+        &self,
+        _trans: &mut impl GenKill<Self::Idx>,
+        _terminator: &mir::Terminator<'tcx>,
+        _loc: mir::Location,
+    ) {
+    }
 
-    fn propagate_call_return(
+    fn call_return_effect(
         &self,
-        _in_out: &mut BitSet<mir::Local>,
-        _call_bb: mir::BasicBlock,
-        _dest_bb: mir::BasicBlock,
-        _dest_place: &mir::Place<'tcx>,
+        _in_out: &mut impl GenKill<Self::Idx>,
+        _block: mir::BasicBlock,
+        _func: &mir::Operand<'tcx>,
+        _args: &[mir::Operand<'tcx>],
+        _return_place: &mir::Place<'tcx>,
     ) {
         // Nothing to do when a call returns successfully
     }
 }
 
-impl<'a, 'tcx> BottomValue for MaybeStorageLive<'a, 'tcx> {
+impl BottomValue for MaybeStorageLive {
     /// bottom = dead
     const BOTTOM_VALUE: bool = false;
 }
@@ -451,8 +442,8 @@ impl<'a, 'tcx> PossibleBorrowerVisitor<'a, 'tcx> {
     fn into_map(
         self,
         cx: &LateContext<'a, 'tcx>,
-        maybe_live: DataflowResults<'tcx, MaybeStorageLive<'a, 'tcx>>,
-    ) -> PossibleBorrower<'a, 'tcx> {
+        maybe_live: ResultsCursor<'tcx, 'tcx, MaybeStorageLive>,
+    ) -> PossibleBorrowerMap<'a, 'tcx> {
         let mut map = FxHashMap::default();
         for row in (1..self.body.local_decls.len()).map(mir::Local::from_usize) {
             if is_copy(cx, self.body.local_decls[row].ty) {
@@ -475,9 +466,9 @@ impl<'a, 'tcx> PossibleBorrowerVisitor<'a, 'tcx> {
         }
 
         let bs = BitSet::new_empty(self.body.local_decls.len());
-        PossibleBorrower {
+        PossibleBorrowerMap {
             map,
-            maybe_live: DataflowResultsCursor::new(maybe_live, self.body),
+            maybe_live,
             bitset: (bs.clone(), bs),
         }
     }
@@ -557,18 +548,18 @@ fn rvalue_locals(rvalue: &mir::Rvalue<'_>, mut visit: impl FnMut(mir::Local)) {
 }
 
 /// Result of `PossibleBorrowerVisitor`.
-struct PossibleBorrower<'a, 'tcx> {
+struct PossibleBorrowerMap<'a, 'tcx> {
     /// Mapping `Local -> its possible borrowers`
     map: FxHashMap<mir::Local, HybridBitSet<mir::Local>>,
-    maybe_live: DataflowResultsCursor<'a, 'tcx, MaybeStorageLive<'a, 'tcx>>,
+    maybe_live: ResultsCursor<'a, 'tcx, MaybeStorageLive>,
     // Caches to avoid allocation of `BitSet` on every query
     bitset: (BitSet<mir::Local>, BitSet<mir::Local>),
 }
 
-impl PossibleBorrower<'_, '_> {
+impl PossibleBorrowerMap<'_, '_> {
     /// Returns true if the set of borrowers of `borrowed` living at `at` matches with `borrowers`.
     fn only_borrowers(&mut self, borrowers: &[mir::Local], borrowed: mir::Local, at: mir::Location) -> bool {
-        self.maybe_live.seek(at);
+        self.maybe_live.seek_after(at);
 
         self.bitset.0.clear();
         let maybe_live = &mut self.maybe_live;