Repository: chronotope/chrono (language: rust)

Issue:
UTC Offset is not Send (cannot send DateTime across mps::channel)
I have a struct with a `DateTime<UTC>` field that I would like to send across a channel, like this:

```
pub struct Signal {
  pub time: DateTime<UTC>,
  pub raw: String
}
```

But when I want to create the channel, `rustc` complains that

```
error: the trait `core::marker::Send` is not implemented for the type `<chrono::offset::utc::UTC as chrono::offset::TimeZone>::Offset` [    E0277]    

let (new_signal_sender, new_signal_rcvr) = channel::<Signal>();
                                           ^~~~~~~~~~~~~~~~~
note: `<chrono::offset::utc::UTC as chrono::offset::TimeZone>::Offset` cannot be sent between threads safely
let (new_signal_sender, new_signal_rcvr) = channel::<Signal>();
```

Now `Send` is easily the part of Rust I understand the least, but I would have expected a DateTime object to be "sendable".



Discussion / hints:
Thank you for reporting. Chrono 0.2.3 fixed this issue.


Fix patch:
diff --git a/src/datetime/mod.rs b/src/datetime/mod.rs
index bb157f836b..1834c1cc6b 100644
--- a/src/datetime/mod.rs
+++ b/src/datetime/mod.rs
@@ -49,7 +49,7 @@ mod tests;
 /// There are some constructors implemented here (the `from_*` methods), but
 /// the general-purpose constructors are all via the methods on the
 /// [`TimeZone`](./offset/trait.TimeZone.html) implementations.
-#[derive(Clone)]
+#[derive(Copy, Clone)]
 #[cfg_attr(
     any(feature = "rkyv", feature = "rkyv-16", feature = "rkyv-32", feature = "rkyv-64"),
     derive(Archive, Deserialize, Serialize),
@@ -1386,10 +1386,6 @@ impl<Tz: TimeZone> Timelike for DateTime<Tz> {
     }
 }
 
-// we need them as automatic impls cannot handle associated types
-impl<Tz: TimeZone> Copy for DateTime<Tz> where <Tz as TimeZone>::Offset: Copy {}
-unsafe impl<Tz: TimeZone> Send for DateTime<Tz> where <Tz as TimeZone>::Offset: Send {}
-
 impl<Tz: TimeZone, Tz2: TimeZone> PartialEq<DateTime<Tz2>> for DateTime<Tz> {
     fn eq(&self, other: &DateTime<Tz2>) -> bool {
         self.datetime == other.datetime


Test patch:
diff --git a/src/datetime/tests.rs b/src/datetime/tests.rs
index 81e5c1bb59..4d81ce7a73 100644
--- a/src/datetime/tests.rs
+++ b/src/datetime/tests.rs
@@ -1866,3 +1866,12 @@ fn nano_roundrip() {
         assert_eq!(nanos, nanos2);
     }
 }
+
+#[test]
+fn test_datetime_utc_is_copy_and_send() {
+    fn is_copy<T: Copy>(_: T) {}
+    fn is_send<T: Send>(_: T) {}
+
+    is_copy(DateTime::<Utc>::MIN_UTC);
+    is_send(DateTime::<Utc>::MIN_UTC);
+}