Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.4.37 semver-incompatibly removes trait bounds on DateTime #1571

Closed
little-dude opened this issue Apr 15, 2024 · 10 comments · Fixed by #1573
Closed

0.4.37 semver-incompatibly removes trait bounds on DateTime #1571

little-dude opened this issue Apr 15, 2024 · 10 comments · Fixed by #1573

Comments

@little-dude
Copy link

Hello,

The following code compile in 0.4.35 but breaks in 0.4.37:

use chrono::TimeZone;
use chrono::DateTime;

#[derive(Clone, Debug)]
pub struct MyDateTime<T: TimeZone>(DateTime<T>);

impl<T: TimeZone> Copy for MyDateTime<T> where T::Offset: Copy {}

With 0.4.37:

error[E0204]: the trait `Copy` cannot be implemented for this type
 --> src/main.rs:7:28
  |
5 | pub struct MyDateTime<T: TimeZone>(chrono::DateTime<T>);
  |                                    ------------------- this field does not implement `Copy`
6 |
7 | impl<T: TimeZone> Copy for MyDateTime<T> where T::Offset: Copy {}
  |                            ^^^^^^^^^^^^^
  |
note: the `Copy` impl for `DateTime<T>` requires that `T: Copy`
 --> src/main.rs:5:36
  |
5 | pub struct MyDateTime<T: TimeZone>(chrono::DateTime<T>);
  |                                    ^^^^^^^^^^^^^^^^^^^
help: consider further restricting this bound
  |
7 | impl<T: TimeZone + Copy> Copy for MyDateTime<T> where T::Offset: Copy {}

This is probably due to #1492

@djc
Copy link
Member

djc commented Apr 15, 2024

Sorry for the regression! We'll look into this. I don't think we're going to just revert the changes for #1492, but let's see what we can do.

@little-dude
Copy link
Author

No worries, it's not a big deal for me. I just thought opening an issue might be good if other people run into this.

@djc djc pinned this issue Apr 15, 2024
@djc
Copy link
Member

djc commented Apr 15, 2024

Right -- I think I'm inclined to let this one go unless there are multiple reporters for whom it turns out to be a larger problem. As I understand it, it mostly requires people add bounds that they should have been adding anyway.

@djc djc changed the title 0.4.37 contains breaking changes 0.4.37 semver-incompatibly removes trait bounds on DateTime Apr 15, 2024
@pitdicker
Copy link
Collaborator

The manual Copy implementation that was deleted in #1492 was sound, it was only the comment that was incorrect. We had it because the type of Tz doesn't matter as it isn't a field of the DateTime struct.

For the Send implementation I'm not 100% sure it was sound.

@pitdicker
Copy link
Collaborator

Reverting the change to Copy is easy, shall I just make a PR?

@little-dude
Copy link
Author

little-dude commented Apr 15, 2024

Yeah I agree that the previous Copy impl was better than the derived one. Wdyt @djc ?

As I understand it, it mostly requires people add bounds that they should have been adding anyway.

Yes, it requires having Tz: Copy, Tz::Offset: Copy, but since the DateTime struct looks like this:

pub struct DateTime<Tz: TimeZone> {
    datetime: NaiveDateTime,
    offset: Tz::Offset,
}

the Tz: Copy shouldn't be necessary.

@djc
Copy link
Member

djc commented Apr 15, 2024

Alright, sounds good.

I think the Send impl was also sound but it was easy to accidentally make it unsound if we changed the layout of NaiveDateTime.

@little-dude
Copy link
Author

little-dude commented Apr 15, 2024

The manual Copy implementation that was deleted in #1492 was sound, it was only the comment that was incorrect.

OOC how could a Copy impl be unsound? It isn't an unsafe trait, so I assumed it couldn't be unsound.

@pitdicker
Copy link
Collaborator

Sorry, I'm not using the right term. Meant 'correct'.

little-dude pushed a commit to little-dude/chrono that referenced this issue Apr 15, 2024
`derive` generates the following impls:

```rust
impl<Tz: ::core::marker::Copy + TimeZone> ::core::marker::Copy for DateTime<Tz>
where
    Tz::Offset: ::core::marker::Copy,
{}

impl<Tz: ::core::clone::Clone + TimeZone> ::core::clone::Clone for DateTime<Tz>
where
    Tz::Offset: ::core::clone::Clone,
{
    #[inline]
    fn clone(&self) -> DateTime<Tz> {
        DateTime {
            datetime: ::core::clone::Clone::clone(&self.datetime),
            offset: ::core::clone::Clone::clone(&self.offset),
        }
    }
}
```

In the `Copy` impl, the `Tz: Copy` bound is un-necessary. Note that in
the `Clone` impl, he `Tz: Clone` is also un-necessary, but it's
implied by the `TimeZone` bound anyway, so there's not point having a
manual implementation of `Clone`.

Fixes chronotope#1571
@little-dude
Copy link
Author

Thanks for the quick response on this @pitdicker and @djc !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants