Skip to content

Stabilize new inclusive range type and iterator type - #150522

Merged
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
pitaj:stabilize-new-rangeinclusive
Feb 7, 2026
Merged

Stabilize new inclusive range type and iterator type#150522
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
pitaj:stabilize-new-rangeinclusive

Conversation

@pitaj

@pitajpitaj commented Dec 30, 2025

Copy link
Copy Markdown
Contributor

Part 1 of stabilizing the new range types for #125687

stabilizes core::range::RangeInclusive and core::range::RangeInclusiveIter. Newly stable API:

// in core and stdpubmod range;// in core::rangepubstructRangeInclusive<Idx>{pubstart:Idx,publast:Idx,}impl<Idx: fmt::Debug> fmt::DebugforRangeInclusive<Idx>{/* ... */}impl<Idx:PartialOrd<Idx>>RangeInclusive<Idx>{pubconstfn contains<U>(&self,item:&U) -> boolwhereIdx:[const]PartialOrd<U>,U: ?Sized + [const]PartialOrd<Idx>;
pub const fnis_empty(&self) -> boolwhereIdx:[const]PartialOrd;}impl<Idx:Step> RangeInclusive<Idx>{pubfniter(&self) -> RangeInclusiveIter<Idx>;}impl<T> const RangeBounds<T>forRangeInclusive<T>{/* ... */}impl<T> const RangeBounds<T>forRangeInclusive<&T>{/* ... */}impl<T> const From<RangeInclusive<T>>for legacy::RangeInclusive<T>{/* ... */}impl<T> const From<legacy::RangeInclusive<T>>forRangeInclusive<T>{/* ... */}pubstructRangeInclusiveIter<A>(/* ... */);
impl<A:Step> RangeInclusiveIter<A> {pubfnremainder(self) -> Option<RangeInclusive<A>>;}impl<A:Step>IteratorforRangeInclusiveIter<A>{typeItem = A;/* ... */}impl<A:Step>DoubleEndedIteratorforRangeInclusiveIter<A>{/* ... */}impl<A:Step>FusedIteratorforRangeInclusiveIter<A>{}impl<A:Step>IntoIteratorforRangeInclusive<A>{typeItem = A;typeIntoIter = RangeInclusiveIter<A>;/* ... */}implExactSizeIteratorforRangeInclusiveIter<u8>{}implExactSizeIteratorforRangeInclusiveIter<i8>{}unsafeimpl<T>constSliceIndex<[T]>for range::RangeInclusive<usize>{typeOutput = [T];/* ... */}unsafeimplconstSliceIndex<str>for range::RangeInclusive<usize>{typeOutput = 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.

@rustbotrustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Dec 30, 2025
@rustbot

Copy link
Copy Markdown
Collaborator

r? @jackh726

rustbot has assigned @jackh726.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@jackh726

Copy link
Copy Markdown
Member

r? libs-api

@rustbotrustbot added the T-libs-api [DEPRECATED; DO NOT USE] label Dec 31, 2025
@rustbotrustbot assigned BurntSushi and unassigned jackh726Dec 31, 2025
Comment threadlibrary/core/src/range.rs Outdated
Comment threadlibrary/core/src/range.rs
Comment threadlibrary/core/src/range.rs Outdated
@rustbotrustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jan 24, 2026
@rustbot

Copy link
Copy Markdown
Collaborator

Reminder, once the PR becomes ready for a review, use @rustbot ready.

Comment threadlibrary/core/src/range.rs
@tgross35

Copy link
Copy Markdown
Member

I added an API summary of what is stabilized here to the top post, nominating for @rust-lang/libs-api to double check and nudge the FCP. There is an ongoing proposed FCP at #125687 (comment), but maybe it makes sense to restart it here with smaller scope?

Everything seems to match up with the traits available on ops::RangeInclusive, delta ExactSizeIterator for i16/u16 (expected as it is incorrect on 16-bit targets).

Two small concerns found from digging around the issue and other discussion:

@rustbot label +I-libs-api-nominated

@rustbotrustbot added the I-libs-api-nominated [DEPRECATED; DO NOT USE] label Jan 24, 2026
@scottmcm

Copy link
Copy Markdown
Member

Field names are "start" and "last" which don't typically go together. It used to be "start" and "end" like

TBH, I never thought "start" and "end" went together either. A race is start-to-finish where you place somewhere in first..=last; a story commonly has a beginning, middle, and end.

Are any of those better enough to bother changing something? Dunno.

@sendittothenewts

Copy link
Copy Markdown
Should we consider `start`->`first` so we have "first" and "last"?

When I suggested changing end to last on the inclusive ranges, it did occur to me that this would be more consistent. I didn't suggest this change because it would bring Range, RangeFrom and arguably RangeBounds::start_bound into the blast radius for little benefit. Also, there is no first method on iterators to be consistent with.

@Amanieu

Copy link
Copy Markdown
Member

We discussed the field names in the @rust-lang/libs-api meeting and were inclined to keep them as they currently are.

@AmanieuAmanieu removed the I-libs-api-nominated [DEPRECATED; DO NOT USE] label Jan 27, 2026
@pitaj

Copy link
Copy Markdown
ContributorAuthor

As they currently are in this PR, or as they currently are on the old RangeInclusive types?

@tgross35tgross35 assigned tgross35 and unassigned BurntSushiJan 31, 2026
@tgross35

Copy link
Copy Markdown
Member

As they currently are in this PR, or as they currently are on the old RangeInclusive types?

I believe as they are in this PR. From the meeting notes at https://hackmd.io/_EpeHNVySbqHWCSqXwLX1w#nominated-rusttf150522-Stabilize-new-inclusive-range-type-and-iterator-type

Amanieu: I'm happy with "start" and "last". Any objections?
[...]
Josh: I'd ship the currently proposed API.

And no different names mentioned.

@rustbot

This comment has been minimized.

@pitaj

pitaj commented Feb 7, 2026

Copy link
Copy Markdown
ContributorAuthor

@rustbot ready

I can rebase and squash everything together upon approval

@rustbotrustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Feb 7, 2026

@tgross35tgross35 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FCP completed at #125687 (comment). The basic API is consistent with what is in #125687 (comment) and the few traits not mentioned there match up with existing range types (as I noted at #150522 (comment)). libs-api has also had a chance to talk about this in their meeting so I think everything is all set.

r=me with a squash.

View changes since this review

@tgross35

Copy link
Copy Markdown
Member

@bors delegate+

@rust-bors

rust-borsBot commented Feb 7, 2026

Copy link
Copy Markdown
Contributor

✌️ @pitaj, you can now approve this pull request!

If @tgross35 told you to "r=me" after making some further change, then please make that change and post @bors r=tgross35.

stabilizes `core::range::RangeInclusive`
and `core::range::RangeInclusiveIter`
and the `core::range` module
@pitaj
pitajforce-pushed the stabilize-new-rangeinclusive branch from f458fc7 to d2020fbCompareFebruary 7, 2026 04:37
@rustbot

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@pitaj

pitaj commented Feb 7, 2026

Copy link
Copy Markdown
ContributorAuthor

@bors r=tgross35

@rust-bors

rust-borsBot commented Feb 7, 2026

Copy link
Copy Markdown
Contributor

📌 Commit d2020fb has been approved by tgross35

It is now in the queue for this repository.

@rust-borsrust-borsBot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 7, 2026
jhpratt added a commit to jhpratt/rust that referenced this pull request Feb 7, 2026
…, 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.
@jhprattjhpratt mentioned this pull request Feb 7, 2026
rust-borsBot pushed a commit that referenced this pull request Feb 7, 2026
Rollup of 4 pull requests
Successful merges:
- #148590 (Stabilize `atomic_try_update`and deprecate `fetch_update` starting 1.99.0)
- #150522 (Stabilize new inclusive range type and iterator type)
- #151576 (Stabilize `core::hint::cold_path`)
- #152199 (Move `rustc_query_system::cache`.)
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Feb 7, 2026
…, 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.
This was referenced Feb 7, 2026
rust-borsBot pushed a commit that referenced this pull request Feb 7, 2026
…uwer
Rollup of 8 pull requests
Successful merges:
- #148590 (Stabilize `atomic_try_update`and deprecate `fetch_update` starting 1.99.0)
- #150522 (Stabilize new inclusive range type and iterator type)
- #152235 (Convert to inline diagnostics in `rustc_parse`)
- #152267 (feat: Implement `int_from_ascii` for `NonZero<T>`)
- #151576 (Stabilize `core::hint::cold_path`)
- #151933 (Linker-plugin-based LTO: give an explanation how to use linker-plugin-lto with full LTO)
- #152010 (Ignore all debuginfo tests for LLDB that we do not run in CI)
- #152199 (Move `rustc_query_system::cache`.)
@rust-bors
rust-borsBot merged commit 29079e4 into rust-lang:mainFeb 7, 2026
11 checks passed
@rustbotrustbot added this to the 1.95.0 milestone Feb 7, 2026
rust-timer added a commit that referenced this pull request Feb 7, 2026
Rollup merge of #150522 - pitaj:stabilize-new-rangeinclusive, r=tgross35
Stabilize new inclusive range type and iterator type
Part 1 of stabilizing the new range types for #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.
@tgross35tgross35 added the relnotes Marks issues that should be documented in the release notes of the next release. label Mar 2, 2026
@BoxyUwUBoxyUwU mentioned this pull request Apr 2, 2026
@oxalica

oxalica commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

1.95 is released now. As a user, I have a question about the two co-existing range types: if I want to use the type (say storing it in a struct private field), is it preferred to use std::range::RangeInclusive and to consider std::ops::RangeInclusive soft-deprecated? If this is the case, then it is quite annoying that a..=b does not work out-of-box. This means the preferred way contains more syntax noises and harder to use.
If it is still encouraged to use the old ops ones, then this stabilization should be ignored by most users, and they should do nothing until the edition change for ../..= desugaring, or is it?

EDIT: The release note does not emphasize this at all and only mention the paths in 3 lines. Is it intentional to let most users ignore these new types for now?

@pitaj

pitaj commented Apr 16, 2026

Copy link
Copy Markdown
ContributorAuthor

The .. syntax is intended to switch over to the new types with the next edition. The types have been stabilized early so library authors can add support before the edition comes out. Continue to use the old types for now unless you need/want the copy versions for something.

I intend to emphasize these in the next release (1.96.0) which will include the stabilization of the remaining types.

@tgross35

tgross35 commented Apr 16, 2026

Copy link
Copy Markdown
Member

This was indeed a bit quiet in the release notes because it’s only the first type to stabilize. The next release will have all of std::range stable, and probably a blog post section to go with it.

As far as when to use: I think you likely want to use the new range types in public API (future compatibility) and anytime you just want a Copy-able range that doesn’t already work with existing ranges (a lot of Span and Position type structs are probably going to find it useful). Other than that there likely aren’t too many advantages of switching until the edition, but there’s also no harm in getting ahead of things if you’re up for it.

(Ah, page didn't refresh so I didn’t see Peter responded already!)

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

relnotesMarks issues that should be documented in the release notes of the next release.S-waiting-on-borsStatus: Waiting on bors to run and complete tests. Bors will change the label on completion.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-libsRelevant to the library team, which will review and decide on the PR/issue.T-libs-api[DEPRECATED; DO NOT USE]

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants

@pitaj@rustbot@jackh726@tgross35@scottmcm@sendittothenewts@Amanieu@oxalica@joshtriplett@BurntSushi