Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upimpl<T> IntoIterator for [T; $N] #32871
Conversation
rust-highfive
assigned
brson
Apr 10, 2016
This comment has been minimized.
This comment has been minimized.
|
r? @brson (rust_highfive has picked a reviewer for you, use r? to override) |
This comment has been minimized.
This comment has been minimized.
|
In case it's questioned, I don't know why the Also, I'd love a more direct way than |
brson
added
the
T-libs
label
Apr 11, 2016
This comment has been minimized.
This comment has been minimized.
|
Hmm, I had only run libcoretest, sorry. The CI failure is from rustdoc, in a snippet like this:
Before it got something like Now it gets to my new So, I suppose my addition is a breaking change. There are easy ways around it, in this case either change to |
This comment has been minimized.
This comment has been minimized.
|
Now some iter doctests are failing, all cases of array So... I'll await a decision whether this break is even tenable before I try to fix any more, however trivial. |
This comment has been minimized.
This comment has been minimized.
|
cc @rust-lang/libs and #25725. Being able to move out of fixed sized arrays would definitely be nice. However, the libs team has not been keen on adding functionality to fixed sized arrays via the up-to-32 macro hack we have now, preferring to wait until we have a more structured way to handle all fixed sized arrays. (Also, being a breaking change is unfortunate, although, in its favour, it is likely considered a "minor change" per the API evolution RFC.) |
This comment has been minimized.
This comment has been minimized.
|
Thanks. FWIW, the iterator itself is not in the macro hack here, just the initial |
huonw
reviewed
Apr 11, 2016
| let ndrop = cmp::min(n, len); | ||
| let slice = array.as_mut_slice(); | ||
| for p in &mut slice[self.index..self.index + ndrop] { | ||
| unsafe { ptr::drop_in_place(p); } |
This comment has been minimized.
This comment has been minimized.
huonw
Apr 11, 2016
Member
What happens if one of these destructors panics? self.index probably needs to be updated either before the loop ("leak amplification") or inside the loop.
This comment has been minimized.
This comment has been minimized.
cuviper
Apr 11, 2016
Author
Member
That's a good point! I think I prefer inside the loop, just to leak as little as possible, but I could go either way.
huonw
reviewed
Apr 11, 2016
| #[inline] | ||
| fn next(&mut self) -> Option<T> { | ||
| if self.len() > 0 { | ||
| if let Some(array) = self.array.as_ref() { |
This comment has been minimized.
This comment has been minimized.
huonw
Apr 11, 2016
Member
It seems to me that self.array should never be None here (i.e. it is a bug for it to be None), so maybe unwrap is more appropriate?
This comment has been minimized.
This comment has been minimized.
cuviper
Apr 11, 2016
Author
Member
Right, it should never be None. I suppose unwrap expresses that better, but it will introduce a panic into codegen, whereas this currently would act like just the end of iteration. I don't mind changing this though.
This comment has been minimized.
This comment has been minimized.
|
Yeah, I agree that the The existing specialisation scheme probably isn't quite enough, as I suspect we'd need the lattice version that allows handling overlapping blanket implementations (the impl for |
cuviper
reviewed
Apr 11, 2016
| } | ||
|
|
||
| // Prevent the array as a whole from dropping. | ||
| unsafe { ptr::write(&mut self.array, None); } |
This comment has been minimized.
This comment has been minimized.
cuviper
Apr 11, 2016
Author
Member
This actually has the same hazard you raised for nth -- if there's a panic in one of the drop_in_place calls, we won't get to clobber self.array. And AFAICT a panic in a drop function will still try to drop the struct members, or even locals if I were to take() the array out early.
I think this will need drop-prevention to be an additional wrapper on the array, to be unwound on its own.
This comment has been minimized.
This comment has been minimized.
bluss
Apr 11, 2016
Contributor
Arrayvec has experienced this hazard too, and it uses two drop flags for this reason (nested types).
This comment has been minimized.
This comment has been minimized.
|
I'll raise the one issue I know with Option (and the reason this doesn't use Option). In |
This comment has been minimized.
This comment has been minimized.
|
@bluss interesting - so the concern is that once the 0th element is moved (or dropped in place), then that memory is sort of undefined, and the tag of the |
This comment has been minimized.
This comment has been minimized.
|
I feel less concerned about |
This comment has been minimized.
This comment has been minimized.
|
In arrayvec it was a practical concern, since it used uninitialized or bitwise zeroed elements when empty. Something that uses unsafe_no_drop_flag and sets itself to 0 even though it's "NonZero" would in fact be problematic here when dropped in place. (This is what zeroing drop used to do until it became filling drop). |
This comment has been minimized.
This comment has been minimized.
|
Thanks for the PR @cuviper! The libs team discussed this during triage yesterday and out conclusion was that we don't want to merge this for now. This unfortunately needs to mention the type in the iterator rather than just the As a result this seems like something which would perhaps want to bake on crates.io first, so we decided to close this for now. We also thought that if |
alexcrichton
closed this
Apr 15, 2016
This comment has been minimized.
This comment has been minimized.
|
That's a good point that the type signature would want to change between this and the ideal integer generics! So I understand holding off for now. I do have safety fixes for the issues raised so far, which I'll go push to my branch later just to have available. When integer generics finally come around, hopefully we can get back on this quickly. :) I'll see about publishing something in a crate too. Is your |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
I see, thanks! |
This comment has been minimized.
This comment has been minimized.
|
Ah yeah sorry, the jargon is pretty cryptic :( |
cuviper
added a commit
to cuviper/generic-array
that referenced
this pull request
May 25, 2016
kennytm
referenced this pull request
Aug 10, 2017
Open
IntoIterator should be implemented for [T; N] not just references #25725
cuviper
referenced this pull request
Aug 17, 2017
Closed
Implement `std::iter::Iterator` for arrays? #43946
This comment has been minimized.
This comment has been minimized.
|
FWIW, I have rebased and updated my branch (comparison), and it should be simple to change it to |
cuviper
unassigned
brson
Sep 16, 2017
This comment has been minimized.
This comment has been minimized.
|
@cuviper: Nice. But wow, those .into_iter() usages in the examples are worrying. |
This comment has been minimized.
This comment has been minimized.
|
I'm tempted to go ahead and submit those |
cuviper
referenced this pull request
Nov 20, 2017
Open
impl `IntoParallelIterator` for fixed sized arrays #478
This comment has been minimized.
This comment has been minimized.
With RFC 2000 on the horizon, do you think we could try this again? We would still have to start with the less-satisfactory
I want to put this together now, at least. |
bors
added a commit
that referenced
this pull request
Mar 14, 2018
cuviper
referenced this pull request
Mar 15, 2018
Merged
Small fixes and improvements before next release #61
This comment has been minimized.
This comment has been minimized.
@alexcrichton Re-reading this again, I wonder why do you think this is a problem? When const generics arrive, the |
This comment has been minimized.
This comment has been minimized.
|
@RReverser we didn't want to commit to that type definition at the time. The type definition will want to change with const generics, and it didn't seem pressing enough to take the future ergonomic hit at the time. Times change though! (also this PR is over 2 years old, naturally it's pretty far out of cache) |
This comment has been minimized.
This comment has been minimized.
|
My newer PR was #49000, where I still wasn't able to update the type definition to const generics, but my hope was that we could just leave that part unstable for the time being. We could have usable array iterators, just not be able to name the iterator type in stable code. We're now blocked on having a good migration story to fix conflicting "legacy" use of |
cuviper commentedApr 10, 2016
This allows an array to move its values out through iteration. I find
this especially handy for
flat_map, to expand one item into severalwithout having to allocate a
Vec, like one of the new tests:Note the array must be moved for the iterator to own it, so you probably
don't want this for large
Tor very many items. But for small arrays,it should be faster than bothering with a vector and the heap.