Skip to content

Add IntoIterator impl for arrays by value (for [T; N]) - #65819

Closed
LukasKalbertodt wants to merge 4 commits into
rust-lang:masterfrom
LukasKalbertodt:add-into-iterator-for-arrays
Closed

Add IntoIterator impl for arrays by value (for [T; N])#65819
LukasKalbertodt wants to merge 4 commits into
rust-lang:masterfrom
LukasKalbertodt:add-into-iterator-for-arrays

Conversation

@LukasKalbertodt

@LukasKalbertodt LukasKalbertodt commented Oct 25, 2019

Copy link
Copy Markdown
Contributor

Current status (2020-12-30):
Const generics are stable now, so this PR is unblocked. The main remaining question is how to deal with the regressions caused by this change (see this comment). In the meantime, you can use IntoIterator::new which has been stabilized independently.

Status update comments:



Closes #25725

Initially part of #62959, this PR adds this impl:

impl<T, const N: usize> IntoIterator for [T; N]

TODO


The backwards compatibility problem

Adding this impl is not as straight-forward as it seems: there are some backwards compatibility hazards. In particular, due to autoref, this compiles today:

let array = [true; 3];
for x in array.into_iter() {
    let _ = *x; // x is a reference
}

With this change, that code wouldn't compile anymore, as x inside the loop would have the type bool and not &bool (like it does today). One should note that this only happens when using the .method call syntax with .into_iter(). It does not affect .iter() (different method) and it does not affect the for-loop syntax (does not involve autoref).

There has been some discussion in #49000 and in #62959. Most agree that a crater run would be very useful. That's what this PR is for. But the fact that this change didn't break anything in the compiler is already promising. (it did)

Arguments to add this impl despite the potential breakage:

  • It doesn't really make sense to call .into_iter(), as .iter() is shorter and the for loop desugars to into_iter() anyway. So hopefully no one used this in the real world. (people did use that in the real world)
  • RFC 1105 clearly specifies that "implementing any non-fundamental trait" is a "minor change". It also acknowledges that "implementing any existing trait can cause breakage", "However, as before, this kind of breakage is considered 'minor'".
  • @scottmcm wrote a comment that I (and apparently many others) completely agree with:

    My personal opinion: having this impl is so obviously the correct thing that I'd be willing to bend stability guarantees to have it, but we don't even need to because adding a new trait impl is an allowed change, no matter whether it breaks code. And the only code that it breaks, today, is code that was doing a.into_iter() when a.iter() would have done exactly the same thing for less typing, so any workaround needed to not trigger this change will make the code strictly better regardless.


CC @Centril @Mark-Simulacrum @cuviper

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

Labels

F-const_generics `#![feature(const_generics)]` needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs-api [DEPRECATED; DO NOT USE]

Projects

None yet

Development

Successfully merging this pull request may close these issues.

IntoIterator should be implemented for [T; N] not just references