-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add by-value iterator for arrays #62959
Conversation
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall this looks nice. Here's some food for thought however:
- I think some tests should also be added that exercise each
impl
you'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
N
andself.pos
is a good idea. - Tests that also
format!(...)
the iterator to exerciseDebug
would 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
IntoIterator
impl for arrays. TheIntoIterator
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):TODO:
Notes for reviewers
MaybeUninit
correct here? I think it has to be used due to theClone
impl which has to fill the dead array elements with something, but cannot fill it with a correct instance.CC #25725