diff --git a/tests/ui/significant_drop_tightening.fixed b/tests/ui/significant_drop_tightening.fixed index eb8524167c4a..52d18263ea6e 100644 --- a/tests/ui/significant_drop_tightening.fixed +++ b/tests/ui/significant_drop_tightening.fixed @@ -2,7 +2,15 @@ #![warn(clippy::significant_drop_tightening)] -use std::sync::Mutex; +use std::{ + cell::UnsafeCell, + mem::{drop as unlock, MaybeUninit}, + sync::{ + atomic::{AtomicU64, AtomicUsize}, + Mutex, + }, + task::Waker, +}; pub fn complex_return_triggers_the_lint() -> i32 { fn foo() -> i32 { @@ -28,9 +36,41 @@ pub fn issue_10413() { } } -pub fn issue_11128() { - use std::mem::drop as unlock; +pub fn issue_11125() { + pub struct Channel { + pub inner: Inner, + pub slots: [UnsafeCell>], + } + + pub struct Inner { + pub join_wakers: Mutex>, + pub ref_count: AtomicUsize, + pub sender_wakers: Mutex>, + pub status: AtomicU64, + } + pub struct SendValue<'s, T> { + pub channel: &'s Channel, + pub registered_waker: Option, + pub value: Option, + } + + impl<'s, T> Drop for SendValue<'s, T> { + fn drop(&mut self) { + if let Some(waker) = self.registered_waker.take() { + let mut sender_wakers = self.channel.inner.sender_wakers.lock().unwrap(); + let idx_opt = sender_wakers.iter().position(|w| w.will_wake(&waker)); + if let Some(idx) = idx_opt { + let local_waker = sender_wakers.swap_remove(idx); + unlock(sender_wakers); + drop(local_waker); + } + } + } + } +} + +pub fn issue_11128() { struct Foo { droppable: Option>, mutex: Mutex>, diff --git a/tests/ui/significant_drop_tightening.rs b/tests/ui/significant_drop_tightening.rs index f7fa65ea9227..d3ee348d2751 100644 --- a/tests/ui/significant_drop_tightening.rs +++ b/tests/ui/significant_drop_tightening.rs @@ -2,7 +2,15 @@ #![warn(clippy::significant_drop_tightening)] -use std::sync::Mutex; +use std::{ + cell::UnsafeCell, + mem::{drop as unlock, MaybeUninit}, + sync::{ + atomic::{AtomicU64, AtomicUsize}, + Mutex, + }, + task::Waker, +}; pub fn complex_return_triggers_the_lint() -> i32 { fn foo() -> i32 { @@ -27,9 +35,41 @@ pub fn issue_10413() { } } -pub fn issue_11128() { - use std::mem::drop as unlock; +pub fn issue_11125() { + pub struct Channel { + pub inner: Inner, + pub slots: [UnsafeCell>], + } + + pub struct Inner { + pub join_wakers: Mutex>, + pub ref_count: AtomicUsize, + pub sender_wakers: Mutex>, + pub status: AtomicU64, + } + pub struct SendValue<'s, T> { + pub channel: &'s Channel, + pub registered_waker: Option, + pub value: Option, + } + + impl<'s, T> Drop for SendValue<'s, T> { + fn drop(&mut self) { + if let Some(waker) = self.registered_waker.take() { + let mut sender_wakers = self.channel.inner.sender_wakers.lock().unwrap(); + let idx_opt = sender_wakers.iter().position(|w| w.will_wake(&waker)); + if let Some(idx) = idx_opt { + let local_waker = sender_wakers.swap_remove(idx); + unlock(sender_wakers); + drop(local_waker); + } + } + } + } +} + +pub fn issue_11128() { struct Foo { droppable: Option>, mutex: Mutex>, diff --git a/tests/ui/significant_drop_tightening.stderr b/tests/ui/significant_drop_tightening.stderr index ca4fede17c93..6195299d3bf0 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:12:9 + --> $DIR/significant_drop_tightening.rs:20:9 | LL | pub fn complex_return_triggers_the_lint() -> i32 { | __________________________________________________- @@ -23,7 +23,7 @@ LL + drop(lock); | error: temporary with significant `Drop` can be early dropped - --> $DIR/significant_drop_tightening.rs:79:13 + --> $DIR/significant_drop_tightening.rs:119:13 | LL | / { LL | | let mutex = Mutex::new(1i32); @@ -43,7 +43,7 @@ LL + drop(lock); | error: temporary with significant `Drop` can be early dropped - --> $DIR/significant_drop_tightening.rs:100:13 + --> $DIR/significant_drop_tightening.rs:140:13 | LL | / { LL | | let mutex = Mutex::new(1i32); @@ -67,7 +67,7 @@ LL + | error: temporary with significant `Drop` can be early dropped - --> $DIR/significant_drop_tightening.rs:106:17 + --> $DIR/significant_drop_tightening.rs:146:17 | LL | / { LL | | let mutex = Mutex::new(vec![1i32]);