From b570ebd37eb81fd8dff1b2e4651609d766043597 Mon Sep 17 00:00:00 2001 From: "Tim (Theemathas Chirananthavat)" Date: Sat, 4 Jul 2026 17:54:11 +0700 Subject: [PATCH 1/2] Weaken guarantee for `From for RangeInclusive` As per https://github.com/rust-lang/rust/pull/155114#issuecomment-4845403701, this `From` impl no longer guarantees panicking for exhausted iterators. Instead, it only guarantees that the conversion will either panic or produce an empty range. This is done so that we can optimize the implementation of `legacy::RangeInclusive` in a way such that we cannot check if it has been exhausted in a generic context without a `Step` and/or `PartialOrd` bound. --- library/core/src/range.rs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/library/core/src/range.rs b/library/core/src/range.rs index fb7a51a779f6d..74d1cfde034eb 100644 --- a/library/core/src/range.rs +++ b/library/core/src/range.rs @@ -402,7 +402,8 @@ const impl From> for RangeInclusive { /// /// # Panics /// - /// Panics if the legacy range iterator has been exhausted. + /// If the legacy range iterator has been exhausted, + /// this function will either panic or return an empty range. /// /// # Examples /// @@ -419,19 +420,16 @@ const impl From> for RangeInclusive { /// assert_eq!((empty.start, empty.last), (0, 0)); /// ``` /// - /// ```should_panic + /// ``` /// use core::range::legacy; /// use core::range::RangeInclusive; + /// use std::panic::catch_unwind; /// /// let mut exhausted: legacy::RangeInclusive = 0..=0; /// exhausted.next(); - /// # if exhausted.is_empty() { - /// # // assert!s don't work correctly in `should_panic` doctests since you - /// # // can't assert the panic message. Skip the rest of the test instead, - /// # // so that the expected panic doesn't happen and the test fails. - /// assert!(exhausted.is_empty()); - /// let _ = RangeInclusive::from(exhausted); // this panics - /// # } + /// let result = catch_unwind(|| RangeInclusive::from(exhausted)); + /// // The `from` call either panicked or returned an empty range. + /// assert!(result.is_err() || result.is_ok_and(|range| range.is_empty())); /// ``` #[inline] fn from(value: legacy::RangeInclusive) -> Self { From 1920371ad120c8c23e0254e04086d448ef46a2ee Mon Sep 17 00:00:00 2001 From: "Tim (Theemathas Chirananthavat)" Date: Sun, 5 Jul 2026 22:55:53 +0700 Subject: [PATCH 2/2] Disable `RangeInclusive`'s `From` test when unwinding isn't available. --- library/core/src/range.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/library/core/src/range.rs b/library/core/src/range.rs index 74d1cfde034eb..07f423edcfea1 100644 --- a/library/core/src/range.rs +++ b/library/core/src/range.rs @@ -421,6 +421,10 @@ const impl From> for RangeInclusive { /// ``` /// /// ``` + /// # // This test requires unwinding to work. + /// # // Disable it when unwinding isn't available. + /// # #[cfg(panic = "unwind")] + /// # fn main() { /// use core::range::legacy; /// use core::range::RangeInclusive; /// use std::panic::catch_unwind; @@ -430,6 +434,9 @@ const impl From> for RangeInclusive { /// let result = catch_unwind(|| RangeInclusive::from(exhausted)); /// // The `from` call either panicked or returned an empty range. /// assert!(result.is_err() || result.is_ok_and(|range| range.is_empty())); + /// # } + /// # #[cfg(not(panic = "unwind"))] + /// # fn main() {} /// ``` #[inline] fn from(value: legacy::RangeInclusive) -> Self {