Ignore significant drops of place expressions

This commit is contained in:
Ruihan Li 2024-04-29 12:55:12 +08:00
parent a78a15c5d3
commit 509ca90bf1
3 changed files with 74 additions and 2 deletions

View file

@ -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 {

View file

@ -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() {}

View file

@ -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