From 4d6e6fe9d9b20f593007b1f0858c19059c72c764 Mon Sep 17 00:00:00 2001 From: Paul Dicker Date: Wed, 10 May 2023 14:23:37 +0200 Subject: [PATCH 1/3] Raise MSRV to 1.57 --- .github/workflows/test.yml | 6 +++--- Cargo.toml | 2 +- README.md | 2 +- src/naive/date.rs | 3 +-- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ee616c7731..a7795fe65f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -32,8 +32,8 @@ jobs: - run: cargo test --doc --all-features --color=always -- --color=always # later this may be able to be included with the below - # kept separate for now as the following don't compile on 1.56.1 - # * arbitrary + # kept separate for now as the following don't compile on 1.57 + # * arbitrary (requires 1.63 as of v1.3.0) rust_msrv: strategy: matrix: @@ -43,7 +43,7 @@ jobs: - uses: actions/checkout@v3 - uses: dtolnay/rust-toolchain@master with: - toolchain: 1.56.1 + toolchain: 1.57 - uses: Swatinem/rust-cache@v2 # run --lib and --doc to avoid the long running integration tests # which are run elsewhere diff --git a/Cargo.toml b/Cargo.toml index 2745c67ebc..76b1551b05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ readme = "README.md" license = "MIT/Apache-2.0" exclude = ["/ci/*"] edition = "2021" -rust-version = "1.56.0" +rust-version = "1.57.0" [lib] name = "chrono" diff --git a/README.md b/README.md index 639a09144d..113dfb38e5 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ Optional features: ## Rust version requirements -The Minimum Supported Rust Version (MSRV) is currently **Rust 1.56.0**. +The Minimum Supported Rust Version (MSRV) is currently **Rust 1.57.0**. The MSRV is explicitly tested in CI. It may be bumped in minor releases, but this is not done lightly. diff --git a/src/naive/date.rs b/src/naive/date.rs index b9404a15f5..c616d5dbc8 100644 --- a/src/naive/date.rs +++ b/src/naive/date.rs @@ -262,8 +262,7 @@ impl NaiveDate { if year < MIN_YEAR || year > MAX_YEAR { return None; // Out-of-range } - // Enable debug check once the MSRV >= 1.57 (panicking in const feature) - // debug_assert!(YearFlags::from_year(year).0 == flags.0); + debug_assert!(YearFlags::from_year(year).0 == flags.0); match Of::new(ordinal, flags) { Some(of) => Some(NaiveDate { ymdf: (year << 13) | (of.inner() as DateImpl) }), None => None, // Invalid: Ordinal outside of the nr of days in a year with those flags. From 9dc742e860e9455d3dd4e0f0914a2451bc23a248 Mon Sep 17 00:00:00 2001 From: Paul Dicker Date: Wed, 10 May 2023 14:23:51 +0200 Subject: [PATCH 2/3] Add `try_opt` and `expect` macros --- src/lib.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 3737d1a9b2..32fb02ed5a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -526,3 +526,25 @@ impl fmt::Debug for OutOfRange { #[cfg(feature = "std")] impl std::error::Error for OutOfRange {} + +/// Workaround because `?` is not (yet) available in const context. +#[macro_export] +macro_rules! try_opt { + ($e:expr) => { + match $e { + Some(v) => v, + None => return None, + } + }; +} + +/// Workaround because `.expect()` is not (yet) available in const context. +#[macro_export] +macro_rules! expect { + ($e:expr, $m:literal) => { + match $e { + Some(v) => v, + None => panic!($m), + } + }; +} From 7375cbff4af4068756d7d14c4098612d34d99fbc Mon Sep 17 00:00:00 2001 From: Paul Dicker Date: Wed, 10 May 2023 14:24:08 +0200 Subject: [PATCH 3/3] Make some methods on `NaiveTime` const --- src/naive/time/mod.rs | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/src/naive/time/mod.rs b/src/naive/time/mod.rs index 3700c5cba2..794c8d7269 100644 --- a/src/naive/time/mod.rs +++ b/src/naive/time/mod.rs @@ -19,6 +19,7 @@ use crate::format::{ }; use crate::oldtime::Duration as OldDuration; use crate::Timelike; +use crate::{expect, try_opt}; #[cfg(feature = "rustc-serialize")] mod rustc_serialize; @@ -216,8 +217,8 @@ impl NaiveTime { #[deprecated(since = "0.4.23", note = "use `from_hms_opt()` instead")] #[inline] #[must_use] - pub fn from_hms(hour: u32, min: u32, sec: u32) -> NaiveTime { - NaiveTime::from_hms_opt(hour, min, sec).expect("invalid time") + pub const fn from_hms(hour: u32, min: u32, sec: u32) -> NaiveTime { + expect!(NaiveTime::from_hms_opt(hour, min, sec), "invalid time") } /// Makes a new `NaiveTime` from hour, minute and second. @@ -255,8 +256,8 @@ impl NaiveTime { #[deprecated(since = "0.4.23", note = "use `from_hms_milli_opt()` instead")] #[inline] #[must_use] - pub fn from_hms_milli(hour: u32, min: u32, sec: u32, milli: u32) -> NaiveTime { - NaiveTime::from_hms_milli_opt(hour, min, sec, milli).expect("invalid time") + pub const fn from_hms_milli(hour: u32, min: u32, sec: u32, milli: u32) -> NaiveTime { + expect!(NaiveTime::from_hms_milli_opt(hour, min, sec, milli), "invalid time") } /// Makes a new `NaiveTime` from hour, minute, second and millisecond. @@ -283,10 +284,14 @@ impl NaiveTime { /// ``` #[inline] #[must_use] - pub fn from_hms_milli_opt(hour: u32, min: u32, sec: u32, milli: u32) -> Option { - milli - .checked_mul(1_000_000) - .and_then(|nano| NaiveTime::from_hms_nano_opt(hour, min, sec, nano)) + pub const fn from_hms_milli_opt( + hour: u32, + min: u32, + sec: u32, + milli: u32, + ) -> Option { + let nano = try_opt!(milli.checked_mul(1_000_000)); + NaiveTime::from_hms_nano_opt(hour, min, sec, nano) } /// Makes a new `NaiveTime` from hour, minute, second and microsecond. @@ -298,8 +303,8 @@ impl NaiveTime { #[deprecated(since = "0.4.23", note = "use `from_hms_micro_opt()` instead")] #[inline] #[must_use] - pub fn from_hms_micro(hour: u32, min: u32, sec: u32, micro: u32) -> NaiveTime { - NaiveTime::from_hms_micro_opt(hour, min, sec, micro).expect("invalid time") + pub const fn from_hms_micro(hour: u32, min: u32, sec: u32, micro: u32) -> NaiveTime { + expect!(NaiveTime::from_hms_micro_opt(hour, min, sec, micro), "invalid time") } /// Makes a new `NaiveTime` from hour, minute, second and microsecond. @@ -326,8 +331,14 @@ impl NaiveTime { /// ``` #[inline] #[must_use] - pub fn from_hms_micro_opt(hour: u32, min: u32, sec: u32, micro: u32) -> Option { - micro.checked_mul(1_000).and_then(|nano| NaiveTime::from_hms_nano_opt(hour, min, sec, nano)) + pub const fn from_hms_micro_opt( + hour: u32, + min: u32, + sec: u32, + micro: u32, + ) -> Option { + let nano = try_opt!(micro.checked_mul(1_000)); + NaiveTime::from_hms_nano_opt(hour, min, sec, nano) } /// Makes a new `NaiveTime` from hour, minute, second and nanosecond. @@ -339,8 +350,8 @@ impl NaiveTime { #[deprecated(since = "0.4.23", note = "use `from_hms_nano_opt()` instead")] #[inline] #[must_use] - pub fn from_hms_nano(hour: u32, min: u32, sec: u32, nano: u32) -> NaiveTime { - NaiveTime::from_hms_nano_opt(hour, min, sec, nano).expect("invalid time") + pub const fn from_hms_nano(hour: u32, min: u32, sec: u32, nano: u32) -> NaiveTime { + expect!(NaiveTime::from_hms_nano_opt(hour, min, sec, nano), "invalid time") } /// Makes a new `NaiveTime` from hour, minute, second and nanosecond. @@ -384,8 +395,8 @@ impl NaiveTime { #[deprecated(since = "0.4.23", note = "use `from_num_seconds_from_midnight_opt()` instead")] #[inline] #[must_use] - pub fn from_num_seconds_from_midnight(secs: u32, nano: u32) -> NaiveTime { - NaiveTime::from_num_seconds_from_midnight_opt(secs, nano).expect("invalid time") + pub const fn from_num_seconds_from_midnight(secs: u32, nano: u32) -> NaiveTime { + expect!(NaiveTime::from_num_seconds_from_midnight_opt(secs, nano), "invalid time") } /// Makes a new `NaiveTime` from the number of seconds since midnight and nanosecond.