mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-25 00:00:18 +02:00
Explicit impl Clone for tx to avoid T: Clone (#865)
`#[derive(Clone)]` on a type `struct Foo<T>` adds an impl that requires that `T: Clone`: ```rust impl<T: Clone> Clone for Foo<T> ``` which is unfortunate in the case of senders, because we don't want to require that the items being sent are `Clone` for the channel sender to be `Clone`. This PR adds an explicit `impl Clone` for the bounded and unbounded sender types which does not have the `T: Clone` bound. Note that this is _also_ an issue with `#[derive(Debug)]`, but that one is harder to work around as `chan::Tx` _also_ has `#[derive(Debug)]`, as does `chan::Chan`, so we'd have to add explicit impls for all of them to make progress.
This commit is contained in:
@@ -7,11 +7,17 @@ use std::fmt;
|
||||
/// Send values to the associated `Receiver`.
|
||||
///
|
||||
/// Instances are created by the [`channel`](fn.channel.html) function.
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug)]
|
||||
pub struct Sender<T> {
|
||||
chan: chan::Tx<T, Semaphore>,
|
||||
}
|
||||
|
||||
impl<T> Clone for Sender<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Sender { chan: self.chan.clone() }
|
||||
}
|
||||
}
|
||||
|
||||
/// Receive values from the associated `Sender`.
|
||||
///
|
||||
/// Instances are created by the [`channel`](fn.channel.html) function.
|
||||
|
||||
@@ -9,11 +9,17 @@ use std::fmt;
|
||||
///
|
||||
/// Instances are created by the
|
||||
/// [`unbounded_channel`](fn.unbounded_channel.html) function.
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug)]
|
||||
pub struct UnboundedSender<T> {
|
||||
chan: chan::Tx<T, Semaphore>,
|
||||
}
|
||||
|
||||
impl<T> Clone for UnboundedSender<T> {
|
||||
fn clone(&self) -> Self {
|
||||
UnboundedSender { chan: self.chan.clone() }
|
||||
}
|
||||
}
|
||||
|
||||
/// Receive values from the associated `UnboundedSender`.
|
||||
///
|
||||
/// Instances are created by the
|
||||
|
||||
@@ -91,6 +91,36 @@ fn send_recv_unbounded() {
|
||||
assert!(val.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clone_sender_no_t_clone_buffer() {
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
struct NotClone;
|
||||
let (mut tx, mut rx) = mpsc::channel(100);
|
||||
tx.try_send(NotClone).unwrap();
|
||||
tx.clone().try_send(NotClone).unwrap();
|
||||
|
||||
let val = assert_ready!(rx.poll());
|
||||
assert_eq!(val, Some(NotClone));
|
||||
|
||||
let val = assert_ready!(rx.poll());
|
||||
assert_eq!(val, Some(NotClone));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clone_sender_no_t_clone_unbounded() {
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
struct NotClone;
|
||||
let (mut tx, mut rx) = mpsc::unbounded_channel();
|
||||
tx.try_send(NotClone).unwrap();
|
||||
tx.clone().try_send(NotClone).unwrap();
|
||||
|
||||
let val = assert_ready!(rx.poll());
|
||||
assert_eq!(val, Some(NotClone));
|
||||
|
||||
let val = assert_ready!(rx.poll());
|
||||
assert_eq!(val, Some(NotClone));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn send_recv_buffer_limited() {
|
||||
let (mut tx, mut rx) = mpsc::channel::<i32>(1);
|
||||
|
||||
Reference in New Issue
Block a user