about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSamuel Tardieu <sam@rfc1149.net>2025-01-11 12:30:17 +0100
committerSamuel Tardieu <sam@rfc1149.net>2025-01-11 14:09:07 +0100
commit0b402baf152ab18774716ea0c8e07a34ad83a252 (patch)
tree76144a0c37b4f6cdf4820e77dc49a91c7fc8062b
parentab55d3fc62c091fbc4b4273347aa8532976741e3 (diff)
downloadrust-0b402baf152ab18774716ea0c8e07a34ad83a252.tar.gz
rust-0b402baf152ab18774716ea0c8e07a34ad83a252.zip
Do not look for significant drop inside `.await` expansion
Temporaries created inside the expansion of `.await` will be dropped and need
no checking. Looking inside the expansion will trigger false positives.
-rw-r--r--clippy_lints/src/matches/significant_drop_in_scrutinee.rs5
-rw-r--r--tests/ui/significant_drop_in_scrutinee.rs18
-rw-r--r--tests/ui/significant_drop_in_scrutinee.stderr18
3 files changed, 38 insertions, 3 deletions
diff --git a/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
index 2ce6a8a85a5..9d8e0a69433 100644
--- a/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
+++ b/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
@@ -441,8 +441,9 @@ impl<'tcx> Visitor<'tcx> for SigDropHelper<'_, 'tcx> {
         let parent_expr_before = self.parent_expr.replace(ex);
 
         match ex.kind {
-            // Skip blocks because values in blocks will be dropped as usual.
-            ExprKind::Block(..) => (),
+            // Skip blocks because values in blocks will be dropped as usual, and await
+            // desugaring because temporary insides the future will have been dropped.
+            ExprKind::Block(..) | ExprKind::Match(_, _, MatchSource::AwaitDesugar) => (),
             _ => walk_expr(self, ex),
         }
 
diff --git a/tests/ui/significant_drop_in_scrutinee.rs b/tests/ui/significant_drop_in_scrutinee.rs
index 8468d1d7c7d..e9ebd23beac 100644
--- a/tests/ui/significant_drop_in_scrutinee.rs
+++ b/tests/ui/significant_drop_in_scrutinee.rs
@@ -832,4 +832,22 @@ fn should_trigger_lint_in_while_let() {
     }
 }
 
+async fn foo_async(mutex: &Mutex<i32>) -> Option<MutexGuard<'_, i32>> {
+    Some(mutex.lock().unwrap())
+}
+
+async fn should_trigger_lint_for_async(mutex: Mutex<i32>) -> i32 {
+    match *foo_async(&mutex).await.unwrap() {
+        n if n < 10 => n,
+        _ => 10,
+    }
+}
+
+async fn should_not_trigger_lint_in_async_expansion(mutex: Mutex<i32>) -> i32 {
+    match foo_async(&mutex).await {
+        Some(guard) => *guard,
+        _ => 0,
+    }
+}
+
 fn main() {}
diff --git a/tests/ui/significant_drop_in_scrutinee.stderr b/tests/ui/significant_drop_in_scrutinee.stderr
index 62030cbe70e..23e38948ec5 100644
--- a/tests/ui/significant_drop_in_scrutinee.stderr
+++ b/tests/ui/significant_drop_in_scrutinee.stderr
@@ -568,5 +568,21 @@ LL |     }
    |
    = note: this might lead to deadlocks or other unexpected behavior
 
-error: aborting due to 29 previous errors
+error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
+  --> tests/ui/significant_drop_in_scrutinee.rs:840:11
+   |
+LL |     match *foo_async(&mutex).await.unwrap() {
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL |     }
+   |      - temporary lives until here
+   |
+   = note: this might lead to deadlocks or other unexpected behavior
+help: try moving the temporary above the match
+   |
+LL ~     let value = *foo_async(&mutex).await.unwrap();
+LL ~     match value {
+   |
+
+error: aborting due to 30 previous errors