Skip to content

implement const Iterator for Range - #156216

Open
Randl wants to merge 5 commits into
rust-lang:mainfrom
Randl:const-for-impl
Open

implement const Iterator for Range#156216
Randl wants to merge 5 commits into
rust-lang:mainfrom
Randl:const-for-impl

Conversation

@Randl

@Randl Randl commented May 6, 2026

Copy link
Copy Markdown
Contributor

View all comments

This allows the use of for i in i..n in const.

This I believe is interesting enough to be justified under #155816

r? @oli-obk

@rustbot rustbot 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 May 6, 2026
@Randl

Randl commented May 6, 2026

Copy link
Copy Markdown
Contributor Author

Another issue I noticed is that while is const-stable, but for isn't. So in some places, reverting the const-hack would make currently const-stable functions const-unstable. Alternatively, we wait until Iterator is const-stable.

@rust-log-analyzer

This comment has been minimized.

@Randl
Randl force-pushed the const-for-impl branch from d4ee14e to 6115579 Compare May 6, 2026 02:08
@theemathas

Copy link
Copy Markdown
Contributor

Does this run into #148200 for types that implement non-const TrustedStep but implements const Step?

@rust-log-analyzer

This comment has been minimized.

@Randl
Randl force-pushed the const-for-impl branch from 6115579 to 58f0c19 Compare May 6, 2026 04:23
@Randl

Randl commented May 6, 2026

Copy link
Copy Markdown
Contributor Author

@theemathas
Can you give maybe an example you had in mind? I'm not sure I can think of one. If I understand correctly, there won't be any non-const functions involved in this case, since the entire implementation will be in the const Step?

@theemathas

Copy link
Copy Markdown
Contributor

Maybe there's actually not a problem with specialization here? I suppose it's kind of fine to call a function that requires const TrustedStep even though the type only actually implements TrustedStep + const Step, since TrustedStep itself doesn't have any methods.

