-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
RFC: movable array iterators #2185
RFC: movable array iterators #2185
Conversation
I very much want this, but what is return type of Or maybe
I believe that in a method taking |
Please prefer line comments so I can respond without copying :)
I think there's a need to be able to drop each elements individually (in other words, only in the range that is not moved out). So we need ManuallyDrop on each element, and trasmuting should be the easiest so far. |
You can call |
Good. I will update the text later. |
```rust | ||
[1, 2].into_iter(); | ||
// This was originally yielding references, but now values. | ||
``` |
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.
This is pretty much ensured to break actual code for many users, both in crater (that we can test, find and maybe fix), and lots of code we can't find or test. Maybe we can begin warning for this long before the new iterator is implemented?
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.
Personally speaking, I don't think people would use into_iter
despite the fact it yields references, and they would just iter
instead. Thus I think fixing after a crater should be sufficient.
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.
We don't reach all rust code in the world with crater. If the break is wide spread, we have to be more careful.
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.
And what about for &x in [1,2,3]
, isn't that just into_iter
?
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.
That does not compile today I think so it's not a backwards compat concern.
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.
Oh I see. [1].into_iter()
currently resolves to the impl for &[_; _]
which the new [_; _]
impl would override, right?
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.
Yes!
This could be done without stabilising impl<T> Iterator for IntoIter<[T; 1]> { ... }
impl<T> Iterator for IntoIter<[T; 2]> { ... }
impl<T> Iterator for IntoIter<[T; 3]> { ... }
// ...
impl<T> Iterator for IntoIter<[T; 32]> { ... } with all the impls calling to some shared unsafe method to avoid duplication. Has a nice migration story for when const generics land, just replacing with impl<T, const N> Iterator for IntoIter<[T; N]> {} |
Please take a look, I think I have addressed the concerns. |
This looks great to me, thanks for writing it up! |
struct IntoIter<T> { ... }
impl<T> Drop for IntoIter<[T; 0]> { ... }
impl<T> Drop for IntoIter<[T; 1]> { ... } // error: Implementations of Drop cannot be specialized
...
// I expect this will work
struct IntoIter<T, const N: usize> { ... }
impl<T, const N: usize> Drop for IntoIter<T, N>
// This works today
struct IntoIter<T, A> where A: FixedSizeArray<T> { ... }
impl<T, A> Drop for IntoIter<T, A> where A: FixedSizeArray<T> { ... } EDIT: typo |
@sinkuu What do you mean by |
Presumably Unsize. |
Should we make multiple IntoIter structs until const generic lands? Like this: I think this should resolve the specialization problem, alongside reducing the template complexity, so we can store pointers (or unsafe slices) inside the struct. |
I want this feature, but I don’t think I want to stabilize such an API. It’d be harder to generalize once const generics land, too.
I don’t understand what you mean here. The point of |
I'm afraid that even
We need to save the range we have consumed with the iterator. It can be either usize-indexed or just start-end pointer. |
Changing the signature of stable APIs is not acceptable, so I’m afraid that this implies we should not stabilize anything here without const generics. Self-referential pointers would become invalid when the iterator is moved. It has to be indices. (Two of them, or a |
I've come up with a partial stabilization plan, please let me know if this is possible. As the signature of the iterator struct is subject to change, we will be keeping that struct(s) unstable until const generics land. I will call this struct
impl<T> IntoIterator for [T; 32] {
type Item = T;
type IntoIter = UnstableIntoIter32<T>;
fn into_iter(self) -> T { ... }
} I have no idea if this implementation will be accepted as stable in the compiler, so we can use it without the ability to annotate the type. |
Instead of a specific |
Would it be compatible to replace struct IntoIter0<T>{ .. };
..
struct IntoIter32<T>{ .. }; with type IntoIter0<T> = IntoIter<T, const 0>;
..
type IntoIter32<T> = IntoIter<T, const 32>; once const generics land? Then the eventual type would be the nice one, and the residual cruft is just a bunch of deprecated type aliases, which should be easy to maintain and ignore in the docs. |
We can do one thing before we even start the implementation: Work on deprecating & future warning the existing |
I experimented with an implementation of deprecation warning, but it seems that I can't avoid one particular false positive: https://play.rust-lang.org/?gist=8b69b43bc947bf112c0f20d0e58b3add&version=stable Basically, the differences between the below cannot be detected without changing the signature:
|
We discussed this at the @rust-lang/libs meeting today, and feel like this won't really be actionable until integer generics are implemented. @rfcbot fcp postpone |
Team member @sfackler has proposed to postpone this. The next step is review by the rest of the tagged teams: No concerns currently listed. Once these reviewers reach consensus, this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
@sfackler What do you think about starting to warn / soft deprecate |
I have mentioned that if we don't stabilize the iterator types, we can implement it with macro generated iterators and partially stabilize the into_iter() function only. |
Not sure - we haven't really done anything like that before. @aturon thoughts? I am personally not a fan of the current "up to size 32" approach, and don't really want to expand that further. |
@sfackler - what we only can do currently is that "up to size 32" approach; it should not be a blocker to improve array usability. I originally thought that the main concern is backwards compatibility, which needs a lint to be developed. As I emphasized above, const generics is not a blocker for this, just a wishlist item. As const generics is an approved RFC, we can expect the stabilization at the same time. |
@bluss I'd be in favor. |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
3 similar comments
🔔 This is now entering its final comment period, as per the review above. 🔔 |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
The final comment period is now complete. |
Closing since FCP with the proposal to postpone is now complete. |
Rendered