diff options
| author | Ruihan Li <lrh2000@pku.edu.cn> | 2024-04-29 12:55:12 +0800 |
|---|---|---|
| committer | Ruihan Li <lrh2000@pku.edu.cn> | 2024-05-06 00:30:41 +0800 |
| commit | 509ca90bf1201c00ba2a519dc590c83dc73bdb3b (patch) | |
| tree | d2b1dc2553888320e68a62f5627d9ef8c41debc8 | |
| parent | a78a15c5d399a813f84a04843164711a743c2692 (diff) | |
| download | rust-509ca90bf1201c00ba2a519dc590c83dc73bdb3b.tar.gz rust-509ca90bf1201c00ba2a519dc590c83dc73bdb3b.zip | |
Ignore significant drops of place expressions
| -rw-r--r-- | clippy_lints/src/matches/significant_drop_in_scrutinee.rs | 2 | ||||
| -rw-r--r-- | tests/ui/significant_drop_in_scrutinee.rs | 56 | ||||
| -rw-r--r-- | tests/ui/significant_drop_in_scrutinee.stderr | 18 |
3 files changed, 74 insertions, 2 deletions
diff --git a/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/clippy_lints/src/matches/significant_drop_in_scrutinee.rs index 13c0b6e742d..3171acda442 100644 --- a/clippy_lints/src/matches/significant_drop_in_scrutinee.rs +++ b/clippy_lints/src/matches/significant_drop_in_scrutinee.rs @@ -116,7 +116,7 @@ impl<'a, 'tcx> SigDropChecker<'a, 'tcx> { } fn is_sig_drop_expr(&mut self, ex: &'tcx Expr<'_>) -> bool { - self.has_sig_drop_attr(self.cx.typeck_results().expr_ty(ex)) + !ex.is_syntactic_place_expr() && self.has_sig_drop_attr(self.cx.typeck_results().expr_ty(ex)) } fn has_sig_drop_attr(&mut self, ty: Ty<'tcx>) -> bool { diff --git a/tests/ui/significant_drop_in_scrutinee.rs b/tests/ui/significant_drop_in_scrutinee.rs index 0305d895fc5..7fc89bb9538 100644 --- a/tests/ui/significant_drop_in_scrutinee.rs +++ b/tests/ui/significant_drop_in_scrutinee.rs @@ -675,4 +675,60 @@ fn should_not_trigger_on_significant_iterator_drop() { } } +// https://github.com/rust-lang/rust-clippy/issues/9072 +fn should_not_trigger_lint_if_place_expr_has_significant_drop() { + let x = Mutex::new(vec![1, 2, 3]); + let x_guard = x.lock().unwrap(); + + match x_guard[0] { + 1 => println!("1!"), + x => println!("{x}"), + } + + match x_guard.len() { + 1 => println!("1!"), + x => println!("{x}"), + } +} + +struct Guard<'a, T>(MutexGuard<'a, T>); + +struct Ref<'a, T>(&'a T); + +impl<'a, T> Guard<'a, T> { + fn guard(&self) -> &MutexGuard<T> { + &self.0 + } + + fn guard_ref(&self) -> Ref<MutexGuard<T>> { + Ref(&self.0) + } + + fn take(self) -> Box<MutexGuard<'a, T>> { + Box::new(self.0) + } +} + +fn should_not_trigger_for_significant_drop_ref() { + let mutex = Mutex::new(vec![1, 2]); + let guard = Guard(mutex.lock().unwrap()); + + match guard.guard().len() { + 0 => println!("empty"), + _ => println!("not empty"), + } + + match guard.guard_ref().0.len() { + 0 => println!("empty"), + _ => println!("not empty"), + } + + match guard.take().len() { + //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the + //~| NOTE: this might lead to deadlocks or other unexpected behavior + 0 => println!("empty"), + _ => println!("not empty"), + }; +} + fn main() {} diff --git a/tests/ui/significant_drop_in_scrutinee.stderr b/tests/ui/significant_drop_in_scrutinee.stderr index 1f19eff0631..811bb065527 100644 --- a/tests/ui/significant_drop_in_scrutinee.stderr +++ b/tests/ui/significant_drop_in_scrutinee.stderr @@ -505,5 +505,21 @@ LL ~ let value = mutex.lock().unwrap().foo(); LL ~ match value { | -error: aborting due to 26 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:726:11 + | +LL | match guard.take().len() { + | ^^^^^^^^^^^^^^^^^^ +... +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 = guard.take().len(); +LL ~ match value { + | + +error: aborting due to 27 previous errors |