Comment thread library/core/src/tuple.rs Outdated
@Randl
Randl force-pushed the const-for-impl branch from 58f0c19 to ccbb26c Compare May 6, 2026 08:18
Comment thread library/core/src/iter/range.rs Outdated
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Step> DoubleEndedIterator for ops::Range<A> {
#[rustc_const_unstable(feature = "const_iter", issue = "92476")]
impl<A: [const] Step + [const] Destruct> const DoubleEndedIterator for ops::Range<A> {

@oli-obk oli-obk May 6, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this change needed for the MVP? should at least be a separate commit unless the rest of this commit requires it

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It is, in fact, required since last() is implemented using next_back(), so it needs to be constified too.

@fee1-dead

Copy link
Copy Markdown
Member

I feel iffy on introducing additional const impls that use specialization without us fixing specialization first

@oli-obk

oli-obk commented May 13, 2026

Copy link
Copy Markdown
Contributor

@rustbot blocked #156454

@rustbot rustbot added S-blocked Status: Blocked on something else such as an RFC or other implementation work. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 13, 2026
@Filiprogrammer

Filiprogrammer commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

This no longer builds since bc2112e.

error: expected a trait, found type
   --> /rustc/1df360b6a885af638e597c167cbb537b3b2137cd/library/core/src/iter/range.rs:819:42
    |
819 | impl<A: [const] Step + [const] Destruct> const RangeIteratorImpl for ops::Range<A> {
    |                                          ^^^^^^^^^^^^^^^^^^^^^^^

error: expected a trait, found type
   --> /rustc/1df360b6a885af638e597c167cbb537b3b2137cd/library/core/src/iter/traits/iterator.rs:321:44
    |
321 |         impl<I: [const] Iterator + ?Sized> const SpecAdvanceBy for I
    |                                            ^^^^^^^^^^^^^^^^^^^

Probably related to a88521a.

Comment thread library/core/src/iter/range.rs Outdated
@rustbot

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@Randl

Randl commented Jun 20, 2026

Copy link
Copy Markdown
Contributor Author

Looks like genuine ICE for me, I may take a look at it tomorrow

@rustbot

This comment has been minimized.

@rust-bors

This comment has been minimized.

@Randl

Randl commented Aug 17, 2026

Copy link
Copy Markdown
Contributor Author

I'll rebase once I get to PC, but it is still blocked on const min specialization resolution (see discussion at https://rust-lang.zulipchat.com/#narrow/channel/326866-t-types.2Fnominated/topic/.23148200.3A.20min_specialization.20with.20const.20traits.20can.20call.20non-.E2.80.A6/with/614859233 )

I do think (and had a feeling that others agree) that this feature, i.e. allowing for in const, as well as constification of the Iterator trait, are well within constification policy and we probably want to play with both before stabilizing const traits

@clarfonthey

Copy link
Copy Markdown
Contributor

To be clear, I mostly said what I did because I hadn't fully read the PR and didn't want to make any guarantees. Taking a second look, nothing looks particularly egregious, although will probably want a second opinion from wg-const-traits on what some of these tests were intended to do since it looks like they were relying on iterator for ranges not being implemented.

@rustbot

This comment has been minimized.

@Randl

Randl commented Aug 22, 2026

Copy link
Copy Markdown
Contributor Author

@rustbot ready

Rebased on master.
I checked the tests; I think the remaining ones should pass.
Still blocked on #156454 / whatever resolution of #148200 is

@rustbot rustbot 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 Aug 22, 2026
@rustbot

This comment has been minimized.

@Randl

Randl commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

If we're okay with specializing on const (and not maybe-const), I think we can merge this.
Note that we can't just make TrustedLen non-const because that would lead to conflicting implementations of RangeIteratorImpl.
cc @clarfonthey @fee1-dead

@JohnTitor

Copy link
Copy Markdown
Member

r? libs

@rustbot rustbot assigned clarfonthey and unassigned JohnTitor Sep 2, 2026
@clarfonthey

Copy link
Copy Markdown
Contributor

Returning from RustConf and finally looking at this: I think that the constification of the various methods on Iterator and DoubleEndedIterator should be done via a separate PR, although nothing in particular bothers me about that implementation.

(Feel free to r? clarfonthey on that PR.)

In terms of the rest, I'm a bit worried about the UI tests being affected, since I don't think the newer versions of the tests are testing what we want to test. The codegen test, however, looks fine, since it's an expected equivalence created by switching to a for loop.

I'm going to mark this as blocked until a separate PR for the iterator changes, but like I said, would be happy to review that separately if you submit it, and you can specify me for review. It's mostly just so that we can separate these out for loads of reasons, including potential perf checks + to get a bit more scrutiny on what exactly is being affected by that versus the range changes.

@rustbot blocked

@rustbot rustbot added S-blocked Status: Blocked on something else such as an RFC or other implementation work. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 13, 2026
let mut x = 0;

for i in 0..4 {
//~^ ERROR: cannot use `for`

@Randl Randl Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This seems to clearly test loops in const context

View changes since the review


const _: () = {
for _ in 0..5 {}
//~^ ERROR cannot use `for`

@Randl Randl Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

this also appears to test specifically for for in const, though it duplicates

View changes since the review

@Randl

Randl commented Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

I've opened #162734 for Iterator and DoubleEndedIterator methods.
As for tests, two are now passing. Both seem to test specifically the ability to use for in const. Some additional tests now have extra error messages related to feature gates for parts of the code that are potentially working on nightly now but still testing the intended behavior, as far as I understand.

jhpratt added a commit to jhpratt/rust that referenced this pull request Sep 14, 2026
Constify more Iterator and DoubleEndedIterator functions required for Range

Extracted from rust-lang#156216
Consitfies functions required for `const impl Iterator for Range`.
r? clarfonthey
rust-bors Bot pushed a commit that referenced this pull request Sep 14, 2026
Rollup merge of #162734 - Randl:const-for-prereq, r=clarfonthey

Constify more Iterator and DoubleEndedIterator functions required for Range

Extracted from #156216
Consitfies functions required for `const impl Iterator for Range`.
r? clarfonthey
@rust-bors

This comment has been minimized.

@rustbot

rustbot commented Sep 14, 2026

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.

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

Labels

S-blocked Status: Blocked on something else such as an RFC or other implementation work. 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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants