Repository: tokio-rs/tokio
File: tokio/src/sync/mpsc/bounded.rs (Rust)

Code before:
/// #Examples
///
/// ```rust
/// use tokio;
/// use tokio::sync::mpsc::channel;
///
/// #[tokio::main]
/// async fn main() {
///     let (tx, mut rx) = channel(15);
///     let _ = tx.send(1).await;
///     let tx_weak = tx.downgrade();
///
///     let _ = tokio::spawn(async move {
///         for i in 0..2 {
///             if i == 0 {
///                 assert_eq!(rx.recv().await.unwrap(), 1);
///             } else if i == 1 {
///                 // only WeakSender instance remains -> channel is dropped
///                 assert!(rx.recv().await.is_none());
///             }
///         }
///     })
///     .await;
///
///     assert!(tx_weak.upgrade().is_none());
/// }
///
/// ```
pub struct WeakSender<T> {
    chan: chan::Tx<T, Semaphore>,
}

/// Permits to send one value into the channel.
///
/// `Permit` values are returned by [`Sender::reserve()`] and [`Sender::try_reserve()`]
/// and are used to guarantee channel capacity before generating a message to send.
///
/// [`Sender::reserve()`]: Sender::reserve
/// [`Sender::try_reserve()`]: Sender::try_reserve
pub struct Permit<'a, T> {
    chan: &'a chan::Tx<T, Semaphore>,
}

/// Owned permit to send one value into the channel.
///
/// This is identical to the [`Permit`] type, except that it moves the sender
/// rather than borrowing it.
///
/// `OwnedPermit` values are returned by [`Sender::reserve_owned()`] and
/// [`Sender::try_reserve_owned()`] and are used to guarantee channel capacity
/// before generating a message to send.

Review comment (bug):
This example ignores panics in the spawned task, and its rather complicated. I suggest replacing it with a much simpler example - e.g. the example could look like this:
```Rust
let (tx, rx) = channel(15);
let tx_weak = tx.clone().downgrade();

// Upgrading will succeed because `tx` still exists.
assert!(tx_weak.clone().upgrade().is_some());

// If we drop `tx`, then it will fail.
drop(tx);
assert!(tx_weak.clone().upgrade().is_none());
```

Code after:
///
/// #Examples
///
/// ```
/// use tokio::sync::mpsc::channel;
///
/// #[tokio::main]
/// async fn main() {
///     let (tx, _rx) = channel::<i32>(15);
///     let tx_weak = tx.downgrade();
///   
///     // Upgrading will succeed because `tx` still exists.
///     assert!(tx_weak.upgrade().is_some());
///   
///     // If we drop `tx`, then it will fail.
///     drop(tx);
///     assert!(tx_weak.clone().upgrade().is_none());
/// }
/// ```
pub struct WeakSender<T> {
    chan: Arc<chan::Chan<T, Semaphore>>,
}

/// Permits to send one value into the channel.
///
/// `Permit` values are returned by [`Sender::reserve()`] and [`Sender::try_reserve()`]
/// and are used to guarantee channel capacity before generating a message to send.
///
/// [`Sender::reserve()`]: Sender::reserve
/// [`Sender::try_reserve()`]: Sender::try_reserve
pub struct Permit<'a, T> {
    chan: &'a chan::Tx<T, Semaphore>,
}

/// Owned permit to send one value into the channel.
///
/// This is identical to the [`Permit`] type, except that it moves the sender
/// rather than borrowing it.
///
/// `OwnedPermit` values are returned by [`Sender::reserve_owned()`] and
/// [`Sender::try_reserve_owned()`] and are used to guarantee channel capacity
/// before generating a message to send.
///
/// [`Permit`]: Permit
/// [`Sender::reserve_owned()`]: Sender::reserve_owned
/// [`Sender::try_reserve_owned()`]: Sender::try_reserve_owned
pub struct OwnedPermit<T> {
    chan: Option<chan::Tx<T, Semaphore>>,
}

/// Receives values from the associated `Sender`.