From 620e92f0166738113eac8ec774253501324a6e75 Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Tue, 3 Mar 2026 18:49:37 -0700 Subject: [PATCH] stabilize new Range type and iterator stabilizes `core::range::Range` stabilizes `core::range::RangeIter` stabilizes `std::range` which was missed in prior PRs Updates docs to reflect stabilization (removed "experimental") `RangeIter::remainder` is excluded from stabilization --- compiler/rustc_index/src/lib.rs | 6 +- library/core/src/range.rs | 56 ++++++++----------- library/core/src/range/iter.rs | 13 ++--- library/core/src/slice/index.rs | 4 +- library/core/src/str/traits.rs | 2 +- library/coretests/tests/lib.rs | 1 - library/std/src/lib.rs | 2 +- .../feature-gates/feature-gate-new_range.rs | 2 - .../feature-gate-new_range.stderr | 6 +- tests/ui/new-range/disabled.rs | 2 +- tests/ui/new-range/enabled.rs | 1 - tests/ui/range/new_range_stability.rs | 22 ++++++-- tests/ui/range/new_range_stability.stderr | 34 ++++------- 13 files changed, 72 insertions(+), 79 deletions(-) diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index dc7fe03dcf3c6..1b8c8e3bd2c86 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -2,9 +2,13 @@ #![cfg_attr(all(feature = "nightly", test), feature(stmt_expr_attributes))] #![cfg_attr(all(feature = "nightly", test), feature(test))] #![cfg_attr(feature = "nightly", feature(extend_one, step_trait))] -#![cfg_attr(feature = "nightly", feature(new_range_api))] // tidy-alphabetical-end +// FIXME(#125687): new_range_api recently stabilized +// Remove this when it hits stable. cfg(bootstrap) +#![allow(stable_features)] +#![cfg_attr(feature = "nightly", feature(new_range_api))] + pub mod bit_set; #[cfg(feature = "nightly")] pub mod interval; diff --git a/library/core/src/range.rs b/library/core/src/range.rs index 2007533e68e54..d4be1b67d3862 100644 --- a/library/core/src/range.rs +++ b/library/core/src/range.rs @@ -1,19 +1,18 @@ -//! # Experimental replacement range types +//! # Replacement range types //! -//! The types within this module are meant to replace the existing -//! `Range`, `RangeInclusive`, and `RangeFrom` types in a future edition. +//! The types within this module are meant to replace the legacy `Range`, +//! `RangeInclusive`, `RangeToInclusive` and `RangeFrom` types in a future edition. //! //! ``` -//! #![feature(new_range_api)] -//! use core::range::{Range, RangeFrom, RangeInclusive}; +//! use core::range::{Range, RangeFrom, RangeInclusive, RangeToInclusive}; //! //! let arr = [0, 1, 2, 3, 4]; -//! assert_eq!(arr[ .. ], [0, 1, 2, 3, 4]); -//! assert_eq!(arr[ .. 3 ], [0, 1, 2 ]); -//! assert_eq!(arr[ ..=3 ], [0, 1, 2, 3 ]); -//! assert_eq!(arr[ RangeFrom::from(1.. )], [ 1, 2, 3, 4]); -//! assert_eq!(arr[ Range::from(1..3 )], [ 1, 2 ]); -//! assert_eq!(arr[RangeInclusive::from(1..=3)], [ 1, 2, 3 ]); +//! assert_eq!(arr[ .. ], [0, 1, 2, 3, 4]); +//! assert_eq!(arr[ .. 3 ], [0, 1, 2 ]); +//! assert_eq!(arr[RangeToInclusive::from( ..=3)], [0, 1, 2, 3 ]); +//! assert_eq!(arr[ RangeFrom::from(1.. )], [ 1, 2, 3, 4]); +//! assert_eq!(arr[ Range::from(1..3 )], [ 1, 2 ]); +//! assert_eq!(arr[ RangeInclusive::from(1..=3)], [ 1, 2, 3 ]); //! ``` use crate::fmt; @@ -21,7 +20,7 @@ use crate::hash::Hash; mod iter; -#[unstable(feature = "new_range_api", issue = "125687")] +#[unstable(feature = "new_range_api_legacy", issue = "125687")] pub mod legacy; #[doc(inline)] @@ -31,7 +30,7 @@ pub use iter::RangeFromIter; #[stable(feature = "new_range_inclusive_api", since = "1.95.0")] pub use iter::RangeInclusiveIter; #[doc(inline)] -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] pub use iter::RangeIter; // FIXME(#125687): re-exports temporarily removed @@ -57,7 +56,6 @@ use crate::ops::{IntoBounds, OneSidedRange, OneSidedRangeBound, RangeBounds}; /// # Examples /// /// ``` -/// #![feature(new_range_api)] /// use core::range::Range; /// /// assert_eq!(Range::from(3..5), Range { start: 3, end: 5 }); @@ -66,17 +64,17 @@ use crate::ops::{IntoBounds, OneSidedRange, OneSidedRangeBound, RangeBounds}; #[lang = "RangeCopy"] #[derive(Copy, Hash)] #[derive_const(Clone, Default, PartialEq, Eq)] -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] pub struct Range { /// The lower bound of the range (inclusive). - #[unstable(feature = "new_range_api", issue = "125687")] + #[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] pub start: Idx, /// The upper bound of the range (exclusive). - #[unstable(feature = "new_range_api", issue = "125687")] + #[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] pub end: Idx, } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] impl fmt::Debug for Range { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { self.start.fmt(fmt)?; @@ -94,7 +92,6 @@ impl Range { /// # Examples /// /// ``` - /// #![feature(new_range_api)] /// use core::range::Range; /// /// let mut i = Range::from(3..9).iter().map(|n| n*n); @@ -102,7 +99,7 @@ impl Range { /// assert_eq!(i.next(), Some(16)); /// assert_eq!(i.next(), Some(25)); /// ``` - #[unstable(feature = "new_range_api", issue = "125687")] + #[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] #[inline] pub fn iter(&self) -> RangeIter { self.clone().into_iter() @@ -115,7 +112,6 @@ impl> Range { /// # Examples /// /// ``` - /// #![feature(new_range_api)] /// use core::range::Range; /// /// assert!(!Range::from(3..5).contains(&2)); @@ -132,7 +128,7 @@ impl> Range { /// assert!(!Range::from(f32::NAN..1.0).contains(&0.5)); /// ``` #[inline] - #[unstable(feature = "new_range_api", issue = "125687")] + #[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_range", issue = "none")] pub const fn contains(&self, item: &U) -> bool where @@ -147,7 +143,6 @@ impl> Range { /// # Examples /// /// ``` - /// #![feature(new_range_api)] /// use core::range::Range; /// /// assert!(!Range::from(3..5).is_empty()); @@ -158,7 +153,6 @@ impl> Range { /// The range is empty if either side is incomparable: /// /// ``` - /// #![feature(new_range_api)] /// use core::range::Range; /// /// assert!(!Range::from(3.0..5.0).is_empty()); @@ -166,7 +160,7 @@ impl> Range { /// assert!( Range::from(f32::NAN..5.0).is_empty()); /// ``` #[inline] - #[unstable(feature = "new_range_api", issue = "125687")] + #[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_range", issue = "none")] pub const fn is_empty(&self) -> bool where @@ -176,7 +170,7 @@ impl> Range { } } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_range", issue = "none")] impl const RangeBounds for Range { fn start_bound(&self) -> Bound<&T> { @@ -193,7 +187,7 @@ impl const RangeBounds for Range { /// If you need to use this implementation where `T` is unsized, /// consider using the `RangeBounds` impl for a 2-tuple of [`Bound<&T>`][Bound], /// i.e. replace `start..end` with `(Bound::Included(start), Bound::Excluded(end))`. -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_range", issue = "none")] impl const RangeBounds for Range<&T> { fn start_bound(&self) -> Bound<&T> { @@ -204,8 +198,7 @@ impl const RangeBounds for Range<&T> { } } -// #[unstable(feature = "range_into_bounds", issue = "136903")] -#[unstable(feature = "new_range_api", issue = "125687")] +#[unstable(feature = "range_into_bounds", issue = "136903")] #[rustc_const_unstable(feature = "const_range", issue = "none")] impl const IntoBounds for Range { fn into_bounds(self) -> (Bound, Bound) { @@ -213,7 +206,7 @@ impl const IntoBounds for Range { } } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_convert", issue = "143773")] impl const From> for legacy::Range { #[inline] @@ -221,8 +214,7 @@ impl const From> for legacy::Range { Self { start: value.start, end: value.end } } } - -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_convert", issue = "143773")] impl const From> for Range { #[inline] diff --git a/library/core/src/range/iter.rs b/library/core/src/range/iter.rs index c29b498bd25f8..a5db3699bc402 100644 --- a/library/core/src/range/iter.rs +++ b/library/core/src/range/iter.rs @@ -6,7 +6,7 @@ use crate::range::{Range, RangeFrom, RangeInclusive, legacy}; use crate::{intrinsics, mem}; /// By-value [`Range`] iterator. -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] #[derive(Debug, Clone)] pub struct RangeIter(legacy::Range); @@ -17,7 +17,6 @@ impl RangeIter { /// # Examples /// /// ``` - /// #![feature(new_range_api)] /// #![feature(new_range_remainder)] /// /// let range = core::range::Range::from(3..11); @@ -65,7 +64,7 @@ unsafe_range_trusted_random_access_impl! { u64 i64 } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] impl Iterator for RangeIter { type Item = A; @@ -133,7 +132,7 @@ impl Iterator for RangeIter { } } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] impl DoubleEndedIterator for RangeIter { #[inline] fn next_back(&mut self) -> Option { @@ -154,10 +153,10 @@ impl DoubleEndedIterator for RangeIter { #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl TrustedLen for RangeIter {} -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] impl FusedIterator for RangeIter {} -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] impl IntoIterator for Range { type Item = A; type IntoIter = RangeIter; @@ -300,7 +299,7 @@ impl IntoIterator for RangeInclusive { // since e.g. `(0..=u64::MAX).len()` would be `u64::MAX + 1`. macro_rules! range_exact_iter_impl { ($($t:ty)*) => ($( - #[unstable(feature = "new_range_api", issue = "125687")] + #[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] impl ExactSizeIterator for RangeIter<$t> { } )*) } diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index b30f82a5783ad..f1727a1f629cb 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -125,7 +125,7 @@ mod private_slice_index { #[stable(feature = "slice_index_with_ops_bound_pair", since = "1.53.0")] impl Sealed for (ops::Bound, ops::Bound) {} - #[unstable(feature = "new_range_api", issue = "125687")] + #[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] impl Sealed for range::Range {} #[stable(feature = "new_range_inclusive_api", since = "1.95.0")] impl Sealed for range::RangeInclusive {} @@ -458,7 +458,7 @@ unsafe impl const SliceIndex<[T]> for ops::Range { } } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_index", issue = "143775")] unsafe impl const SliceIndex<[T]> for range::Range { type Output = [T]; diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs index 336f074883d25..da0039f055fde 100644 --- a/library/core/src/str/traits.rs +++ b/library/core/src/str/traits.rs @@ -258,7 +258,7 @@ unsafe impl const SliceIndex for ops::Range { } } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_index", issue = "143775")] unsafe impl const SliceIndex for range::Range { type Output = str; diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index fba144c0e9839..90a33aeead150 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -85,7 +85,6 @@ #![feature(maybe_uninit_uninit_array_transpose)] #![feature(min_specialization)] #![feature(never_type)] -#![feature(new_range_api)] #![feature(next_index)] #![feature(non_exhaustive_omitted_patterns_lint)] #![feature(nonzero_from_str_radix)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 7497fa100eb9e..1730742dffe93 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -537,7 +537,7 @@ pub use core::option; pub use core::pin; #[stable(feature = "rust1", since = "1.0.0")] pub use core::ptr; -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] pub use core::range; #[stable(feature = "rust1", since = "1.0.0")] pub use core::result; diff --git a/tests/ui/feature-gates/feature-gate-new_range.rs b/tests/ui/feature-gates/feature-gate-new_range.rs index 32eeb0424b645..6fd4f19fa8dc6 100644 --- a/tests/ui/feature-gates/feature-gate-new_range.rs +++ b/tests/ui/feature-gates/feature-gate-new_range.rs @@ -1,5 +1,3 @@ -#![feature(new_range_api)] - fn main() { let a: core::range::RangeFrom = 1..; //~^ ERROR mismatched types diff --git a/tests/ui/feature-gates/feature-gate-new_range.stderr b/tests/ui/feature-gates/feature-gate-new_range.stderr index b7f70d30bfa0b..c7f2d2171b106 100644 --- a/tests/ui/feature-gates/feature-gate-new_range.stderr +++ b/tests/ui/feature-gates/feature-gate-new_range.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/feature-gate-new_range.rs:4:41 + --> $DIR/feature-gate-new_range.rs:2:41 | LL | let a: core::range::RangeFrom = 1..; | -------------------------- ^^^ expected `RangeFrom`, found `RangeFrom<{integer}>` @@ -14,7 +14,7 @@ LL | let a: core::range::RangeFrom = (1..).into(); | + ++++++++ error[E0308]: mismatched types - --> $DIR/feature-gate-new_range.rs:6:37 + --> $DIR/feature-gate-new_range.rs:4:37 | LL | let b: core::range::Range = 2..3; | ---------------------- ^^^^ expected `Range`, found `Range<{integer}>` @@ -29,7 +29,7 @@ LL | let b: core::range::Range = (2..3).into(); | + ++++++++ error[E0308]: mismatched types - --> $DIR/feature-gate-new_range.rs:8:46 + --> $DIR/feature-gate-new_range.rs:6:46 | LL | let c: core::range::RangeInclusive = 4..=5; | ------------------------------- ^^^^^ expected `RangeInclusive`, found `RangeInclusive<{integer}>` diff --git a/tests/ui/new-range/disabled.rs b/tests/ui/new-range/disabled.rs index ab6fbd3276b3f..528c464117a13 100644 --- a/tests/ui/new-range/disabled.rs +++ b/tests/ui/new-range/disabled.rs @@ -1,6 +1,6 @@ //@ check-pass -#![feature(new_range_api)] +#![feature(new_range_api_legacy)] fn main() { // Unchanged diff --git a/tests/ui/new-range/enabled.rs b/tests/ui/new-range/enabled.rs index b49681eaacde3..6d9a1259b7756 100644 --- a/tests/ui/new-range/enabled.rs +++ b/tests/ui/new-range/enabled.rs @@ -1,6 +1,5 @@ //@ check-pass -#![feature(new_range_api)] #![feature(new_range)] fn main() { diff --git a/tests/ui/range/new_range_stability.rs b/tests/ui/range/new_range_stability.rs index 71a0f02e58968..965be17efa747 100644 --- a/tests/ui/range/new_range_stability.rs +++ b/tests/ui/range/new_range_stability.rs @@ -6,6 +6,7 @@ use std::range::{ RangeToInclusive, RangeFrom, RangeFromIter, + Range, }; fn range_inclusive(mut r: RangeInclusive) { @@ -43,13 +44,24 @@ fn range_from(mut r: RangeFrom) { i.remainder(); //~ ERROR unstable } -// Unstable module +fn range(mut r: Range) { + &[1, 2, 3][r]; -use std::range::legacy; //~ ERROR unstable + r.start; + r.end; + r.contains(&5); + r.is_empty(); + r.iter(); -// Unstable types + let mut i = r.into_iter(); + i.next(); -use std::range::Range; //~ ERROR unstable -use std::range::RangeIter; //~ ERROR unstable + // Left unstable + i.remainder(); //~ ERROR unstable +} + +// Unstable module + +use std::range::legacy; //~ ERROR unstable fn main() {} diff --git a/tests/ui/range/new_range_stability.stderr b/tests/ui/range/new_range_stability.stderr index 64ef6a4166873..ac269a2b2227e 100644 --- a/tests/ui/range/new_range_stability.stderr +++ b/tests/ui/range/new_range_stability.stderr @@ -1,35 +1,25 @@ -error[E0658]: use of unstable library feature `new_range_api` - --> $DIR/new_range_stability.rs:48:5 +error[E0658]: use of unstable library feature `new_range_api_legacy` + --> $DIR/new_range_stability.rs:65:5 | LL | use std::range::legacy; | ^^^^^^^^^^^^^^^^^^ | = note: see issue #125687 for more information - = help: add `#![feature(new_range_api)]` to the crate attributes to enable + = help: add `#![feature(new_range_api_legacy)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: use of unstable library feature `new_range_api` - --> $DIR/new_range_stability.rs:52:5 - | -LL | use std::range::Range; - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #125687 for more information - = help: add `#![feature(new_range_api)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: use of unstable library feature `new_range_api` - --> $DIR/new_range_stability.rs:53:5 +error[E0658]: use of unstable library feature `new_range_remainder` + --> $DIR/new_range_stability.rs:23:7 | -LL | use std::range::RangeIter; - | ^^^^^^^^^^^^^^^^^^^^^ +LL | i.remainder(); + | ^^^^^^^^^ | - = note: see issue #125687 for more information - = help: add `#![feature(new_range_api)]` to the crate attributes to enable + = note: see issue #154458 for more information + = help: add `#![feature(new_range_remainder)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `new_range_remainder` - --> $DIR/new_range_stability.rs:22:7 + --> $DIR/new_range_stability.rs:44:7 | LL | i.remainder(); | ^^^^^^^^^ @@ -39,7 +29,7 @@ LL | i.remainder(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `new_range_remainder` - --> $DIR/new_range_stability.rs:43:7 + --> $DIR/new_range_stability.rs:60:7 | LL | i.remainder(); | ^^^^^^^^^ @@ -48,6 +38,6 @@ LL | i.remainder(); = help: add `#![feature(new_range_remainder)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0658`.