about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/significant_drop_tightening.rs24
-rw-r--r--tests/ui/significant_drop_tightening.fixed8
-rw-r--r--tests/ui/significant_drop_tightening.rs8
-rw-r--r--tests/ui/significant_drop_tightening.stderr6
4 files changed, 38 insertions, 8 deletions
diff --git a/clippy_lints/src/significant_drop_tightening.rs b/clippy_lints/src/significant_drop_tightening.rs
index 4cc85e38564..367466b7d82 100644
--- a/clippy_lints/src/significant_drop_tightening.rs
+++ b/clippy_lints/src/significant_drop_tightening.rs
@@ -61,6 +61,18 @@ pub struct SignificantDropTightening<'tcx> {
 }
 
 impl<'tcx> SignificantDropTightening<'tcx> {
+    /// Searches for at least one statement that could slow down the release of a significant drop.
+    fn at_least_one_stmt_is_expensive(stmts: &[hir::Stmt<'_>]) -> bool {
+        for stmt in stmts {
+            match stmt.kind {
+                hir::StmtKind::Local(local) if let Some(expr) = local.init
+                    && let hir::ExprKind::Path(_) = expr.kind => {},
+                _ => return true
+            };
+        }
+        false
+    }
+
     /// Verifies if the expression is of type `drop(some_lock_path)` to assert that the temporary
     /// is already being dropped before the end of its scope.
     fn has_drop(expr: &'tcx hir::Expr<'_>, init_bind_ident: Ident) -> bool {
@@ -198,13 +210,15 @@ impl<'tcx> LateLintPass<'tcx> for SignificantDropTightening<'tcx> {
                     }
                     self.modify_sdap_if_sig_drop_exists(cx, expr, idx, &mut sdap, stmt, |_| {});
                 },
-                _ => continue
+                _ => {}
             };
         }
-        if sdap.number_of_stmts > 1 && {
-            let last_stmts_idx = block.stmts.len().wrapping_sub(1);
-            sdap.last_use_stmt_idx != last_stmts_idx
-        } {
+        let stmts_after_last_use = sdap
+            .last_use_stmt_idx
+            .checked_add(1)
+            .and_then(|idx| block.stmts.get(idx..))
+            .unwrap_or_default();
+        if sdap.number_of_stmts > 1 && Self::at_least_one_stmt_is_expensive(stmts_after_last_use) {
             span_lint_and_then(
                 cx,
                 SIGNIFICANT_DROP_TIGHTENING,
diff --git a/tests/ui/significant_drop_tightening.fixed b/tests/ui/significant_drop_tightening.fixed
index 7d56a87053f..5d176d2a927 100644
--- a/tests/ui/significant_drop_tightening.fixed
+++ b/tests/ui/significant_drop_tightening.fixed
@@ -4,6 +4,14 @@
 
 use std::sync::Mutex;
 
+pub fn post_bindings_can_be_ignored() {
+    let mutex = Mutex::new(1);
+    let lock = mutex.lock().unwrap();
+    let rslt = *lock;
+    let another = rslt;
+    let _ = another;
+}
+
 pub fn unnecessary_contention_with_multiple_owned_results() {
     {
         let mutex = Mutex::new(1i32);
diff --git a/tests/ui/significant_drop_tightening.rs b/tests/ui/significant_drop_tightening.rs
index 6f3ce328e5d..be9c0774275 100644
--- a/tests/ui/significant_drop_tightening.rs
+++ b/tests/ui/significant_drop_tightening.rs
@@ -4,6 +4,14 @@
 
 use std::sync::Mutex;
 
+pub fn post_bindings_can_be_ignored() {
+    let mutex = Mutex::new(1);
+    let lock = mutex.lock().unwrap();
+    let rslt = *lock;
+    let another = rslt;
+    let _ = another;
+}
+
 pub fn unnecessary_contention_with_multiple_owned_results() {
     {
         let mutex = Mutex::new(1i32);
diff --git a/tests/ui/significant_drop_tightening.stderr b/tests/ui/significant_drop_tightening.stderr
index 52754aac782..0ec9b1acb59 100644
--- a/tests/ui/significant_drop_tightening.stderr
+++ b/tests/ui/significant_drop_tightening.stderr
@@ -1,5 +1,5 @@
 error: temporary with significant `Drop` can be early dropped
-  --> $DIR/significant_drop_tightening.rs:17:13
+  --> $DIR/significant_drop_tightening.rs:25:13
    |
 LL | /     {
 LL | |         let mutex = Mutex::new(1i32);
@@ -20,7 +20,7 @@ LL +         drop(lock);
    |
 
 error: temporary with significant `Drop` can be early dropped
-  --> $DIR/significant_drop_tightening.rs:38:13
+  --> $DIR/significant_drop_tightening.rs:46:13
    |
 LL | /     {
 LL | |         let mutex = Mutex::new(1i32);
@@ -44,7 +44,7 @@ LL +
    |
 
 error: temporary with significant `Drop` can be early dropped
-  --> $DIR/significant_drop_tightening.rs:44:17
+  --> $DIR/significant_drop_tightening.rs:52:17
    |
 LL | /     {
 LL | |         let mutex = Mutex::new(vec![1i32]);