diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ee616c773..a7795fe65 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 2745c67eb..76b1551b0 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 639a09144..113dfb38e 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/lib.rs b/src/lib.rs index 3737d1a9b..32fb02ed5 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), + } + }; +} diff --git a/src/naive/date.rs b/src/naive/date.rs index b9404a15f..c616d5dbc 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. diff --git a/src/naive/time/mod.rs b/src/naive/time/mod.rs index 3700c5cba..794c8d726 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.