feat: Add a way to reserve many permits on bounded mpsc channel
## Motivation

I am in a situation where I need to be able to efficiently reserve `n` permit from the same `mpsc::bounded` channel. Because the `Semaphore` API already implement the possibility to reserve `n` permit. It is quite easy to propagate this API to the `mpsc::bounded` API. More details on this need can be found on the corresponding issue : 
* Fixes #6174 

## Solution

In order to avoid any API breaking change rather than adding a `u32` field on the current `Permit` struct I added : 
* a `ManyPermit` struct
* a `reserve_many(n: u32)` fn on the `Sender` struct
* a `try_reserve_many(n: u32)` fn on the `Sender` struct
**Is your feature request related to a problem? Please describe.**
I'm making a library where I'm exposing an API that transforms a message into many payloads, then insert them into an `mpsc::channel`. Because I want to be able to return an error with the **original** message if the channel is full I need to use the `Permit` API. However because I send `n` payload for `1` message I need to be able to ask `n Permit` efficiently before doing the message transformation. 

**Describe the solution you'd like**
I noticed that the `Semaphore` API already has the possibility to ask `n` Permit and that the Permit API provided by the `mpsc::channel` is just a layer on top of it. So it shouldn't be too difficult to change the API. It could be something like that: 
```rust
pub struct ManyPermit<'a, T> {
    chan: &'a chan::Tx<T, Semaphore>,
    n: u32,
}
```

```rust
pub fn try_reserve_many(&self, n: u32) -> Result<ManyPermit<'_, T>, TrySendError<()>> {
    match self.chan.semaphore().semaphore.try_acquire(n) {
        Ok(()) => {}
        Err(TryAcquireError::Closed) => return Err(TrySendError::Closed(())),
        Err(TryAcquireError::NoPermits) => return Err(TrySendError::Full(())),
    }

    Ok(ManyPermit {
        chan: &self.chan,
        n,
    })
}
```

```rust
impl<T> ManyPermit<'_, T> {
    pub fn send(&mut self, value: T) {
				// Behavior here still needs some clarification between :
				// * returning an error
				// * Doing nothing
				// * Panic
        if self.n > 0 {
            self.chan.send(value);
            self.n -= 1;
        }
    }
}

impl<T> Drop for ManyPermit<'_, T> {
    fn drop(&mut self) {
        use chan::Semaphore;

        let semaphore = self.chan.semaphore();

        // Add the remaining permits back to the semaphore
        semaphore.add_permits(self.n as usize);

        // If this is the last sender for this channel, wake the receiver so
        // that it can be notified that the channel is closed.
        if semaphore.is_closed() && semaphore.is_idle() {
            self.chan.wake_rx();
        }
    }
}
```

**Describe alternatives you've considered**
There are two other possibilitie I considered:
* Ask multiple permits and then return a `Vec<Permit>` but this would allocate a new vec, so it is quite inneficient.
* Put a `Semaphore` with the same size next to my sender and synchronize it with my sender to track the number of given permits.

**Additional context**
I'm willing to work on this feature if it is accepted.

Add a way to request many permits on a `mpsc::channel`
diff --git a/tokio/src/sync/batch_semaphore.rs b/tokio/src/sync/batch_semaphore.rs
index 35de9a57436..aa23dea7d3c 100644
--- a/tokio/src/sync/batch_semaphore.rs
+++ b/tokio/src/sync/batch_semaphore.rs
@@ -71,7 +71,7 @@ pub struct AcquireError(());
 pub(crate) struct Acquire<'a> {
     node: Waiter,
     semaphore: &'a Semaphore,
-    num_permits: u32,
+    num_permits: usize,
     queued: bool,
 }
 
@@ -262,13 +262,13 @@ impl Semaphore {
         self.permits.load(Acquire) & Self::CLOSED == Self::CLOSED
     }
 
