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

Make functions in internals const #1043

Merged
merged 4 commits into from
May 23, 2023
Merged

Conversation

pitdicker
Copy link
Collaborator

@pitdicker pitdicker commented Apr 29, 2023

@esheppa My intention was to understand why you would need to overhaul the internals of chono in #882 to make functions const. So I started sprinkling const around to see what breaks.

Everything in internals.rs can easily be made const, even on the 0.4.x branch. I made this PR because the work was done anyway, no use in letting someone else do it again.

@esheppa Would you be willing to review?
I also did a good number of the functions from NaiveDate just to prove for myself there are no major obstacles, but kept them out of this PR to keep it reviewable. There are a lot more choices that can be made there, so they deserve an own PR in the future.

I'll add some comments on the required changes.

@@ -53,7 +51,7 @@ pub(super) const FE: YearFlags = YearFlags(0o07);
pub(super) const G: YearFlags = YearFlags(0o16);
pub(super) const GF: YearFlags = YearFlags(0o06);

static YEAR_TO_FLAGS: [YearFlags; 400] = [
const YEAR_TO_FLAGS: &[YearFlags; 400] = &[
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A static is only included once in the binary. To prevent duplication of this array on every use as const, It has to be put behind a reference (see https://users.rust-lang.org/t/const-vs-static/52951/12). It can still be duplicated with multiple codegen units, but the statics are not that big that it should be a problem.

src/naive/internals.rs Show resolved Hide resolved
let mdl = mdf >> 3;
match MDL_TO_OL.get(mdl as usize) {
Some(&v) => Of(mdf.wrapping_sub((i32::from(v) as u32 & 0x3ff) << 3)),
None => Of(0),
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These three lines where using array.get() and returning a safe value instead of panicking on out-of-bounds. Yet the index value is created in this module, and always in bounds.

I suspect the reason here is not just to avoid a potential panic, but to avoid the creation of landings pads if the compiler can't elide the bounds check.

In my opinion it would be fine to simplify this code to direct array indexing, but I kept the functionality. Note that array.get() is unavailable in const, so this needs a manual bounds check.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ai. I was wrong, this code is just ancient. In various places it is returning 0 instead of Option, and you are supposed to call valid() afterwards 😞. Let me see if I can clean that up a little.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we may even have some correctness gains by separating these values out to separate modules, with the modules only exposing APIs that allow valid values (in cases where a const API still requires things like .valid())

@@ -368,33 +370,37 @@ impl fmt::Debug for Of {
/// (month, day of month and leap flag),
/// which is an index to the `MDL_TO_OL` lookup table.
#[derive(PartialEq, PartialOrd, Copy, Clone)]
pub(super) struct Mdf(pub(super) u32);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The value didn't need to be public. Making it private makes it clearer the value is always correct, and thus in bounds for array indexing.

let Of(of) = *self;
Weekday::from_u32(((of >> 4) + (of & 0b111)) % 7).unwrap()
Weekday::from_u32_mod7((of >> 4) + (of & 0b111))
Copy link
Collaborator Author

@pitdicker pitdicker Apr 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't use Weekday::from_u32 because that is part of num_traits::FromPrimitive, and trait methods can't yet be const.

src/weekday.rs Outdated
/// Create a `Weekday` from an `u32`, with Monday = 0.
/// Infallible, takes `n & 7`.
#[inline]
pub(crate) const fn from_u32_mod7(n: u32) -> Weekday {
Copy link
Collaborator Author

@pitdicker pitdicker Apr 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For use in this crate it would be nice if there was a const, infallible way to create a Weekday.

Because the two methods constructing a Weekday in internals.rs passed n % 7, making from_u32_mod7 seemed like a good way to have an infallible function and avoid a little code duplication.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the mod7 requirement which is not enforced in the type system and the fact that this is used only in the internals module, I think this should be a free function in the internals module rather than a method here.

@pitdicker
Copy link
Collaborator Author

pitdicker commented Apr 29, 2023

@RagibHasin You expressed an interest to help with making the API const. Would you also be willing to review?

And maybe we can work together?

It seems hard to avoid one massive 'make everything const'-PR, because a lot depends on each other. DateTime depends on NaiveDateTime, NaiveDateTime depends on NaiveDate and NaiveTime...

IsoWeek, Month, NaiveTime, Duration and FixedOffset should be pretty self contained. Do you want to make PRs for any or all of those?

@RagibHasin
Copy link

Thanks, @pitdicker. I expect to have some free time in around 12 hours. I would try to review it then.

Very excited about this progress.

@pitdicker
Copy link
Collaborator Author

#638 Already worked on Duration about 2 years ago, but hit the problem Option::unwrap and Option::expect are unavailable in const.

Maybe we can use some ugly macro that imitates them but works in const by doing an implicit panic, like https://users.rust-lang.org/t/compile-time-const-unwrapping/51619/6?

Or chrono would have to update to Rust 2021 and raise the MSRV to 1.57, which supports panic in const context. See #995.

Copy link
Contributor

@jtmoon79 jtmoon79 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

This is a safe and useful improvement!

Just one request for a new test case.

src/weekday.rs Outdated Show resolved Hide resolved
Copy link
Collaborator Author

@pitdicker pitdicker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While making parts of NaiveDate const, I noticed there where Options created in places where I would not expect them, and not created where they should.

Of was written to allow the creation of invalid values, and you were supposed to call valid() afterwards and handle the error. That didn't seem very Rusty, so I changed Of is to always be valid and return Options earlier.

There is not any extra validation happening. It is just happening in the functions that would create the invalid state, not in the functions calling them.

src/naive/date.rs Show resolved Hide resolved
/// Does not check whether the flags are correct for the provided year.
const fn from_of(year: i32, ordinal: u32, flags: YearFlags) -> Option<NaiveDate> {
if year < MIN_YEAR || year > MAX_YEAR {
return None; // Out-of-range
Copy link
Collaborator Author

@pitdicker pitdicker Apr 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This already splits out the failure causes for when this method is switched to return a Result.


/// Makes a new `NaiveDate` from year, ordinal and flags.
/// Does not check whether the flags are correct for the provided year.
const fn from_of(year: i32, ordinal: u32, flags: YearFlags) -> Option<NaiveDate> {
Copy link
Collaborator Author

@pitdicker pitdicker Apr 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function was always used in a pattern of NaiveDate::from_of(year, Of::new(ordinal, flags)?). Clearer to combine them, which helps to see the failure cause.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This combination should be a separate commit with no other changes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also rename this method? The current name doesn't really fit anymore.

}
match mdf.to_of() {
Some(of) => Some(NaiveDate { ymdf: (year << 13) | (of.inner() as DateImpl) }),
None => None, // Non-existing date
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should return another error than in from_of if this methods is converted to return a Result.

} else {
None
}
const fn with_of(&self, of: Of) -> NaiveDate {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because an Of is now always valid, this function no longer has to return Option.

@@ -172,8 +172,9 @@ impl fmt::Debug for YearFlags {
}
}

// OL: (ordinal << 1) | leap year flag
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the important trick of the validation logic.

@@ -266,56 +267,66 @@ const OL_TO_MDL: &[u8; MAX_OL as usize + 1] = &[
/// The whole bits except for the least 3 bits are referred as `Ol` (ordinal and leap flag),
/// which is an index to the `OL_TO_MDL` lookup table.
#[derive(PartialEq, PartialOrd, Copy, Clone)]
pub(super) struct Of(pub(crate) u32);
pub(super) struct Of(u32);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The value of Of is now private and always valid.

}

pub(super) const fn from_date_impl(date_impl: DateImpl) -> Of {
// We assume the value in the `DateImpl` is valid.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had to add this to make Of private, and prevent unnecessary validation when converting from DateImpl. But DateImpl is not private... Had to stop somewhere 😄

@esheppa
Copy link
Collaborator

esheppa commented Apr 30, 2023

Thanks @pitdicker - this looks great. Looks like there were a few critical parts I missed that led me down the path of an internals rewrite (that said, some of it was to try to simplify the code and avoid some conversions, but in the end the benchmarks were much worse). The good news is this looks like a great solution, and I can potentially look into doing a new PR with some of the potentially useful parts of #882 once this is merged

@esheppa
Copy link
Collaborator

esheppa commented Apr 30, 2023

With regards to:

Or chrono would have to update to Rust 2021 and raise the MSRV to 1.57, which supports panic in const context. See #995.

What we can do here is have a non-default feature that allows this (eg const-validation), that said, for Duration another potentially better option is moving to using the Duration type from the stdlib. I've got some PRs (which need a little updating) which I'll update shortly that could provide a good solution here

@RagibHasin
Copy link

With regards to:

Or chrono would have to update to Rust 2021 and raise the MSRV to 1.57, which supports panic in const context. See #995.

What we can do here is have a non-default feature that allows this (eg const-validation), that said, for Duration another potentially better option is moving to using the Duration type from the stdlib. I've got some PRs (which need a little updating) which I'll update shortly that could provide a good solution here

std::time::Duration cannot represent negative durations. But negative durations feel awkward anyway IMO. If the decision is to move towards stdlib then would there be some new type (eg. Stride) which would be a signed Duration to be returned by subtraction operations?

@esheppa
Copy link
Collaborator

esheppa commented Apr 30, 2023

std::time::Duration cannot represent negative durations. But negative durations feel awkward anyway IMO.

Yes I think the best solution is to avoid negative durations - however I'm also keen to receive any feedback on where they would be useful.

The current design is implemented in this PR: #895 (a continuation of a long series of designs, but this one is able to be used in the 0.4.x series which is a large benefit)

Originally we had thought to use a new enum, eg:

enum TimeDelta { Forwards(Duration), Backwards(Duration) }

However in the current iteration I'm just reusing the Result type, with Ok containing a forwards duration, and Err containing the absolute value of the negative duration if applicable, as there didn't seem to be enough justification to add a new type. Importantly, because Duration doesn't implement Error, this is unlikely to be accidentally handled with ?.

@RagibHasin as this is off topic for this PR, we should continue any further discussions on this at #895

Copy link
Contributor

@jtmoon79 jtmoon79 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At risk of sounding like a broken record...

Could some 1:1 tests be added, e.g. each function gets it's own test_function?

On top of that, preferably added in two or more commits:

  • A bunch of tests in one (or more) a before changes commit
  • and then one (or more) commit with changes + test adjustments.

The additional tests provide clarity to developers about function expectations (esp. code reviewers 😊) and give more confidence about the changes.

Just my request. I'm requesting this now and not previously because a new commit has added a few behavior changes (459defd).

Also, just having more 1:1 function testing would be good for chrono.

@pitdicker
Copy link
Collaborator Author

At risk of sounding like a broken record...

Please do! I'll learn 😄

For these changes though: this code is already tested really, really thoroughly.

  • In this module there are tests for the year flags, ordinal + flag-format, and month-dag-flag formats. These test that one form can be converted to another and back correctly. And there are tests that create all possible year flags and ordinals, or year flags and dates, and check some methods.
  • Although this is another module than NaiveDate, they are very closely integrated. Of::succ and Of::pred are not tested here, but NaiveDate::succ and NaiveDate::pred have tests for the interesting cases.

I don't see much to improve here w.r.t the existing tests.

Or did you mean: add tests to verify the functions keep working in const context?

@pitdicker
Copy link
Collaborator Author

I'm requesting this now and not previously because a new commit has added a few behavior changes

Oops, replied to soon. I'll add tests that verify the changed functions return None on invalid cases. We can check those now directly in this module 👍.

@pitdicker
Copy link
Collaborator Author

Thanks @pitdicker - this looks great. Looks like there were a few critical parts I missed that led me down the path of an internals rewrite (that said, some of it was to try to simplify the code and avoid some conversions, but in the end the benchmarks were much worse). The good news is this looks like a great solution, and I can potentially look into doing a new PR with some of the potentially useful parts of #882 once this is merged

Nice! Seems like most of the code necessary to make functions in chrono const already exists, it just has to come together 👍.

@pitdicker
Copy link
Collaborator Author

What we can do here is have a non-default feature that allows this (eg const-validation), that said, for Duration another potentially better option is moving to using the Duration type from the stdlib. I've got some PRs (which need a little updating) which I'll update shortly that could provide a good solution here

Is that something that can be done on the 0.4.x branch, or would it require breaking changes? I'll reply on your #895 when I get to know that area a little better.

Maybe for the somewhat simple work of making methods const we can make something work for the current implementation.

What we can do here is have a non-default feature that allows this (eg const-validation)

I remember that removing a feature can only be done when going to a new major version. I.e. if we introduce it in 0.4.x, it can't be removed until 0.5. That doesn't seem too bad... Maybe a more general msrv_workarounds that potentially stays relevant?

This feels like a ok-ish solution to me. A macro that maps to regular unwrap without the feature, and a hack with implicit panic on older rust versions. But if we can avoid the mess and raise the MSRV that would be so much nicer.

Maybe just work on that assumption for now, and make a PR with the workarounds if the MSRV has to stay below 1.57?

Copy link
Contributor

@jtmoon79 jtmoon79 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@pitdicker
Copy link
Collaborator Author

Sorry for the slow follow-up. I let myself get distracted by some very interesting panics (in another issue)...

Added a test to check Of::new, Mdf::new, Of::from_mdf, Of::succ and Of::pred return None when they should.

Thank you for the reminders to add tests @jtmoon79.

@pitdicker pitdicker force-pushed the const_internals branch 2 times, most recently from bfc85fc to 600c953 Compare May 15, 2023 09:09
match MDL_TO_OL.get(mdl as usize) {
Some(&v) => Of(mdf.wrapping_sub((i32::from(v) as u32 & 0x3ff) << 3)),
None => Of(0),
if mdl <= MAX_MDL {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty sure <= is incorrect when preparing to index into something? Also for cases like these I prefer to invert the condition so we can do an early return for the simple case (here, Of(0)) and resume unindented for the straight-line path.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The arrays in this file are a bit strange: index 0 has an invalid value, and the length is MAX + 1.
It makes some sense, as we encode ordinals and day of month starting from 1. This allows indexing without the need to subtract -1.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, can you add a comment to each comparison where this is relevant?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would like the comment on the same line as the if, can be shorter like // 1-based indexing.

match OL_TO_MDL.get(ol as usize) {
Some(&v) => Mdf(of + (u32::from(v) << 3)),
None => Mdf(0),
if ol <= MAX_OL {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be <? Please add some tests for the edge cases here...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same array with an unused zero index. There is a test with the edge cases.

match MDL_TO_OL.get(mdl as usize) {
Some(&v) => v >= 0,
None => false,
if mdl <= MAX_MDL {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<= -> <?

src/weekday.rs Outdated
/// Create a `Weekday` from an `u32`, with Monday = 0.
/// Infallible, takes `n & 7`.
#[inline]
pub(crate) const fn from_u32_mod7(n: u32) -> Weekday {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the mod7 requirement which is not enforced in the type system and the fact that this is used only in the internals module, I think this should be a free function in the internals module rather than a method here.

src/naive/date.rs Show resolved Hide resolved

/// Makes a new `NaiveDate` from year, ordinal and flags.
/// Does not check whether the flags are correct for the provided year.
const fn from_of(year: i32, ordinal: u32, flags: YearFlags) -> Option<NaiveDate> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This combination should be a separate commit with no other changes.

src/weekday.rs Outdated
@@ -260,6 +260,14 @@ mod tests {
);
}
}

#[test]
fn test_from_u32_mod7() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please squash this in the commit where the function is added.

@@ -266,6 +266,8 @@ const OL_TO_MDL: &[u8; MAX_OL as usize + 1] = &[
///
/// The whole bits except for the least 3 bits are referred as `Ol` (ordinal and leap flag),
/// which is an index to the `OL_TO_MDL` lookup table.
///
/// The methods implemented on `Of` always return a valid value.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please squash this change into the commit that originated the described changes.

@pitdicker pitdicker force-pushed the const_internals branch 3 times, most recently from 59122a3 to b354578 Compare May 15, 2023 12:08
src/naive/date.rs Outdated Show resolved Hide resolved
match MDL_TO_OL.get(mdl as usize) {
Some(&v) => Of(mdf.wrapping_sub((i32::from(v) as u32 & 0x3ff) << 3)),
None => Of(0),
if mdl <= MAX_MDL {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would like the comment on the same line as the if, can be shorter like // 1-based indexing.

@@ -467,11 +466,28 @@ impl fmt::Debug for Mdf {
}
}

/// Create a `Weekday` from an `u32`, with Monday = 0.
/// Infallible, takes `n % 7`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The takes n % 7 comment is no longer correct, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intention was to say it is infallible, because it takes any n and does modulus 7. I'll see if I can word it better.

Comment on lines +846 to +893
for i in 0..=1000 {
assert_eq!(weekday_from_u32_mod7(i), Weekday::from_u32(i % 7).unwrap());
}
assert_eq!(weekday_from_u32_mod7(u32::MAX), Weekday::Thu);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there's any point to testing with values larger than 7.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really, but testing up to 1000 and a single u32:MAX is cheap.

Comment on lines 365 to 368
if self.ordinal() == 1 {
return None;
}
Some(Of(self.0 - (1 << 4)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style: I prefer writing this as

match self.ordinal() {
    1 =>  None,
    _ => Some(Of(self.0 - (1 << 4)))
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That looks very clean, thank you 👍

@@ -370,13 +387,17 @@ impl fmt::Debug for Of {
/// The whole bits except for the least 3 bits are referred as `Mdl`
/// (month, day of month and leap flag),
/// which is an index to the `MDL_TO_OL` lookup table.
///
/// The methods implemented on `Mdf` do not always return a valid value.
/// Dates than can't exist, like February 30, can still be represented.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"than" -> "that"

Why do we need to allow Mdf instances with an invalid value?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Testing whether an ordinal is valid is easy. Testing a month, day, leap year flag combination is valid, and doing it fast, is more involved.

The table lookup to convert Mdf to Of is pretty much the ideal place to put the validity check.

@@ -662,8 +683,7 @@ mod tests {
fn test_of_fields() {
for &flags in FLAGS.iter() {
for ordinal in range_inclusive(1u32, 366) {
let of = Of::new(ordinal, flags).unwrap();
if of.valid() {
if let Some(of) = Of::new(ordinal, flags) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For tests, let's just unwrap() cases like these?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't. The test is creating all possible combinations of year flags and ordinals. But some of these combinations are just invalid. It tests if those that are let through, have an ordinal that round-trips.


/// Makes a new `NaiveDate` from year, ordinal and flags.
/// Does not check whether the flags are correct for the provided year.
const fn from_of(year: i32, ordinal: u32, flags: YearFlags) -> Option<NaiveDate> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also rename this method? The current name doesn't really fit anymore.

@pitdicker
Copy link
Collaborator Author

Would like the comment on the same line as the if, can be shorter like // 1-based indexing.

I would also like to put it on the same line, but rustfmt disagrees with me.

@pitdicker
Copy link
Collaborator Author

Should we also rename this method? The current name doesn't really fit anymore.

(Some of your comments are missing a reply field for some reason.)

I suppose it can be called from_ordinal_and_flags. I quite liked the short name, but agree it can be confusing.

@pitdicker
Copy link
Collaborator Author

@djc Just to make sure, you are not waiting on me?

@djc
Copy link
Member

djc commented May 17, 2023

@djc Just to make sure, you are not waiting on me?

Nope.

Copy link
Member

@djc djc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks again for working on this!

@djc djc merged commit 403b247 into chronotope:0.4.x May 23, 2023
@pitdicker pitdicker deleted the const_internals branch May 23, 2023 10:06
@pitdicker
Copy link
Collaborator Author

pitdicker commented May 23, 2023

🎉

Time to get my branch that makes most of NaiveDate and NaiveTime const in shape.

crapStone pushed a commit to Calciumdibromid/CaBr2 that referenced this pull request Jun 12, 2023
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [chrono](https://github.com/chronotope/chrono) | dependencies | patch | `0.4.24` -> `0.4.26` |

---

### Release Notes

<details>
<summary>chronotope/chrono</summary>

### [`v0.4.26`](https://github.com/chronotope/chrono/releases/tag/v0.4.26): 0.4.26

[Compare Source](chronotope/chrono@v0.4.25...v0.4.26)

The changes from [#&#8203;807](chronotope/chrono#807) we merged for 0.4.25 unfortunately restricted parsing in a way that was incompatible with earlier 0.4.x releases. We reverted this in [#&#8203;1113](chronotope/chrono#1113). A small amount of other changes were merged since.

-   Update README ([#&#8203;1111](chronotope/chrono#1111), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Revert backport of [#&#8203;807](chronotope/chrono#807) ([#&#8203;1113](chronotope/chrono#1113), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Update to 2021 edition ([#&#8203;1109](chronotope/chrono#1109), thanks to [@&#8203;tottoto](https://github.com/tottoto))
-   Fix `DurationRound` panics from issue [#&#8203;1010](chronotope/chrono#1010) ([#&#8203;1093](chronotope/chrono#1093), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   tests: date path consolidate (branch 0.4.x) ([#&#8203;1090](chronotope/chrono#1090), thanks to [@&#8203;jtmoon79](https://github.com/jtmoon79))
-   Parse tests nanosecond bare dot (branch 0.4.x) ([#&#8203;1098](chronotope/chrono#1098), thanks to [@&#8203;jtmoon79](https://github.com/jtmoon79))
-   yamllint cleanup lint.yml test.yml ([#&#8203;1102](chronotope/chrono#1102), thanks to [@&#8203;jtmoon79](https://github.com/jtmoon79))
-   Remove num-iter dependency ([#&#8203;1107](chronotope/chrono#1107), thanks to [@&#8203;tottoto](https://github.com/tottoto))

Thanks on behalf of the chrono team ([@&#8203;djc](https://github.com/djc) and [@&#8203;esheppa](https://github.com/esheppa)) to all contributors!

### [`v0.4.25`](https://github.com/chronotope/chrono/releases/tag/v0.4.25): 0.4.25

[Compare Source](chronotope/chrono@v0.4.24...v0.4.25)

Time for another maintenance release. This release bumps the MSRV to 1.56; given MSRV bumps in chrono's dependencies (notably for syn 2), we felt that it no longer made sense to support any older versions. Feedback welcome in our issue tracker!

##### Additions

-   Bump the MSRV to 1.56 ([#&#8203;1053](chronotope/chrono#1053))
-   Apply comments from MSRV bump ([#&#8203;1026](chronotope/chrono#1026), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Remove num-integer dependency ([#&#8203;1037](chronotope/chrono#1037), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Add `NaiveDateTime::and_utc()` method ([#&#8203;952](chronotope/chrono#952), thanks to [@&#8203;klnusbaum](https://github.com/klnusbaum))
-   derive `Hash` for most pub types that also derive `PartialEq` ([#&#8203;938](chronotope/chrono#938), thanks to [@&#8203;bruceg](https://github.com/bruceg))
-   Add `parse_and_remainder()` methods ([#&#8203;1011](chronotope/chrono#1011), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Add `DateTime::fix_offset()` ([#&#8203;1030](chronotope/chrono#1030), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Add `#[track_caller]` to `LocalResult::unwrap` ([#&#8203;1046](chronotope/chrono#1046), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Add `#[must_use]` to some methods ([#&#8203;1007](chronotope/chrono#1007), thanks to [@&#8203;aceArt-GmbH](https://github.com/aceArt-GmbH))
-   Implement `PartialOrd` for `Month` ([#&#8203;999](chronotope/chrono#999), thanks to [@&#8203;Munksgaard](https://github.com/Munksgaard))
-   Add `impl From<NaiveDateTime> for NaiveDate` ([#&#8203;1012](chronotope/chrono#1012), thanks to [@&#8203;pezcore](https://github.com/pezcore))
-   Extract timezone info from tzdata file on Android ([#&#8203;978](chronotope/chrono#978), thanks to [@&#8203;RumovZ](https://github.com/RumovZ))

##### Fixes

-   Prevent string slicing inside char boundaries ([#&#8203;1024](chronotope/chrono#1024), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   fix IsoWeek so that its flags are always correct ([#&#8203;991](chronotope/chrono#991), thanks to [@&#8203;moshevds](https://github.com/moshevds))
-   Fix out-of-range panic in `NaiveWeek::last_day` ([#&#8203;1070](chronotope/chrono#1070), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Use correct offset in conversion from `Local` to `FixedOffset` ([#&#8203;1041](chronotope/chrono#1041), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Fix military timezones in RFC 2822 parsing ([#&#8203;1013](chronotope/chrono#1013), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Guard against overflow in NaiveDate::with_\*0 methods ([#&#8203;1023](chronotope/chrono#1023), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Fix panic in from_num_days_from_ce_opt ([#&#8203;1052](chronotope/chrono#1052), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))

##### Refactoring

-   Rely on std for getting local time offset ([#&#8203;1072](chronotope/chrono#1072), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Make functions in internals const ([#&#8203;1043](chronotope/chrono#1043), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Refactor windows module in `Local` ([#&#8203;992](chronotope/chrono#992), thanks to [@&#8203;nekevss](https://github.com/nekevss))
-   Simplify from_timestamp_millis, from_timestamp_micros ([#&#8203;1032](chronotope/chrono#1032), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Backport [#&#8203;983](chronotope/chrono#983) and [#&#8203;1000](chronotope/chrono#1000) ([#&#8203;1063](chronotope/chrono#1063), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))

##### Documentation

-   Backport documentation improvements ([#&#8203;1066](chronotope/chrono#1066), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Add documentation for %Z quirk ([#&#8203;1051](chronotope/chrono#1051), thanks to [@&#8203;campbellcole](https://github.com/campbellcole))
-   Add an example to Weekday ([#&#8203;1019](chronotope/chrono#1019), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))

##### Internal improvements

-   Gate test on `clock` feature ([#&#8203;1061](chronotope/chrono#1061), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   CI: Also run tests with `--no-default-features` ([#&#8203;1059](chronotope/chrono#1059), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Prevent `bench_year_flags_from_year` from being optimized out ([#&#8203;1034](chronotope/chrono#1034), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Fix test_leap_second during DST transition ([#&#8203;1064](chronotope/chrono#1064), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Fix warnings when running tests on Windows ([#&#8203;1038](chronotope/chrono#1038), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Fix tests on AIX ([#&#8203;1028](chronotope/chrono#1028), thanks to [@&#8203;ecnelises](https://github.com/ecnelises))
-   Fix doctest warnings, remove mention of deprecated methods from main doc ([#&#8203;1081](chronotope/chrono#1081), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Reformat `test_datetime_parse_from_str` ([#&#8203;1078](chronotope/chrono#1078), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   GitHub yml shell `set -eux`, use bash ([#&#8203;1103](chronotope/chrono#1103), thanks to [@&#8203;jtmoon79](https://github.com/jtmoon79))
-   test: explicitly set `LANG` to `c` in gnu `date` ([#&#8203;1089](chronotope/chrono#1089), thanks to [@&#8203;scarf005](https://github.com/scarf005))
-   Switch test to `TryFrom` ([#&#8203;1086](chronotope/chrono#1086), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Add test for issue 551 ([#&#8203;1020](chronotope/chrono#1020), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   RFC 2822 single-letter obsolete tests ([#&#8203;1014](chronotope/chrono#1014), thanks to [@&#8203;jtmoon79](https://github.com/jtmoon79))
-   \[CI] Lint Windows target and documentation links ([#&#8203;1062](chronotope/chrono#1062), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   add test_issue\_866 ([#&#8203;1077](chronotope/chrono#1077), thanks to [@&#8203;jtmoon79](https://github.com/jtmoon79))
-   Remove AUTHORS metadata ([#&#8203;1074](chronotope/chrono#1074))

On behalf of [@&#8203;djc](https://github.com/djc) and [@&#8203;esheppa](https://github.com/esheppa), thanks to all contributors!

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNS4xMDUuMSIsInVwZGF0ZWRJblZlciI6IjM1LjExNS4yIiwidGFyZ2V0QnJhbmNoIjoiZGV2ZWxvcCJ9-->

Co-authored-by: cabr2-bot <cabr2.help@gmail.com>
Reviewed-on: https://codeberg.org/Calciumdibromid/CaBr2/pulls/1909
Reviewed-by: crapStone <crapstone@noreply.codeberg.org>
Co-authored-by: Calciumdibromid Bot <cabr2_bot@noreply.codeberg.org>
Co-committed-by: Calciumdibromid Bot <cabr2_bot@noreply.codeberg.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants