Skip to content

Commit 19e6e5b

Browse files
Rollup merge of rust-lang#150522 - pitaj:stabilize-new-rangeinclusive, r=tgross35
Stabilize new inclusive range type and iterator type Part 1 of stabilizing the new range types for rust-lang#125687 stabilizes `core::range::RangeInclusive` and `core::range::RangeInclusiveIter`. Newly stable API: ```rust // in core and std pub mod range; // in core::range pub struct RangeInclusive<Idx> { pub start: Idx, pub last: Idx, } impl<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> { /* ... */ } impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> { pub const fn contains<U>(&self, item: &U) -> bool where Idx: [const] PartialOrd<U>, U: ?Sized + [const] PartialOrd<Idx>; pub const fn is_empty(&self) -> bool where Idx: [const] PartialOrd; } impl<Idx: Step> RangeInclusive<Idx> { pub fn iter(&self) -> RangeInclusiveIter<Idx>; } impl<T> const RangeBounds<T> for RangeInclusive<T> { /* ... */ } impl<T> const RangeBounds<T> for RangeInclusive<&T> { /* ... */ } impl<T> const From<RangeInclusive<T>> for legacy::RangeInclusive<T> { /* ... */ } impl<T> const From<legacy::RangeInclusive<T>> for RangeInclusive<T> { /* ... */ } pub struct RangeInclusiveIter<A>(/* ... */); impl<A: Step> RangeInclusiveIter<A> { pub fn remainder(self) -> Option<RangeInclusive<A>>; } impl<A: Step> Iterator for RangeInclusiveIter<A> { type Item = A; /* ... */ } impl<A: Step> DoubleEndedIterator for RangeInclusiveIter<A> { /* ... */ } impl<A: Step> FusedIterator for RangeInclusiveIter<A> { } impl<A: Step> IntoIterator for RangeInclusive<A> { type Item = A; type IntoIter = RangeInclusiveIter<A>; /* ... */ } impl ExactSizeIterator for RangeInclusiveIter<u8> { } impl ExactSizeIterator for RangeInclusiveIter<i8> { } unsafe impl<T> const SliceIndex<[T]> for range::RangeInclusive<usize> { type Output = [T]; /* ... */ } unsafe impl const SliceIndex<str> for range::RangeInclusive<usize> { type Output = str; /* ... */ } ``` I've removed the re-exports temporarily because from what I can tell, there's no way to make re-exports of stable items unstable. They will be added back and stabilized in a separate PR.
2 parents 80b44f6 + d2020fb commit 19e6e5b

File tree

11 files changed

+140
-46
lines changed

11 files changed

+140
-46
lines changed

library/core/src/index.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ unsafe impl<T> SliceIndex<[T]> for Clamp<ops::RangeFrom<usize>> {
315315
}
316316

317317
#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
318-
unsafe impl<T> SliceIndex<[T]> for Clamp<range::RangeTo<usize>> {
318+
unsafe impl<T> SliceIndex<[T]> for Clamp<ops::RangeTo<usize>> {
319319
type Output = [T];
320320

321321
fn get(self, slice: &[T]) -> Option<&Self::Output> {
@@ -408,7 +408,7 @@ unsafe impl<T> SliceIndex<[T]> for Clamp<ops::RangeToInclusive<usize>> {
408408
}
409409

410410
#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
411-
unsafe impl<T> SliceIndex<[T]> for Clamp<range::RangeFull> {
411+
unsafe impl<T> SliceIndex<[T]> for Clamp<ops::RangeFull> {
412412
type Output = [T];
413413

414414
fn get(self, slice: &[T]) -> Option<&Self::Output> {

library/core/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ pub mod pat;
324324
pub mod pin;
325325
#[unstable(feature = "random", issue = "130703")]
326326
pub mod random;
327-
#[unstable(feature = "new_range_api", issue = "125687")]
327+
#[stable(feature = "new_range_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
328328
pub mod range;
329329
pub mod result;
330330
pub mod sync;

library/core/src/random.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Random value generation.
22
3-
use crate::range::RangeFull;
3+
use crate::ops::RangeFull;
44

55
/// A source of randomness.
66
#[unstable(feature = "random", issue = "130703")]

library/core/src/range.rs

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,26 @@ mod iter;
2424
#[unstable(feature = "new_range_api", issue = "125687")]
2525
pub mod legacy;
2626

27-
use Bound::{Excluded, Included, Unbounded};
2827
#[doc(inline)]
29-
pub use iter::{RangeFromIter, RangeInclusiveIter, RangeIter};
30-
31-
#[doc(inline)]
32-
pub use crate::iter::Step;
28+
#[stable(feature = "new_range_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
29+
pub use iter::RangeInclusiveIter;
3330
#[doc(inline)]
34-
pub use crate::ops::{Bound, IntoBounds, OneSidedRange, RangeBounds, RangeFull, RangeTo};
31+
#[unstable(feature = "new_range_api", issue = "125687")]
32+
pub use iter::{RangeFromIter, RangeIter};
33+
34+
// FIXME(#125687): re-exports temporarily removed
35+
// Because re-exports of stable items (Bound, RangeBounds, RangeFull, RangeTo)
36+
// can't be made unstable.
37+
//
38+
// #[doc(inline)]
39+
// #[unstable(feature = "new_range_api", issue = "125687")]
40+
// pub use crate::iter::Step;
41+
// #[doc(inline)]
42+
// #[unstable(feature = "new_range_api", issue = "125687")]
43+
// pub use crate::ops::{Bound, IntoBounds, OneSidedRange, RangeBounds, RangeFull, RangeTo};
44+
use crate::iter::Step;
45+
use crate::ops::Bound::{self, Excluded, Included, Unbounded};
46+
use crate::ops::{IntoBounds, RangeBounds};
3547

3648
/// A (half-open) range bounded inclusively below and exclusively above
3749
/// (`start..end` in a future edition).
@@ -226,25 +238,24 @@ impl<T> const From<legacy::Range<T>> for Range<T> {
226238
/// The `start..=last` syntax is a `RangeInclusive`:
227239
///
228240
/// ```
229-
/// #![feature(new_range_api)]
230241
/// use core::range::RangeInclusive;
231242
///
232243
/// assert_eq!(RangeInclusive::from(3..=5), RangeInclusive { start: 3, last: 5 });
233244
/// assert_eq!(3 + 4 + 5, RangeInclusive::from(3..=5).into_iter().sum());
234245
/// ```
235246
#[lang = "RangeInclusiveCopy"]
236247
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
237-
#[unstable(feature = "new_range_api", issue = "125687")]
248+
#[stable(feature = "new_range_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
238249
pub struct RangeInclusive<Idx> {
239250
/// The lower bound of the range (inclusive).
240-
#[unstable(feature = "new_range_api", issue = "125687")]
251+
#[stable(feature = "new_range_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
241252
pub start: Idx,
242253
/// The upper bound of the range (inclusive).
243-
#[unstable(feature = "new_range_api", issue = "125687")]
254+
#[stable(feature = "new_range_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
244255
pub last: Idx,
245256
}
246257

247-
#[unstable(feature = "new_range_api", issue = "125687")]
258+
#[stable(feature = "new_range_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
248259
impl<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> {
249260
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
250261
self.start.fmt(fmt)?;
@@ -260,7 +271,6 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
260271
/// # Examples
261272
///
262273
/// ```
263-
/// #![feature(new_range_api)]
264274
/// use core::range::RangeInclusive;
265275
///
266276
/// assert!(!RangeInclusive::from(3..=5).contains(&2));
@@ -278,7 +288,7 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
278288
/// assert!(!RangeInclusive::from(f32::NAN..=1.0).contains(&1.0));
279289
/// ```
280290
#[inline]
281-
#[unstable(feature = "new_range_api", issue = "125687")]
291+
#[stable(feature = "new_range_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
282292
#[rustc_const_unstable(feature = "const_range", issue = "none")]
283293
pub const fn contains<U>(&self, item: &U) -> bool
284294
where
@@ -293,7 +303,6 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
293303
/// # Examples
294304
///
295305
/// ```
296-
/// #![feature(new_range_api)]
297306
/// use core::range::RangeInclusive;
298307
///
299308
/// assert!(!RangeInclusive::from(3..=5).is_empty());
@@ -304,14 +313,13 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
304313
/// The range is empty if either side is incomparable:
305314
///
306315
/// ```
307-
/// #![feature(new_range_api)]
308316
/// use core::range::RangeInclusive;
309317
///
310318
/// assert!(!RangeInclusive::from(3.0..=5.0).is_empty());
311319
/// assert!( RangeInclusive::from(3.0..=f32::NAN).is_empty());
312320
/// assert!( RangeInclusive::from(f32::NAN..=5.0).is_empty());
313321
/// ```
314-
#[unstable(feature = "new_range_api", issue = "125687")]
322+
#[stable(feature = "new_range_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
315323
#[inline]
316324
#[rustc_const_unstable(feature = "const_range", issue = "none")]
317325
pub const fn is_empty(&self) -> bool
@@ -330,15 +338,14 @@ impl<Idx: Step> RangeInclusive<Idx> {
330338
/// # Examples
331339
///
332340
/// ```
333-
/// #![feature(new_range_api)]
334341
/// use core::range::RangeInclusive;
335342
///
336343
/// let mut i = RangeInclusive::from(3..=8).iter().map(|n| n*n);
337344
/// assert_eq!(i.next(), Some(9));
338345
/// assert_eq!(i.next(), Some(16));
339346
/// assert_eq!(i.next(), Some(25));
340347
/// ```
341-
#[unstable(feature = "new_range_api", issue = "125687")]
348+
#[stable(feature = "new_range_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
342349
#[inline]
343350
pub fn iter(&self) -> RangeInclusiveIter<Idx> {
344351
self.clone().into_iter()
@@ -354,7 +361,7 @@ impl RangeInclusive<usize> {
354361
}
355362
}
356363

357-
#[unstable(feature = "new_range_api", issue = "125687")]
364+
#[stable(feature = "new_range_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
358365
#[rustc_const_unstable(feature = "const_range", issue = "none")]
359366
impl<T> const RangeBounds<T> for RangeInclusive<T> {
360367
fn start_bound(&self) -> Bound<&T> {
@@ -371,7 +378,7 @@ impl<T> const RangeBounds<T> for RangeInclusive<T> {
371378
/// If you need to use this implementation where `T` is unsized,
372379
/// consider using the `RangeBounds` impl for a 2-tuple of [`Bound<&T>`][Bound],
373380
/// i.e. replace `start..=end` with `(Bound::Included(start), Bound::Included(end))`.
374-
#[unstable(feature = "new_range_api", issue = "125687")]
381+
#[stable(feature = "new_range_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
375382
#[rustc_const_unstable(feature = "const_range", issue = "none")]
376383
impl<T> const RangeBounds<T> for RangeInclusive<&T> {
377384
fn start_bound(&self) -> Bound<&T> {
@@ -382,24 +389,24 @@ impl<T> const RangeBounds<T> for RangeInclusive<&T> {
382389
}
383390
}
384391

385-
// #[unstable(feature = "range_into_bounds", issue = "136903")]
386-
#[unstable(feature = "new_range_api", issue = "125687")]
392+
// #[stable(feature = "new_range_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
393+
#[unstable(feature = "range_into_bounds", issue = "136903")]
387394
#[rustc_const_unstable(feature = "const_range", issue = "none")]
388395
impl<T> const IntoBounds<T> for RangeInclusive<T> {
389396
fn into_bounds(self) -> (Bound<T>, Bound<T>) {
390397
(Included(self.start), Included(self.last))
391398
}
392399
}
393400

394-
#[unstable(feature = "new_range_api", issue = "125687")]
401+
#[stable(feature = "new_range_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
395402
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
396403
impl<T> const From<RangeInclusive<T>> for legacy::RangeInclusive<T> {
397404
#[inline]
398405
fn from(value: RangeInclusive<T>) -> Self {
399406
Self::new(value.start, value.last)
400407
}
401408
}
402-
#[unstable(feature = "new_range_api", issue = "125687")]
409+
#[stable(feature = "new_range_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
403410
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
404411
impl<T> const From<legacy::RangeInclusive<T>> for RangeInclusive<T> {
405412
#[inline]
@@ -650,12 +657,13 @@ impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> {
650657
}
651658
}
652659

660+
#[unstable(feature = "new_range_api", issue = "125687")]
653661
impl<T> From<legacy::RangeToInclusive<T>> for RangeToInclusive<T> {
654662
fn from(value: legacy::RangeToInclusive<T>) -> Self {
655663
Self { last: value.end }
656664
}
657665
}
658-
666+
#[unstable(feature = "new_range_api", issue = "125687")]
659667
impl<T> From<RangeToInclusive<T>> for legacy::RangeToInclusive<T> {
660668
fn from(value: RangeToInclusive<T>) -> Self {
661669
Self { end: value.last }

library/core/src/range/iter.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use crate::{intrinsics, mem};
1111
pub struct RangeIter<A>(legacy::Range<A>);
1212

1313
impl<A> RangeIter<A> {
14+
#[unstable(feature = "new_range_api", issue = "125687")]
1415
/// Returns the remainder of the range being iterated over.
1516
pub fn remainder(self) -> Range<A> {
1617
Range { start: self.0.start, end: self.0.end }
@@ -152,14 +153,15 @@ impl<A: Step> IntoIterator for Range<A> {
152153
}
153154

154155
/// By-value [`RangeInclusive`] iterator.
155-
#[unstable(feature = "new_range_api", issue = "125687")]
156+
#[stable(feature = "new_range_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
156157
#[derive(Debug, Clone)]
157158
pub struct RangeInclusiveIter<A>(legacy::RangeInclusive<A>);
158159

159160
impl<A: Step> RangeInclusiveIter<A> {
160161
/// Returns the remainder of the range being iterated over.
161162
///
162163
/// If the iterator is exhausted or empty, returns `None`.
164+
#[stable(feature = "new_range_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
163165
pub fn remainder(self) -> Option<RangeInclusive<A>> {
164166
if self.0.is_empty() {
165167
return None;
@@ -169,7 +171,7 @@ impl<A: Step> RangeInclusiveIter<A> {
169171
}
170172
}
171173

172-
#[unstable(feature = "new_range_api", issue = "125687")]
174+
#[stable(feature = "new_range_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
173175
impl<A: Step> Iterator for RangeInclusiveIter<A> {
174176
type Item = A;
175177

@@ -225,7 +227,7 @@ impl<A: Step> Iterator for RangeInclusiveIter<A> {
225227
}
226228
}
227229

228-
#[unstable(feature = "new_range_api", issue = "125687")]
230+
#[stable(feature = "new_range_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
229231
impl<A: Step> DoubleEndedIterator for RangeInclusiveIter<A> {
230232
#[inline]
231233
fn next_back(&mut self) -> Option<A> {
@@ -246,10 +248,10 @@ impl<A: Step> DoubleEndedIterator for RangeInclusiveIter<A> {
246248
#[unstable(feature = "trusted_len", issue = "37572")]
247249
unsafe impl<A: TrustedStep> TrustedLen for RangeInclusiveIter<A> {}
248250

249-
#[unstable(feature = "new_range_api", issue = "125687")]
251+
#[stable(feature = "new_range_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
250252
impl<A: Step> FusedIterator for RangeInclusiveIter<A> {}
251253

252-
#[unstable(feature = "new_range_api", issue = "125687")]
254+
#[stable(feature = "new_range_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
253255
impl<A: Step> IntoIterator for RangeInclusive<A> {
254256
type Item = A;
255257
type IntoIter = RangeInclusiveIter<A>;
@@ -276,7 +278,7 @@ macro_rules! range_exact_iter_impl {
276278

277279
macro_rules! range_incl_exact_iter_impl {
278280
($($t:ty)*) => ($(
279-
#[unstable(feature = "new_range_api", issue = "125687")]
281+
#[stable(feature = "new_range_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
280282
impl ExactSizeIterator for RangeInclusiveIter<$t> { }
281283
)*)
282284
}
@@ -305,6 +307,7 @@ impl<A: Step> RangeFromIter<A> {
305307
/// Returns the remainder of the range being iterated over.
306308
#[inline]
307309
#[rustc_inherit_overflow_checks]
310+
#[unstable(feature = "new_range_api", issue = "125687")]
308311
pub fn remainder(self) -> RangeFrom<A> {
309312
if intrinsics::overflow_checks() {
310313
if !self.first {

library/core/src/slice/index.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ mod private_slice_index {
127127

128128
#[unstable(feature = "new_range_api", issue = "125687")]
129129
impl Sealed for range::Range<usize> {}
130-
#[unstable(feature = "new_range_api", issue = "125687")]
130+
#[stable(feature = "new_range_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
131131
impl Sealed for range::RangeInclusive<usize> {}
132132
#[unstable(feature = "new_range_api", issue = "125687")]
133133
impl Sealed for range::RangeToInclusive<usize> {}
@@ -724,7 +724,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeInclusive<usize> {
724724
}
725725
}
726726

727-
#[unstable(feature = "new_range_api", issue = "125687")]
727+
#[stable(feature = "new_range_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
728728
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
729729
unsafe impl<T> const SliceIndex<[T]> for range::RangeInclusive<usize> {
730730
type Output = [T];

library/core/src/str/traits.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,7 @@ unsafe impl const SliceIndex<str> for ops::RangeInclusive<usize> {
672672
}
673673
}
674674

675-
#[unstable(feature = "new_range_api", issue = "125687")]
675+
#[stable(feature = "new_range_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
676676
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
677677
unsafe impl const SliceIndex<str> for range::RangeInclusive<usize> {
678678
type Output = str;

tests/ui/new-range/disabled.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44

55
fn main() {
66
// Unchanged
7-
let a: core::range::RangeFull = ..;
8-
let b: core::range::RangeTo<u8> = ..2;
7+
let a: core::ops::RangeFull = ..;
8+
let b: core::ops::RangeTo<u8> = ..2;
99

10-
let _: core::ops::RangeFull = a;
11-
let _: core::ops::RangeTo<u8> = b;
10+
// FIXME(#125687): re-exports temporarily removed
11+
// let _: core::range::RangeFull = a;
12+
// let _: core::range::RangeTo<u8> = b;
1213

1314
// Changed
1415
let a: core::range::legacy::RangeFrom<u8> = 1..;

tests/ui/new-range/enabled.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@
55

66
fn main() {
77
// Unchanged
8-
let a: core::range::RangeFull = ..;
9-
let b: core::range::RangeTo<u8> = ..2;
8+
let a: core::ops::RangeFull = ..;
9+
let b: core::ops::RangeTo<u8> = ..2;
1010

11-
let _: core::ops::RangeFull = a;
12-
let _: core::ops::RangeTo<u8> = b;
11+
// FIXME(#125687): re-exports temporarily removed
12+
// let _: core::range::RangeFull = a;
13+
// let _: core::range::RangeTo<u8> = b;
1314

1415
// Changed
1516
let a: core::range::RangeFrom<u8> = 1..;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Stable
2+
3+
use std::range::{RangeInclusive, RangeInclusiveIter};
4+
5+
fn range_inclusive(mut r: RangeInclusive<usize>) {
6+
r.start;
7+
r.last;
8+
r.contains(&5);
9+
r.is_empty();
10+
r.iter();
11+
12+
let mut i = r.into_iter();
13+
i.next();
14+
i.remainder();
15+
}
16+
17+
// Unstable module
18+
19+
use std::range::legacy; //~ ERROR unstable
20+
21+
// Unstable types
22+
23+
use std::range::RangeFrom; //~ ERROR unstable
24+
use std::range::Range; //~ ERROR unstable
25+
use std::range::RangeFromIter; //~ ERROR unstable
26+
use std::range::RangeIter; //~ ERROR unstable
27+
28+
fn main() {}

0 commit comments

Comments
 (0)