-    pub(crate) fn try_acquire(&self, num_permits: u32) -> Result<(), TryAcquireError> {
+    pub(crate) fn try_acquire(&self, num_permits: usize) -> Result<(), TryAcquireError> {
         assert!(
-            num_permits as usize <= Self::MAX_PERMITS,
+            num_permits <= Self::MAX_PERMITS,
             "a semaphore may not have more than MAX_PERMITS permits ({})",
             Self::MAX_PERMITS
         );
-        let num_permits = (num_permits as usize) << Self::PERMIT_SHIFT;
+        let num_permits = num_permits << Self::PERMIT_SHIFT;
         let mut curr = self.permits.load(Acquire);
         loop {
             // Has the semaphore closed?
@@ -293,7 +293,7 @@ impl Semaphore {
         }
     }
 
-    pub(crate) fn acquire(&self, num_permits: u32) -> Acquire<'_> {
+    pub(crate) fn acquire(&self, num_permits: usize) -> Acquire<'_> {
         Acquire::new(self, num_permits)
     }
 
@@ -371,7 +371,7 @@ impl Semaphore {
     fn poll_acquire(
         &self,
         cx: &mut Context<'_>,
-        num_permits: u32,
+        num_permits: usize,
         node: Pin<&mut Waiter>,
         queued: bool,
     ) -> Poll<Result<(), AcquireError>> {
@@ -380,7 +380,7 @@ impl Semaphore {
         let needed = if queued {
             node.state.load(Acquire) << Self::PERMIT_SHIFT
         } else {
-            (num_permits as usize) << Self::PERMIT_SHIFT
+            num_permits << Self::PERMIT_SHIFT
         };
 
         let mut lock = None;
@@ -506,12 +506,12 @@ impl fmt::Debug for Semaphore {
 
 impl Waiter {
     fn new(
-        num_permits: u32,
+        num_permits: usize,
         #[cfg(all(tokio_unstable, feature = "tracing"))] ctx: trace::AsyncOpTracingCtx,
     ) -> Self {
         Waiter {
             waker: UnsafeCell::new(None),
-            state: AtomicUsize::new(num_permits as usize),
+            state: AtomicUsize::new(num_permits),
             pointers: linked_list::Pointers::new(),
             #[cfg(all(tokio_unstable, feature = "tracing"))]
             ctx,
@@ -591,7 +591,7 @@ impl Future for Acquire<'_> {
 }
 
 impl<'a> Acquire<'a> {
-    fn new(semaphore: &'a Semaphore, num_permits: u32) -> Self {
+    fn new(semaphore: &'a Semaphore, num_permits: usize) -> Self {
         #[cfg(any(not(tokio_unstable), not(feature = "tracing")))]
         return Self {
             node: Waiter::new(num_permits),
@@ -635,14 +635,14 @@ impl<'a> Acquire<'a> {
         });
     }
 
-    fn project(self: Pin<&mut Self>) -> (Pin<&mut Waiter>, &Semaphore, u32, &mut bool) {
+    fn project(self: Pin<&mut Self>) -> (Pin<&mut Waiter>, &Semaphore, usize, &mut bool) {
         fn is_unpin<T: Unpin>() {}
         unsafe {
             // Safety: all fields other than `node` are `Unpin`
 
             is_unpin::<&Semaphore>();
             is_unpin::<&mut bool>();
-            is_unpin::<u32>();
+            is_unpin::<usize>();
 
             let this = self.get_unchecked_mut();
             (
@@ -673,7 +673,7 @@ impl Drop for Acquire<'_> {
         // Safety: we have locked the wait list.
         unsafe { waiters.queue.remove(node) };
 
-        let acquired_permits = self.num_permits as usize - self.node.state.load(Acquire);
+        let acquired_permits = self.num_permits - self.node.state.load(Acquire);
         if acquired_permits > 0 {
             self.semaphore.add_permits_locked(acquired_permits, waiters);
         }
diff --git a/tokio/src/sync/mpsc/bounded.rs b/tokio/src/sync/mpsc/bounded.rs
index 3a795d55774..a1e0a82d9e2 100644
--- a/tokio/src/sync/mpsc/bounded.rs
+++ b/tokio/src/sync/mpsc/bounded.rs
@@ -68,6 +68,18 @@ pub struct Permit<'a, T> {
     chan: &'a chan::Tx<T, Semaphore>,
 }
 
+/// An [`Iterator`] of [`Permit`] that can be used to hold `n` slots in the channel.
+///
+/// `PermitIterator` values are returned by [`Sender::reserve_many()`] and [`Sender::try_reserve_many()`]
+/// and are used to guarantee channel capacity before generating `n` messages to send.
+///
+/// [`Sender::reserve_many()`]: Sender::reserve_many
+/// [`Sender::try_reserve_many()`]: Sender::try_reserve_many
+pub struct PermitIterator<'a, T> {
+    chan: &'a chan::Tx<T, Semaphore>,
+    n: usize,
+}
+
 /// Owned permit to send one value into the channel.
 ///
 /// This is identical to the [`Permit`] type, except that it moves the sender
@@ -926,10 +938,74 @@ impl<T> Sender<T> {
     /// }
     /// ```
     pub async fn reserve(&self) -> Result<Permit<'_, T>, SendError<()>> {
-        self.reserve_inner().await?;
+        self.reserve_inner(1).await?;
         Ok(Permit { chan: &self.chan })
     }
 
+    /// Waits for channel capacity. Once capacity to send `n` messages is
+    /// available, it is reserved for the caller.
+    ///
+    /// If the channel is full or if there are fewer than `n` permits available, the function waits
+    /// for the number of unreceived messages to become `n` less than the channel capacity.
+    /// Capacity to send `n` message is then reserved for the caller.
+    ///
+    /// A [`PermitIterator`] is returned to track the reserved capacity.
+    /// You can call this [`Iterator`] until it is exhausted to
+    /// get a [`Permit`] and then call [`Permit::send`]. This function is similar to
+    /// [`try_reserve_many`] except it awaits for the slots to become available.
+    ///
+    /// If the channel is closed, the function returns a [`SendError`].
+    ///
+    /// Dropping [`PermitIterator`] without consuming it entirely releases the remaining
+    /// permits back to the channel.
+    ///
+    /// [`PermitIterator`]: PermitIterator
+    /// [`Permit`]: Permit
+    /// [`send`]: Permit::send
+    /// [`try_reserve_many`]: Sender::try_reserve_many
+    ///
+    /// # Cancel safety
+    ///
+    /// This channel uses a queue to ensure that calls to `send` and `reserve_many`
+    /// complete in the order they were requested. Cancelling a call to
+    /// `reserve_many` makes you lose your place in the queue.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use tokio::sync::mpsc;
+    ///
+    /// #[tokio::main]
+    /// async fn main() {
+    ///     let (tx, mut rx) = mpsc::channel(2);
+    ///
+    ///     // Reserve capacity
+    ///     let mut permit = tx.reserve_many(2).await.unwrap();
+    ///
+    ///     // Trying to send directly on the `tx` will fail due to no
+    ///     // available capacity.
+    ///     assert!(tx.try_send(123).is_err());
+    ///
+    ///     // Sending with the permit iterator succeeds
+    ///     permit.next().unwrap().send(456);
+    ///     permit.next().unwrap().send(457);
+    ///
+    ///     // The iterator should now be exhausted
+    ///     assert!(permit.next().is_none());
+    ///     
+    ///     // The value sent on the permit is received
+    ///     assert_eq!(rx.recv().await.unwrap(), 456);
+    ///     assert_eq!(rx.recv().await.unwrap(), 457);
+    /// }
+    /// ```
+    pub async fn reserve_many(&self, n: usize) -> Result<PermitIterator<'_, T>, SendError<()>> {
+        self.reserve_inner(n).await?;
+        Ok(PermitIterator {
+            chan: &self.chan,
+            n,
+        })
+    }
+
     /// Waits for channel capacity, moving the `Sender` and returning an owned
     /// permit. Once capacity to send one message is available, it is reserved
     /// for the caller.
@@ -1011,16 +1087,19 @@ impl<T> Sender<T> {
     /// [`send`]: OwnedPermit::send
     /// [`Arc::clone`]: std::sync::Arc::clone
     pub async fn reserve_owned(self) -> Result<OwnedPermit<T>, SendError<()>> {
-        self.reserve_inner().await?;
+        self.reserve_inner(1).await?;
         Ok(OwnedPermit {
             chan: Some(self.chan),
         })
     }
 
-    async fn reserve_inner(&self) -> Result<(), SendError<()>> {
+    async fn reserve_inner(&self, n: usize) -> Result<(), SendError<()>> {
         crate::trace::async_trace_leaf().await;
 
-        match self.chan.semaphore().semaphore.acquire(1).await {
+        if n > self.max_capacity() {
+            return Err(SendError(()));
+        }
+        match self.chan.semaphore().semaphore.acquire(n).await {
             Ok(()) => Ok(()),
             Err(_) => Err(SendError(())),
         }
@@ -1079,6 +1158,91 @@ impl<T> Sender<T> {
         Ok(Permit { chan: &self.chan })
     }
 
+    /// Tries to acquire `n` slots in the channel without waiting for the slot to become
+    /// available.
+    ///
+    /// A [`PermitIterator`] is returned to track the reserved capacity.
+    /// You can call this [`Iterator`] until it is exhausted to
+    /// get a [`Permit`] and then call [`Permit::send`]. This function is similar to
+    /// [`reserve_many`] except it does not await for the slots to become available.
+    ///
+    /// If there are fewer than `n` permits available on the channel, then
+    /// this function will return a [`TrySendError::Full`]. If the channel is closed
+    /// this function will return a [`TrySendError::Closed`].
+    ///
+    /// Dropping [`PermitIterator`] without consuming it entirely releases the remaining
+    /// permits back to the channel.
+    ///
+    /// [`PermitIterator`]: PermitIterator
+    /// [`send`]: Permit::send
+    /// [`reserve_many`]: Sender::reserve_many
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use tokio::sync::mpsc;
+    ///
+    /// #[tokio::main]
+    /// async fn main() {
+    ///     let (tx, mut rx) = mpsc::channel(2);
+    ///
+    ///     // Reserve capacity
+    ///     let mut permit = tx.try_reserve_many(2).unwrap();
+    ///
+    ///     // Trying to send directly on the `tx` will fail due to no
+    ///     // available capacity.
+    ///     assert!(tx.try_send(123).is_err());
+    ///
+    ///     // Trying to reserve an additional slot on the `tx` will
+    ///     // fail because there is no capacity.
+    ///     assert!(tx.try_reserve().is_err());
+    ///
+    ///     // Sending with the permit iterator succeeds
+    ///     permit.next().unwrap().send(456);
+    ///     permit.next().unwrap().send(457);
+    ///
+    ///     // The iterator should now be exhausted
+    ///     assert!(permit.next().is_none());
+    ///
+    ///     // The value sent on the permit is received
+    ///     assert_eq!(rx.recv().await.unwrap(), 456);
+    ///     assert_eq!(rx.recv().await.unwrap(), 457);
+    ///     
+    ///     // Trying to call try_reserve_many with 0 will return an empty iterator
+    ///     let mut permit = tx.try_reserve_many(0).unwrap();
+    ///     assert!(permit.next().is_none());
+    ///
+    ///     // Trying to call try_reserve_many with a number greater than the channel
+    ///     // capacity will return an error
+    ///     let permit = tx.try_reserve_many(3);
+    ///     assert!(permit.is_err());
+    ///
+    ///     // Trying to call try_reserve_many on a closed channel will return an error
+    ///     drop(rx);
+    ///     let permit = tx.try_reserve_many(1);
+    ///     assert!(permit.is_err());
+    ///
+    ///     let permit = tx.try_reserve_many(0);
+    ///     assert!(permit.is_err());
+    /// }
+    /// ```
+    pub fn try_reserve_many(&self, n: usize) -> Result<PermitIterator<'_, T>, TrySendError<()>> {
+        if n > self.max_capacity() {
+            return Err(TrySendError::Full(()));
+        }
+
+        match self.chan.semaphore().semaphore.try_acquire(n) {
+            Ok(()) => {}
+            Err(TryAcquireError::Closed) => return Err(TrySendError::Closed(())),
+            Err(TryAcquireError::NoPermits) => return Err(TrySendError::Full(())),
+        }
+
+        Ok(PermitIterator {
+            chan: &self.chan,
+            n,
+        })
+    }
+
     /// Tries to acquire a slot in the channel without waiting for the slot to become
     /// available, returning an owned permit.
     ///
@@ -1355,6 +1519,58 @@ impl<T> fmt::Debug for Permit<'_, T> {
     }
 }
 
+// ===== impl PermitIterator =====
+
+impl<'a, T> Iterator for PermitIterator<'a, T> {
+    type Item = Permit<'a, T>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        if self.n == 0 {
+            return None;
+        }
+
+        self.n -= 1;
+        Some(Permit { chan: self.chan })
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let n = self.n;
+        (n, Some(n))
+    }
+}
+impl<T> ExactSizeIterator for PermitIterator<'_, T> {}
+impl<T> std::iter::FusedIterator for PermitIterator<'_, T> {}
+
+impl<T> Drop for PermitIterator<'_, T> {
+    fn drop(&mut self) {
+        use chan::Semaphore;
+
+        if self.n == 0 {
+            return;
+        }
+
+        let semaphore = self.chan.semaphore();
+
+        // Add the remaining permits back to the semaphore
+        semaphore.add_permits(self.n);
+
+        // If this is the last sender for this channel, wake the receiver so
+        // that it can be notified that the channel is closed.
+        if semaphore.is_closed() && semaphore.is_idle() {
+            self.chan.wake_rx();
+        }
+    }
+}
+
+impl<T> fmt::Debug for PermitIterator<'_, T> {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt.debug_struct("PermitIterator")
+            .field("chan", &self.chan)
+            .field("capacity", &self.n)
+            .finish()
+    }
+}
+
 // ===== impl Permit =====
 
 impl<T> OwnedPermit<T> {
diff --git a/tokio/src/sync/mpsc/mod.rs b/tokio/src/sync/mpsc/mod.rs
index b2af084b2ae..052620be1a9 100644
--- a/tokio/src/sync/mpsc/mod.rs
+++ b/tokio/src/sync/mpsc/mod.rs
@@ -95,7 +95,9 @@
 pub(super) mod block;
 
 mod bounded;
-pub use self::bounded::{channel, OwnedPermit, Permit, Receiver, Sender, WeakSender};
+pub use self::bounded::{
+    channel, OwnedPermit, Permit, PermitIterator, Receiver, Sender, WeakSender,
+};
 
 mod chan;
 
diff --git a/tokio/src/sync/rwlock.rs b/tokio/src/sync/rwlock.rs
index 877458a57fb..37cf73c5905 100644
--- a/tokio/src/sync/rwlock.rs
+++ b/tokio/src/sync/rwlock.rs
@@ -772,7 +772,7 @@ impl<T: ?Sized> RwLock<T> {
     /// ```
     pub async fn write(&self) -> RwLockWriteGuard<'_, T> {
         let acquire_fut = async {
-            self.s.acquire(self.mr).await.unwrap_or_else(|_| {
+            self.s.acquire(self.mr as usize).await.unwrap_or_else(|_| {
                 // The semaphore was closed. but, we never explicitly close it, and we have a
                 // handle to it through the Arc, which means that this can never happen.
                 unreachable!()
@@ -907,7 +907,7 @@ impl<T: ?Sized> RwLock<T> {
         let resource_span = self.resource_span.clone();
 
         let acquire_fut = async {
-            self.s.acquire(self.mr).await.unwrap_or_else(|_| {
+            self.s.acquire(self.mr as usize).await.unwrap_or_else(|_| {
                 // The semaphore was closed. but, we never explicitly close it, and we have a
                 // handle to it through the Arc, which means that this can never happen.
                 unreachable!()
@@ -971,7 +971,7 @@ impl<T: ?Sized> RwLock<T> {
     /// }
     /// ```
     pub fn try_write(&self) -> Result<RwLockWriteGuard<'_, T>, TryLockError> {
-        match self.s.try_acquire(self.mr) {
+        match self.s.try_acquire(self.mr as usize) {
             Ok(permit) => permit,
             Err(TryAcquireError::NoPermits) => return Err(TryLockError(())),
             Err(TryAcquireError::Closed) => unreachable!(),
@@ -1029,7 +1029,7 @@ impl<T: ?Sized> RwLock<T> {
     /// }
     /// ```
     pub fn try_write_owned(self: Arc<Self>) -> Result<OwnedRwLockWriteGuard<T>, TryLockError> {
-        match self.s.try_acquire(self.mr) {
+        match self.s.try_acquire(self.mr as usize) {
             Ok(permit) => permit,
             Err(TryAcquireError::NoPermits) => return Err(TryLockError(())),
             Err(TryAcquireError::Closed) => unreachable!(),
diff --git a/tokio/src/sync/semaphore.rs b/tokio/src/sync/semaphore.rs
index 8b8fdb23871..25e4134373c 100644
--- a/tokio/src/sync/semaphore.rs
+++ b/tokio/src/sync/semaphore.rs
@@ -565,7 +565,7 @@ impl Semaphore {
     pub async fn acquire_many(&self, n: u32) -> Result<SemaphorePermit<'_>, AcquireError> {
         #[cfg(all(tokio_unstable, feature = "tracing"))]
         trace::async_op(
-            || self.ll_sem.acquire(n),
+            || self.ll_sem.acquire(n as usize),
             self.resource_span.clone(),
             "Semaphore::acquire_many",
             "poll",
@@ -574,7 +574,7 @@ impl Semaphore {
         .await?;
 
         #[cfg(not(all(tokio_unstable, feature = "tracing")))]
-        self.ll_sem.acquire(n).await?;
+        self.ll_sem.acquire(n as usize).await?;
 
         Ok(SemaphorePermit {
             sem: self,
@@ -646,7 +646,7 @@ impl Semaphore {
     /// [`TryAcquireError::NoPermits`]: crate::sync::TryAcquireError::NoPermits
     /// [`SemaphorePermit`]: crate::sync::SemaphorePermit
     pub fn try_acquire_many(&self, n: u32) -> Result<SemaphorePermit<'_>, TryAcquireError> {
-        match self.ll_sem.try_acquire(n) {
+        match self.ll_sem.try_acquire(n as usize) {
             Ok(()) => Ok(SemaphorePermit {
                 sem: self,
                 permits: n,
@@ -764,14 +764,14 @@ impl Semaphore {
     ) -> Result<OwnedSemaphorePermit, AcquireError> {
         #[cfg(all(tokio_unstable, feature = "tracing"))]
         let inner = trace::async_op(
-            || self.ll_sem.acquire(n),
+            || self.ll_sem.acquire(n as usize),
             self.resource_span.clone(),
             "Semaphore::acquire_many_owned",
             "poll",
             true,
         );
         #[cfg(not(all(tokio_unstable, feature = "tracing")))]
-        let inner = self.ll_sem.acquire(n);
+        let inner = self.ll_sem.acquire(n as usize);
 
         inner.await?;
         Ok(OwnedSemaphorePermit {
@@ -855,7 +855,7 @@ impl Semaphore {
         self: Arc<Self>,
         n: u32,
     ) -> Result<OwnedSemaphorePermit, TryAcquireError> {
-        match self.ll_sem.try_acquire(n) {
+        match self.ll_sem.try_acquire(n as usize) {
             Ok(()) => Ok(OwnedSemaphorePermit {
                 sem: self,
                 permits: n,

diff --git a/tokio/tests/sync_mpsc.rs b/tokio/tests/sync_mpsc.rs
index a5c15a4cfc6..1b581ce98c1 100644
--- a/tokio/tests/sync_mpsc.rs
+++ b/tokio/tests/sync_mpsc.rs
@@ -522,6 +522,79 @@ async fn try_send_fail_with_try_recv() {
     assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
 }
 
+#[maybe_tokio_test]
+async fn reserve_many_above_cap() {
+    const MAX_PERMITS: usize = tokio::sync::Semaphore::MAX_PERMITS;
+    let (tx, _rx) = mpsc::channel::<()>(1);
+
+    assert_err!(tx.reserve_many(2).await);
+    assert_err!(tx.reserve_many(MAX_PERMITS + 1).await);
+    assert_err!(tx.reserve_many(usize::MAX).await);
+}
+
+#[test]
+fn try_reserve_many_zero() {
+    let (tx, rx) = mpsc::channel::<()>(1);
+
+    // Succeeds when not closed.
+    assert!(assert_ok!(tx.try_reserve_many(0)).next().is_none());
+
+    // Even when channel is full.
+    tx.try_send(()).unwrap();
+    assert!(assert_ok!(tx.try_reserve_many(0)).next().is_none());
+
+    drop(rx);
+
+    // Closed error when closed.
+    assert_eq!(
+        assert_err!(tx.try_reserve_many(0)),
+        TrySendError::Closed(())
+    );
+}
+
+#[maybe_tokio_test]
+async fn reserve_many_zero() {
+    let (tx, rx) = mpsc::channel::<()>(1);
+
+    // Succeeds when not closed.
+    assert!(assert_ok!(tx.reserve_many(0).await).next().is_none());
+
+    // Even when channel is full.
+    tx.send(()).await.unwrap();
+    assert!(assert_ok!(tx.reserve_many(0).await).next().is_none());
+
+    drop(rx);
+
+    // Closed error when closed.
+    assert_err!(tx.reserve_many(0).await);
+}
+
+#[maybe_tokio_test]
+async fn try_reserve_many_edge_cases() {
+    const MAX_PERMITS: usize = tokio::sync::Semaphore::MAX_PERMITS;
+
+    let (tx, rx) = mpsc::channel::<()>(1);
+
+    let mut permit = assert_ok!(tx.try_reserve_many(0));
+    assert!(permit.next().is_none());
+
+    let permit = tx.try_reserve_many(MAX_PERMITS + 1);
+    match assert_err!(permit) {
+        TrySendError::Full(..) => {}
+        _ => panic!(),
+    }
+
+    let permit = tx.try_reserve_many(usize::MAX);
+    match assert_err!(permit) {
+        TrySendError::Full(..) => {}
+        _ => panic!(),
+    }
+
+    // Dropping the receiver should close the channel
+    drop(rx);
+    assert_err!(tx.reserve_many(0).await);
+}
+
 #[maybe_tokio_test]
 async fn try_reserve_fails() {
     let (tx, mut rx) = mpsc::channel(1);
@@ -545,6 +618,87 @@ async fn try_reserve_fails() {
     let _permit = tx.try_reserve().unwrap();
 }
 
+#[maybe_tokio_test]
+async fn reserve_many_and_send() {
+    let (tx, mut rx) = mpsc::channel(100);
+    for i in 0..100 {
+        for permit in assert_ok!(tx.reserve_many(i).await) {
+            permit.send("foo");
+            assert_eq!(rx.recv().await, Some("foo"));
+        }
+        assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
+    }
+}
+#[maybe_tokio_test]
+async fn try_reserve_many_and_send() {
+    let (tx, mut rx) = mpsc::channel(100);
+    for i in 0..100 {
+        for permit in assert_ok!(tx.try_reserve_many(i)) {
+            permit.send("foo");
+            assert_eq!(rx.recv().await, Some("foo"));
+        }
+        assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
+    }
+}
+
+#[maybe_tokio_test]
+async fn reserve_many_on_closed_channel() {
+    let (tx, rx) = mpsc::channel::<()>(100);
+    drop(rx);
+    assert_err!(tx.reserve_many(10).await);
+}
+
+#[maybe_tokio_test]
+async fn try_reserve_many_on_closed_channel() {
+    let (tx, rx) = mpsc::channel::<usize>(100);
+    drop(rx);
+    match assert_err!(tx.try_reserve_many(10)) {
+        TrySendError::Closed(()) => {}
+        _ => panic!(),
+    };
+}
+
+#[maybe_tokio_test]
+async fn try_reserve_many_full() {
+    // Reserve n capacity and send k messages
+    for n in 1..100 {
+        for k in 0..n {
+            let (tx, mut rx) = mpsc::channel::<usize>(n);
+            let permits = assert_ok!(tx.try_reserve_many(n));
+
+            assert_eq!(permits.len(), n);
+            assert_eq!(tx.capacity(), 0);
+
+            match assert_err!(tx.try_reserve_many(1)) {
+                TrySendError::Full(..) => {}
+                _ => panic!(),
+            };
+
+            for permit in permits.take(k) {
+                permit.send(0);
+            }
+            // We only used k permits on the n reserved
+            assert_eq!(tx.capacity(), n - k);
+
+            // We can reserve more permits
+            assert_ok!(tx.try_reserve_many(1));
+
+            // But not more than the current capacity
+            match assert_err!(tx.try_reserve_many(n - k + 1)) {
+                TrySendError::Full(..) => {}
+                _ => panic!(),
+            };
+
+            for _i in 0..k {
+                assert_eq!(rx.recv().await, Some(0));
+            }
+
+            // Now that we've received everything, capacity should be back to n
+            assert_eq!(tx.capacity(), n);
+        }
+    }
+}
+
 #[tokio::test]
 #[cfg(feature = "full")]
 async fn drop_permit_releases_permit() {
@@ -564,6 +718,30 @@ async fn drop_permit_releases_permit() {
     assert_ready_ok!(reserve2.poll());
 }
 
+#[maybe_tokio_test]
+async fn drop_permit_iterator_releases_permits() {
+    // poll_ready reserves capacity, ensure that the capacity is released if tx
+    // is dropped w/o sending a value.
+    for n in 1..100 {
+        let (tx1, _rx) = mpsc::channel::<i32>(n);
+        let tx2 = tx1.clone();
+
+        let permits = assert_ok!(tx1.reserve_many(n).await);
+
+        let mut reserve2 = tokio_test::task::spawn(tx2.reserve_many(n));
+        assert_pending!(reserve2.poll());
+
+        drop(permits);
+
+        assert!(reserve2.is_woken());
+
+        let permits = assert_ready_ok!(reserve2.poll());
+        drop(permits);
+
+        assert_eq!(tx1.capacity(), n);
+    }
+}
+
 #[maybe_tokio_test]
 async fn dropping_rx_closes_channel() {
     let (tx, rx) = mpsc::channel(100);
@@ -573,6 +751,7 @@ async fn dropping_rx_closes_channel() {
 
     drop(rx);
     assert_err!(tx.reserve().await);
+    assert_err!(tx.reserve_many(10).await);
     assert_eq!(1, Arc::strong_count(&msg));
 }
 

{"signal::unix::tests::into_c_int": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::rwlock::bounds": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::tests::inject::push_and_pop": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "util::memchr::tests::memchr_all": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "open_options_write": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "signal::reusable_box::test::test_different_futures": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "path_read_write": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "io::util::lines::tests::assert_unpin": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::cancel_acquire_releases_permits": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "open_options_custom_flags_linux": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "basic_write": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::try_acquire_one_available": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "signal::registry::tests::broadcast_returns_if_at_least_one_event_fired": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "pin": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::poll_acquire_many_unavailable": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::broadcast::tests::receiver_count_on_channel_constructor": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::release_permits_at_drop": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "basic_read": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::time::wheel::level::test::test_slot_for": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::read_err_then_read_success": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "file_debug_fmt": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::incomplete_read_followed_by_flush": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "task::local::tests::local_current_thread_scheduler": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "process::test::no_kill_if_already_killed": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "remove": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::mpsc::block::assert_no_stack_overflow": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "read_file_from_unix_fd": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "process::imp::orphan::test::no_reap_if_no_signal_received": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::open_set_len_ok": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::close_semaphore_notifies_permit2": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::incomplete_partial_read_followed_by_write": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "util::memchr::tests::memchr_test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::open_set_len_err": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::read_with_smaller_buf": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::sync_all_ordered_after_write": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "io::util::buf_reader::tests::assert_unpin": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::incomplete_read_followed_by_write": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::time::tests::poll_process_levels_targeted": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "open_options_create": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "unix_fd_is_valid": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::sync_data_ordered_after_write": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::time::tests::single_timer": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "util::linked_list::tests::push_pop_push_pop": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "process::imp::orphan::test::does_nothing_if_signal_could_not_be_registered": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::max_permits_doesnt_panic": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "signal::unix::tests::signal_enable_error_on_forbidden_input": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "io::stdio_common::tests::test_pseudo_text": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "coop_budget_udp_send_recv": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::write_seek_flush_err": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::notify::notify_clones_waker_before_lock": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::tests::inject::push_batch_and_pop": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::scheduler::multi_thread::queue::test_local_queue_capacity": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "io::util::sink::tests::assert_unpin": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::poll_acquire_many_available": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "open_options_create_new": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::read_with_bigger_buf": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "open_options_truncate": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::broadcast::tests::receiver_count_on_sender_constructor": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "signal::reusable_box::test::test_different_sizes": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "util::linked_list::tests::const_new": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::try_acquire_one_unavailable": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::flush_while_idle": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::scheduler::multi_thread::idle::test_state": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::try_acquire_many_available": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::tests::queue::steal_batch": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "process::imp::reap::test::drop_reaps_if_possible": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "canonicalize_root_dir_unix": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "write_into_std_immediate": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "io::util::buf_stream::tests::assert_unpin": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "process::test::kills_on_drop_if_specified": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "build_dir_mode_read_only": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::open_write": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::poll_acquire_one_zero_permits": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::tests::queue::fits_256_one_at_a_time": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "io::util::split::tests::assert_unpin": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "signal::unix::tests::from_c_int": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::task::core::header_lte_cache_line": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::read_twice_before_dispatch": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::coop::test::budgeting": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "basic_write_and_shutdown": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "copy": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "create_dir": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "io::util::repeat::tests::assert_unpin": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::write_seek_write_err": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::open_read": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "io::util::take::tests::assert_unpin": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "util::linked_list::tests::remove_by_address": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "coop": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "process::imp::reap::test::drop_enqueues_orphan_if_wait_fails": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::tests::queue::stress1": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::poll_acquire_one_available": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::atomic_waker::basic_usage": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test_symlink": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "io::util::buf_writer::tests::assert_unpin": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "open_options_append": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "process::test::no_kill_if_reaped": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "io::stdio_common::tests::test_splitter": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::write_read_flush_err": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::task::list::tests::test_id_not_broken": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "util::linked_list::tests::push_and_drain": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::notify::notify_waiters_handles_panicking_waker": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::time::wheel::test::test_level_for": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::write_write_err": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "signal::registry::tests::record_invalid_event_does_nothing": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::time::tests::reset_future": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "echo_server": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::close_semaphore_prevents_acquire": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "read_dir_entry_info": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "create_all": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "io::util::chain::tests::assert_unpin": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "process::imp::reap::test::kill": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::atomic_waker::wake_without_register": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test_hard_link": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::write_read_write_err": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::mutex::bounds": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::incomplete_flush_followed_by_write": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "write_into_std": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::time::tests::change_waker": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "process::imp::reap::test::reaper": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "util::idle_notified_set::tests::join_set_test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::tests::queue::stress2": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "signal::registry::tests::smoke": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "io::util::empty::tests::assert_unpin": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::time::tests::poll_process_levels": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::notify::notify_simple": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::sync_data_err_ordered_after_write": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::atomic_waker::atomic_waker_panic_safe": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::notify::watch_test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "signal::reusable_box::test::test_zero_sized": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "write_to_clone": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::semaphore::bounds": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "compile_fail_full": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::busy_file_seek_error": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::poll_acquire_one_unavailable": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "process::test::no_kill_on_drop_by_default": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "signal::unix::tests::signal_enable_error_on_invalid_input": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "io::util::copy_buf::tests::assert_unpin": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "copy_permissions": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "process::imp::orphan::test::does_not_register_signal_if_queue_empty": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "process::imp::orphan::test::no_reap_if_signal_lock_held": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::write_twice_before_dispatch": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::read_err": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::partial_read_set_len_ok": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "build_dir": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "read_inherent": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "read_file_from_std": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::tests::queue::fits_256_all_at_once": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::write_with_buffer_larger_than_max": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::time::tests::drop_timer": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::sync_all_err_ordered_after_write": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::try_acquire_many_unavailable": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::read_with_buffer_larger_than_max": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "util::memchr::tests::memchr_empty": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::tests::task_combinations::test_combinations": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "write_vectored": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "process::imp::orphan::test::drain_attempts_a_single_reap_of_all_queued_orphans": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "write_vectored_and_shutdown": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::tests::queue::fits_256_all_in_chunks": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::tests::inject::pop_n_drains_on_drop": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::close_semaphore_notifies_permit1": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "task::local::tests::wakes_to_local_queue": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "rewind_seek_position": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::tests::queue::overflow": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "open_with_open_options_and_read": {"run": "PASS", "test": "NONE", "fix": "PASS"}}
{"signal::unix::tests::into_c_int": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::rwlock::bounds": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::tests::inject::push_and_pop": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "util::memchr::tests::memchr_all": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "open_options_write": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "signal::reusable_box::test::test_different_futures": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "path_read_write": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "io::util::lines::tests::assert_unpin": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::cancel_acquire_releases_permits": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "open_options_custom_flags_linux": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "basic_write": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::try_acquire_one_available": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "signal::registry::tests::broadcast_returns_if_at_least_one_event_fired": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "pin": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::poll_acquire_many_unavailable": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::broadcast::tests::receiver_count_on_channel_constructor": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::release_permits_at_drop": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "basic_read": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::time::wheel::level::test::test_slot_for": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::read_err_then_read_success": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "file_debug_fmt": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::incomplete_read_followed_by_flush": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "task::local::tests::local_current_thread_scheduler": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "process::test::no_kill_if_already_killed": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "remove": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::mpsc::block::assert_no_stack_overflow": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "read_file_from_unix_fd": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "process::imp::orphan::test::no_reap_if_no_signal_received": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::open_set_len_ok": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::close_semaphore_notifies_permit2": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::incomplete_partial_read_followed_by_write": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "util::memchr::tests::memchr_test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::open_set_len_err": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::read_with_smaller_buf": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::sync_all_ordered_after_write": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "io::util::buf_reader::tests::assert_unpin": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::incomplete_read_followed_by_write": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::time::tests::poll_process_levels_targeted": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "open_options_create": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "unix_fd_is_valid": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::sync_data_ordered_after_write": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::time::tests::single_timer": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "util::linked_list::tests::push_pop_push_pop": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "process::imp::orphan::test::does_nothing_if_signal_could_not_be_registered": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::max_permits_doesnt_panic": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "signal::unix::tests::signal_enable_error_on_forbidden_input": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "io::stdio_common::tests::test_pseudo_text": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "coop_budget_udp_send_recv": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::write_seek_flush_err": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::notify::notify_clones_waker_before_lock": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::tests::inject::push_batch_and_pop": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::scheduler::multi_thread::queue::test_local_queue_capacity": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "io::util::sink::tests::assert_unpin": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::poll_acquire_many_available": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "open_options_create_new": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::read_with_bigger_buf": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "open_options_truncate": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::broadcast::tests::receiver_count_on_sender_constructor": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "signal::reusable_box::test::test_different_sizes": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "util::linked_list::tests::const_new": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::try_acquire_one_unavailable": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::flush_while_idle": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::scheduler::multi_thread::idle::test_state": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::try_acquire_many_available": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::tests::queue::steal_batch": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "process::imp::reap::test::drop_reaps_if_possible": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "canonicalize_root_dir_unix": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "write_into_std_immediate": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "io::util::buf_stream::tests::assert_unpin": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "process::test::kills_on_drop_if_specified": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "build_dir_mode_read_only": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::open_write": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::poll_acquire_one_zero_permits": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::tests::queue::fits_256_one_at_a_time": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "io::util::split::tests::assert_unpin": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "signal::unix::tests::from_c_int": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::task::core::header_lte_cache_line": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::read_twice_before_dispatch": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::coop::test::budgeting": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "basic_write_and_shutdown": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "copy": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "create_dir": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "io::util::repeat::tests::assert_unpin": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::write_seek_write_err": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::open_read": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "io::util::take::tests::assert_unpin": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "util::linked_list::tests::remove_by_address": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "coop": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "process::imp::reap::test::drop_enqueues_orphan_if_wait_fails": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::tests::queue::stress1": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::poll_acquire_one_available": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::atomic_waker::basic_usage": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test_symlink": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "io::util::buf_writer::tests::assert_unpin": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "open_options_append": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "process::test::no_kill_if_reaped": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "io::stdio_common::tests::test_splitter": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::write_read_flush_err": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::task::list::tests::test_id_not_broken": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "util::linked_list::tests::push_and_drain": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::notify::notify_waiters_handles_panicking_waker": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::time::wheel::test::test_level_for": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::write_write_err": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "signal::registry::tests::record_invalid_event_does_nothing": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::time::tests::reset_future": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "echo_server": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::close_semaphore_prevents_acquire": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "read_dir_entry_info": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "create_all": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "io::util::chain::tests::assert_unpin": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "process::imp::reap::test::kill": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::atomic_waker::wake_without_register": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test_hard_link": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::write_read_write_err": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::mutex::bounds": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::incomplete_flush_followed_by_write": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "write_into_std": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::time::tests::change_waker": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "process::imp::reap::test::reaper": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "util::idle_notified_set::tests::join_set_test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::tests::queue::stress2": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "signal::registry::tests::smoke": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "io::util::empty::tests::assert_unpin": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::time::tests::poll_process_levels": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::notify::notify_simple": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::sync_data_err_ordered_after_write": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::atomic_waker::atomic_waker_panic_safe": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::notify::watch_test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "signal::reusable_box::test::test_zero_sized": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "write_to_clone": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::semaphore::bounds": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "compile_fail_full": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::busy_file_seek_error": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::poll_acquire_one_unavailable": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "process::test::no_kill_on_drop_by_default": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "signal::unix::tests::signal_enable_error_on_invalid_input": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "io::util::copy_buf::tests::assert_unpin": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "copy_permissions": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "process::imp::orphan::test::does_not_register_signal_if_queue_empty": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "process::imp::orphan::test::no_reap_if_signal_lock_held": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::write_twice_before_dispatch": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::read_err": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::partial_read_set_len_ok": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "build_dir": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "read_inherent": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "read_file_from_std": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::tests::queue::fits_256_all_at_once": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::write_with_buffer_larger_than_max": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::time::tests::drop_timer": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::sync_all_err_ordered_after_write": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::try_acquire_many_unavailable": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "fs::file::tests::read_with_buffer_larger_than_max": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "util::memchr::tests::memchr_empty": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::tests::task_combinations::test_combinations": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "write_vectored": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "process::imp::orphan::test::drain_attempts_a_single_reap_of_all_queued_orphans": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "write_vectored_and_shutdown": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::tests::queue::fits_256_all_in_chunks": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::tests::inject::pop_n_drains_on_drop": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "sync::tests::semaphore_batch::close_semaphore_notifies_permit1": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "task::local::tests::wakes_to_local_queue": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "rewind_seek_position": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtime::tests::queue::overflow": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "open_with_open_options_and_read": {"run": "PASS", "test": "NONE", "fix": "PASS"}}
{"passed_count": 164, "failed_count": 1, "skipped_count": 0, "passed_tests": ["signal::unix::tests::into_c_int", "sync::rwlock::bounds", "runtime::tests::inject::push_and_pop", "util::memchr::tests::memchr_all", "open_options_write", "signal::reusable_box::test::test_different_futures", "path_read_write", "io::util::lines::tests::assert_unpin", "sync::tests::semaphore_batch::cancel_acquire_releases_permits", "open_options_custom_flags_linux", "basic_write", "sync::tests::semaphore_batch::try_acquire_one_available", "signal::registry::tests::broadcast_returns_if_at_least_one_event_fired", "pin", "sync::tests::semaphore_batch::poll_acquire_many_unavailable", "sync::broadcast::tests::receiver_count_on_channel_constructor", "sync::tests::semaphore_batch::release_permits_at_drop", "basic_read", "runtime::time::wheel::level::test::test_slot_for", "fs::file::tests::read_err_then_read_success", "file_debug_fmt", "fs::file::tests::incomplete_read_followed_by_flush", "task::local::tests::local_current_thread_scheduler", "process::test::no_kill_if_already_killed", "remove", "sync::mpsc::block::assert_no_stack_overflow", "read_file_from_unix_fd", "process::imp::orphan::test::no_reap_if_no_signal_received", "fs::file::tests::open_set_len_ok", "sync::tests::semaphore_batch::close_semaphore_notifies_permit2", "fs::file::tests::incomplete_partial_read_followed_by_write", "util::memchr::tests::memchr_test", "fs::file::tests::open_set_len_err", "fs::file::tests::read_with_smaller_buf", "fs::file::tests::sync_all_ordered_after_write", "io::util::buf_reader::tests::assert_unpin", "fs::file::tests::incomplete_read_followed_by_write", "runtime::time::tests::poll_process_levels_targeted", "open_options_create", "unix_fd_is_valid", "fs::file::tests::sync_data_ordered_after_write", "runtime::time::tests::single_timer", "util::linked_list::tests::push_pop_push_pop", "process::imp::orphan::test::does_nothing_if_signal_could_not_be_registered", "sync::tests::semaphore_batch::max_permits_doesnt_panic", "signal::unix::tests::signal_enable_error_on_forbidden_input", "io::stdio_common::tests::test_pseudo_text", "coop_budget_udp_send_recv", "fs::file::tests::write_seek_flush_err", "sync::tests::notify::notify_clones_waker_before_lock", "runtime::tests::inject::push_batch_and_pop", "runtime::scheduler::multi_thread::queue::test_local_queue_capacity", "io::util::sink::tests::assert_unpin", "sync::tests::semaphore_batch::poll_acquire_many_available", "open_options_create_new", "fs::file::tests::read_with_bigger_buf", "open_options_truncate", "sync::broadcast::tests::receiver_count_on_sender_constructor", "signal::reusable_box::test::test_different_sizes", "util::linked_list::tests::const_new", "sync::tests::semaphore_batch::try_acquire_one_unavailable", "fs::file::tests::flush_while_idle", "runtime::scheduler::multi_thread::idle::test_state", "sync::tests::semaphore_batch::try_acquire_many_available", "runtime::tests::queue::steal_batch", "process::imp::reap::test::drop_reaps_if_possible", "canonicalize_root_dir_unix", "write_into_std_immediate", "open_with_open_options_and_read", "io::util::buf_stream::tests::assert_unpin", "process::test::kills_on_drop_if_specified", "build_dir_mode_read_only", "fs::file::tests::open_write", "sync::tests::semaphore_batch::poll_acquire_one_zero_permits", "runtime::tests::queue::fits_256_one_at_a_time", "io::util::split::tests::assert_unpin", "signal::unix::tests::from_c_int", "runtime::task::core::header_lte_cache_line", "fs::file::tests::read_twice_before_dispatch", "runtime::coop::test::budgeting", "basic_write_and_shutdown", "copy", "create_dir", "io::util::repeat::tests::assert_unpin", "fs::file::tests::write_seek_write_err", "fs::file::tests::open_read", "io::util::take::tests::assert_unpin", "util::linked_list::tests::remove_by_address", "coop", "process::imp::reap::test::drop_enqueues_orphan_if_wait_fails", "runtime::tests::queue::stress1", "sync::tests::semaphore_batch::poll_acquire_one_available", "sync::tests::atomic_waker::basic_usage", "test_symlink", "io::util::buf_writer::tests::assert_unpin", "open_options_append", "process::test::no_kill_if_reaped", "io::stdio_common::tests::test_splitter", "fs::file::tests::write_read_flush_err", "runtime::task::list::tests::test_id_not_broken", "util::linked_list::tests::push_and_drain", "sync::tests::notify::notify_waiters_handles_panicking_waker", "runtime::time::wheel::test::test_level_for", "fs::file::tests::write_write_err", "signal::registry::tests::record_invalid_event_does_nothing", "runtime::time::tests::reset_future", "echo_server", "sync::tests::semaphore_batch::close_semaphore_prevents_acquire", "read_dir_entry_info", "io::util::chain::tests::assert_unpin", "process::imp::reap::test::kill", "sync::tests::atomic_waker::wake_without_register", "test_hard_link", "fs::file::tests::write_read_write_err", "sync::mutex::bounds", "fs::file::tests::incomplete_flush_followed_by_write", "write_into_std", "runtime::time::tests::change_waker", "process::imp::reap::test::reaper", "util::idle_notified_set::tests::join_set_test", "runtime::tests::queue::stress2", "signal::registry::tests::smoke", "io::util::empty::tests::assert_unpin", "runtime::time::tests::poll_process_levels", "sync::tests::notify::notify_simple", "fs::file::tests::sync_data_err_ordered_after_write", "sync::tests::atomic_waker::atomic_waker_panic_safe", "sync::tests::notify::watch_test", "signal::reusable_box::test::test_zero_sized", "write_to_clone", "sync::semaphore::bounds", "compile_fail_full", "fs::file::tests::busy_file_seek_error", "sync::tests::semaphore_batch::poll_acquire_one_unavailable", "process::test::no_kill_on_drop_by_default", "signal::unix::tests::signal_enable_error_on_invalid_input", "io::util::copy_buf::tests::assert_unpin", "copy_permissions", "process::imp::orphan::test::does_not_register_signal_if_queue_empty", "process::imp::orphan::test::no_reap_if_signal_lock_held", "fs::file::tests::write_twice_before_dispatch", "fs::file::tests::read_err", "fs::file::tests::partial_read_set_len_ok", "build_dir", "read_inherent", "read_file_from_std", "runtime::tests::queue::fits_256_all_at_once", "fs::file::tests::write_with_buffer_larger_than_max", "runtime::time::tests::drop_timer", "fs::file::tests::sync_all_err_ordered_after_write", "sync::tests::semaphore_batch::try_acquire_many_unavailable", "fs::file::tests::read_with_buffer_larger_than_max", "util::memchr::tests::memchr_empty", "runtime::tests::task_combinations::test_combinations", "write_vectored", "process::imp::orphan::test::drain_attempts_a_single_reap_of_all_queued_orphans", "write_vectored_and_shutdown", "runtime::tests::queue::fits_256_all_in_chunks", "runtime::tests::inject::pop_n_drains_on_drop", "sync::tests::semaphore_batch::close_semaphore_notifies_permit1", "task::local::tests::wakes_to_local_queue", "rewind_seek_position", "runtime::tests::queue::overflow", "create_all"], "failed_tests": ["open_options_mode"], "skipped_tests": []}
{"passed_count": 0, "failed_count": 0, "skipped_count": 0, "passed_tests": [], "failed_tests": [], "skipped_tests": []}
{"passed_count": 164, "failed_count": 1, "skipped_count": 0, "passed_tests": ["signal::unix::tests::into_c_int", "sync::rwlock::bounds", "runtime::tests::inject::push_and_pop", "util::memchr::tests::memchr_all", "open_options_write", "signal::reusable_box::test::test_different_futures", "path_read_write", "io::util::lines::tests::assert_unpin", "sync::tests::semaphore_batch::cancel_acquire_releases_permits", "open_options_custom_flags_linux", "basic_write", "sync::tests::semaphore_batch::try_acquire_one_available", "signal::registry::tests::broadcast_returns_if_at_least_one_event_fired", "pin", "sync::tests::semaphore_batch::poll_acquire_many_unavailable", "sync::broadcast::tests::receiver_count_on_channel_constructor", "sync::tests::semaphore_batch::release_permits_at_drop", "basic_read", "runtime::time::wheel::level::test::test_slot_for", "fs::file::tests::read_err_then_read_success", "file_debug_fmt", "fs::file::tests::incomplete_read_followed_by_flush", "task::local::tests::local_current_thread_scheduler", "process::test::no_kill_if_already_killed", "remove", "sync::mpsc::block::assert_no_stack_overflow", "read_file_from_unix_fd", "process::imp::orphan::test::no_reap_if_no_signal_received", "fs::file::tests::open_set_len_ok", "sync::tests::semaphore_batch::close_semaphore_notifies_permit2", "fs::file::tests::incomplete_partial_read_followed_by_write", "util::memchr::tests::memchr_test", "fs::file::tests::open_set_len_err", "fs::file::tests::read_with_smaller_buf", "fs::file::tests::sync_all_ordered_after_write", "fs::file::tests::incomplete_read_followed_by_write", "io::util::buf_reader::tests::assert_unpin", "runtime::time::tests::poll_process_levels_targeted", "open_options_create", "unix_fd_is_valid", "fs::file::tests::sync_data_ordered_after_write", "runtime::time::tests::single_timer", "util::linked_list::tests::push_pop_push_pop", "process::imp::orphan::test::does_nothing_if_signal_could_not_be_registered", "sync::tests::semaphore_batch::max_permits_doesnt_panic", "signal::unix::tests::signal_enable_error_on_forbidden_input", "io::stdio_common::tests::test_pseudo_text", "coop_budget_udp_send_recv", "runtime::scheduler::multi_thread::queue::test_local_queue_capacity", "fs::file::tests::write_seek_flush_err", "runtime::tests::inject::push_batch_and_pop", "io::util::sink::tests::assert_unpin", "sync::tests::notify::notify_clones_waker_before_lock", "sync::tests::semaphore_batch::poll_acquire_many_available", "open_options_create_new", "fs::file::tests::read_with_bigger_buf", "open_options_truncate", "sync::broadcast::tests::receiver_count_on_sender_constructor", "signal::reusable_box::test::test_different_sizes", "util::linked_list::tests::const_new", "sync::tests::semaphore_batch::try_acquire_one_unavailable", "fs::file::tests::flush_while_idle", "runtime::scheduler::multi_thread::idle::test_state", "sync::tests::semaphore_batch::try_acquire_many_available", "runtime::tests::queue::steal_batch", "process::imp::reap::test::drop_reaps_if_possible", "canonicalize_root_dir_unix", "write_into_std_immediate", "open_with_open_options_and_read", "io::util::buf_stream::tests::assert_unpin", "process::test::kills_on_drop_if_specified", "build_dir_mode_read_only", "fs::file::tests::open_write", "sync::tests::semaphore_batch::poll_acquire_one_zero_permits", "runtime::tests::queue::fits_256_one_at_a_time", "io::util::split::tests::assert_unpin", "signal::unix::tests::from_c_int", "fs::file::tests::read_twice_before_dispatch", "runtime::task::core::header_lte_cache_line", "runtime::coop::test::budgeting", "basic_write_and_shutdown", "copy", "create_dir", "io::util::repeat::tests::assert_unpin", "fs::file::tests::write_seek_write_err", "fs::file::tests::open_read", "io::util::take::tests::assert_unpin", "util::linked_list::tests::remove_by_address", "coop", "process::imp::reap::test::drop_enqueues_orphan_if_wait_fails", "runtime::tests::queue::stress1", "sync::tests::semaphore_batch::poll_acquire_one_available", "sync::tests::atomic_waker::basic_usage", "test_symlink", "io::util::buf_writer::tests::assert_unpin", "open_options_append", "process::test::no_kill_if_reaped", "io::stdio_common::tests::test_splitter", "fs::file::tests::write_read_flush_err", "runtime::task::list::tests::test_id_not_broken", "util::linked_list::tests::push_and_drain", "sync::tests::notify::notify_waiters_handles_panicking_waker", "runtime::time::wheel::test::test_level_for", "fs::file::tests::write_write_err", "signal::registry::tests::record_invalid_event_does_nothing", "runtime::time::tests::reset_future", "echo_server", "sync::tests::semaphore_batch::close_semaphore_prevents_acquire", "read_dir_entry_info", "io::util::chain::tests::assert_unpin", "process::imp::reap::test::kill", "sync::tests::atomic_waker::wake_without_register", "test_hard_link", "fs::file::tests::write_read_write_err", "sync::mutex::bounds", "fs::file::tests::incomplete_flush_followed_by_write", "write_into_std", "runtime::time::tests::change_waker", "process::imp::reap::test::reaper", "util::idle_notified_set::tests::join_set_test", "runtime::tests::queue::stress2", "signal::registry::tests::smoke", "io::util::empty::tests::assert_unpin", "runtime::time::tests::poll_process_levels", "sync::tests::notify::notify_simple", "fs::file::tests::sync_data_err_ordered_after_write", "sync::tests::atomic_waker::atomic_waker_panic_safe", "sync::tests::notify::watch_test", "signal::reusable_box::test::test_zero_sized", "write_to_clone", "sync::semaphore::bounds", "compile_fail_full", "fs::file::tests::busy_file_seek_error", "sync::tests::semaphore_batch::poll_acquire_one_unavailable", "process::test::no_kill_on_drop_by_default", "signal::unix::tests::signal_enable_error_on_invalid_input", "io::util::copy_buf::tests::assert_unpin", "copy_permissions", "process::imp::orphan::test::does_not_register_signal_if_queue_empty", "process::imp::orphan::test::no_reap_if_signal_lock_held", "fs::file::tests::write_twice_before_dispatch", "fs::file::tests::read_err", "fs::file::tests::partial_read_set_len_ok", "build_dir", "read_inherent", "read_file_from_std", "runtime::tests::queue::fits_256_all_at_once", "fs::file::tests::write_with_buffer_larger_than_max", "runtime::time::tests::drop_timer", "fs::file::tests::sync_all_err_ordered_after_write", "sync::tests::semaphore_batch::try_acquire_many_unavailable", "fs::file::tests::read_with_buffer_larger_than_max", "util::memchr::tests::memchr_empty", "runtime::tests::task_combinations::test_combinations", "write_vectored", "process::imp::orphan::test::drain_attempts_a_single_reap_of_all_queued_orphans", "write_vectored_and_shutdown", "runtime::tests::queue::fits_256_all_in_chunks", "runtime::tests::inject::pop_n_drains_on_drop", "sync::tests::semaphore_batch::close_semaphore_notifies_permit1", "task::local::tests::wakes_to_local_queue", "rewind_seek_position", "runtime::tests::queue::overflow", "create_all"], "failed_tests": ["open_options_mode"], "skipped_tests": []}