Skip to content

Commit 509ca90

Browse files
committed
Ignore significant drops of place expressions
1 parent a78a15c commit 509ca90

File tree

3 files changed

+74
-2
lines changed

3 files changed

+74
-2
lines changed

clippy_lints/src/matches/significant_drop_in_scrutinee.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ impl<'a, 'tcx> SigDropChecker<'a, 'tcx> {
116116
}
117117

118118
fn is_sig_drop_expr(&mut self, ex: &'tcx Expr<'_>) -> bool {
119-
self.has_sig_drop_attr(self.cx.typeck_results().expr_ty(ex))
119+
!ex.is_syntactic_place_expr() && self.has_sig_drop_attr(self.cx.typeck_results().expr_ty(ex))
120120
}
121121

122122
fn has_sig_drop_attr(&mut self, ty: Ty<'tcx>) -> bool {

tests/ui/significant_drop_in_scrutinee.rs

+56
Original file line numberDiff line numberDiff line change
@@ -675,4 +675,60 @@ fn should_not_trigger_on_significant_iterator_drop() {
675675
}
676676
}
677677

678+
// https://github.com/rust-lang/rust-clippy/issues/9072
679+
fn should_not_trigger_lint_if_place_expr_has_significant_drop() {
680+
let x = Mutex::new(vec![1, 2, 3]);
681+
let x_guard = x.lock().unwrap();
682+
683+
match x_guard[0] {
684+
1 => println!("1!"),
685+
x => println!("{x}"),
686+
}
687+
688+
match x_guard.len() {
689+
1 => println!("1!"),
690+
x => println!("{x}"),
691+
}
692+
}
693+
694+
struct Guard<'a, T>(MutexGuard<'a, T>);
695+
696+
struct Ref<'a, T>(&'a T);
697+
698+
impl<'a, T> Guard<'a, T> {
699+
fn guard(&self) -> &MutexGuard<T> {
700+
&self.0
701+
}
702+
703+
fn guard_ref(&self) -> Ref<MutexGuard<T>> {
704+
Ref(&self.0)
705+
}
706+
707+
fn take(self) -> Box<MutexGuard<'a, T>> {
708+
Box::new(self.0)
709+
}
710+
}
711+
712+
fn should_not_trigger_for_significant_drop_ref() {
713+
let mutex = Mutex::new(vec![1, 2]);
714+
let guard = Guard(mutex.lock().unwrap());
715+
716+
match guard.guard().len() {
717+
0 => println!("empty"),
718+
_ => println!("not empty"),
719+
}
720+
721+
match guard.guard_ref().0.len() {
722+
0 => println!("empty"),
723+
_ => println!("not empty"),
724+
}
725+
726+
match guard.take().len() {
727+
//~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the
728+
//~| NOTE: this might lead to deadlocks or other unexpected behavior
729+
0 => println!("empty"),
730+
_ => println!("not empty"),
731+
};
732+
}
733+
678734
fn main() {}

tests/ui/significant_drop_in_scrutinee.stderr

+17-1
Original file line numberDiff line numberDiff line change
@@ -505,5 +505,21 @@ LL ~ let value = mutex.lock().unwrap().foo();
505505
LL ~ match value {
506506
|
507507

508-
error: aborting due to 26 previous errors
508+
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
509+
--> tests/ui/significant_drop_in_scrutinee.rs:726:11
510+
|
511+
LL | match guard.take().len() {
512+
| ^^^^^^^^^^^^^^^^^^
513+
...
514+
LL | };
515+
| - temporary lives until here
516+
|
517+
= note: this might lead to deadlocks or other unexpected behavior
518+
help: try moving the temporary above the match
519+
|
520+
LL ~ let value = guard.take().len();
521+
LL ~ match value {
522+
|
523+
524+
error: aborting due to 27 previous errors
509525

0 commit comments

Comments
 (0)