Add by-value iterator for arrays #62959
Conversation
This comment has been minimized.
This comment has been minimized.
Centril
left a comment
There was a problem hiding this comment.
Overall this looks nice. Here's some food for thought however:
- I think some tests should also be added that exercise each
implyou've provided here. - In particular, there should be tests collecting into a
Vec<...>and then checking the contents. - It would be good to have tests that drop some elements on the floor in some positions (
let _ = iter.next();) - Checking the boundary conditions around
Nandself.posis a good idea. - Tests that also
format!(...)the iterator to exerciseDebugwould be good.
(Some of these checks can be done in the same tests).
Also cc @scottmcm
|
r? @scottmcm |
|
This is unfortunately not backwards compatible. Arrays deref to slices and calling .into_iter currently returns &T but would begin returning T. cc @cuviper who has done investigation into this in the past - we should probably update the relevant issue. |
This comment has been minimized.
This comment has been minimized.
|
@Centril Thanks a lot for the fairly in-depth review already! I will fix all of that once the bigger questions are resolved. @Mark-Simulacrum I wasn't aware this is a problem. Sigh, that's unfortunate indeed. (I am a bit surprised about quickly closing the PR without a discussion though...) From #49000 it seems like there has been a fair amount of discussion already. To sidestep the |
|
I also wonder if there has already been a crater run and what the fallout was? Maybe @cuviper knows. Ostensibly some minor breakage could (it's a choice!) be justified as "inference breakage" and this is a rather large paper cut in the language which would be good to finally solve. (I'm also thinking of #59500 which technically was not "allowed" due to
In my view a solid interim plan! Reopening so that we may consider that. |
cuviper
left a comment
There was a problem hiding this comment.
Please compare with #49000 for feature parity of what I did before. Most of it should be similar, apart from having real const generics now. I had as_slice() and as_mut_slice(), Clone, DoubleEndedIterator, ExactSizedIterator, FusedIterator, and TrustedLen. You could take my added tests too.
I don't think we did a direct crater run with the new |
|
@cuviper In that case this is as good a time as any to try out a crater run then. |
|
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 |
This comment has been minimized.
This comment has been minimized.
Is that true? I think it also breaks code that does We could probably have a clippy/rustc lint to start moving people away from that, though. |
|
|
|
@Mark-Simulacrum ah, good point. That's great then! The part about the lint still stands. |
(Relevant lowering code: rust/src/librustc/hir/lowering.rs Lines 4887 to 4894 in eedf6ce |
|
The clippy lint exists, although I don't think it was default-deny when we tried the crater run before. https://rust-lang.github.io/rust-clippy/master/index.html#into_iter_on_array |
This comment has been minimized.
This comment has been minimized.
ac96d77 to
cad2150
Compare
The iterator is implemented using const generics. It implements the traits `Iterator`, `DoubleEndedIterator`, `ExactSizeIterator`, `FusedIterator` and `TrustedLen`. It also contains a public method `new` to create it from an array. `IntoIterator` was not implemented for arrays yet, as there are still some open questions regarding backwards compatibility. This commit only adds the iterator impl and does not yet offer a convenient way to obtain that iterator.
Many tests are based on tests by Josh Stone <cuviper@gmail.com>
This it to make sure traits are implemented for arrays with length 32 and below, while they are not implemented for >= 33.
0fe38bd to
c36b9dd
Compare
This comment has been minimized.
This comment has been minimized.
|
Huzzah! Kudos to everyone working on const generics for getting this to work ❤️ @bors r+ |
|
📌 Commit c36b9dd has been approved by |
…=scottmcm
Add by-value iterator for arrays
This adds an iterator that can iterate over arrays by value, yielding all elements by value. However, **this PR does _not_ add a corresponding `IntoIterator` impl for arrays**. The `IntoIterator` impl needs some discussion about backwards-compatibility that should take place in a separate PR. With this patch, this code should work (but there is currently still a bug):
```rust
#![feature(array_value_iter)]
use std::array::IntoIter;
let arr = [1, 2, 3];
for x in IntoIter::new(arr) {
println!("{}", x);
}
```
**TODO**:
- [x] Get initial feedback
- [x] Add tests
- [x] Figure out why stage1 produces weird bugs ([comment](rust-lang#62959 (comment)))
- [x] Add UI tests as mentioned [here](rust-lang#62959 (comment)) (will do that soon-ish)
- [x] Fix [this new bug](rust-lang#62959 (comment))
**Notes for reviewers**
- Is the use of `MaybeUninit` correct here? I think it has to be used due to the `Clone` impl which has to fill the dead array elements with something, but cannot fill it with a correct instance.
- Are the unit tests sufficient?
CC rust-lang#25725
Rollup of 9 pull requests Successful merges: - #62959 (Add by-value iterator for arrays ) - #65390 (Add long error explanation for E0576) - #65408 (reorder config.toml.example options and add one missing option) - #65414 (ignore uninhabited non-exhaustive variant fields) - #65666 (Deprecated proc_macro doesn't trigger warning on build library) - #65742 (Pre-expansion gate most of the things) - #65747 (Adjust the tracking issue for `untagged_unions`.) - #65763 (Changed APIT with explicit generic args span to specific arg spans) - #65775 (Fix more `ReEmpty` ICEs) Failed merges: - #65519 (trait-based structural match implementation) r? @ghost
…er-tracking-issue, r=Centril Fill tracking issue number for `array_value_iter` Thanks for [noticing](rust-lang#62959 (comment))! r? @Centril
…er-tracking-issue, r=Centril Fill tracking issue number for `array_value_iter` Thanks for [noticing](rust-lang#62959 (comment))! r? @Centril
…er-tracking-issue, r=Centril Fill tracking issue number for `array_value_iter` Thanks for [noticing](rust-lang#62959 (comment))! r? @Centril
…er-tracking-issue, r=Centril Fill tracking issue number for `array_value_iter` Thanks for [noticing](rust-lang#62959 (comment))! r? @Centril
This adds an iterator that can iterate over arrays by value, yielding all elements by value. However, this PR does not add a corresponding
IntoIteratorimpl for arrays. TheIntoIteratorimpl needs some discussion about backwards-compatibility that should take place in a separate PR. With this patch, this code should work (but there is currently still a bug):TODO:
Notes for reviewers
MaybeUninitcorrect here? I think it has to be used due to theCloneimpl which has to fill the dead array elements with something, but cannot fill it with a correct instance.CC #25725