Implementing IntoIterator for [T; $N]?


#1

Sometimes, to simplify repetitive code without introducing a function (which is kinda verbose), I’d like to do something like:

for (a, b) in vec![
    (foo, 4),
    (bar, 0),
    (baz, 7),
] {
    // ...
}

… where the loop takes ownership of the values. However, the heap allocation in vec! here seems wasteful: the number of items is known at compile time, so it should be possible to allocate them on the stack.

The IntoIterator trait is already implemented for &'a [T, $N] for $N up to 32, yielding &'a T. Could it also be possible to implement it for [T, $N], taking ownership and yielding T? Getting the destructor right (in case the iterator was not consumed to its end) seems tricky, but I don’t see a reason it would be impossible.


#2

As far as I know, it is only possible to implement a correct destructor with the zeroing we currently have (but do not wish to rely on) or a type like ManuallyDrop proposed in RFC 197.


#3

Is the magic in std::vec::IntoIter’s destructor not applicable?


#4

It would be applicable if you could follow it up with forgetting the whole original [T; N] value, but you can’t (?). You can’t inhibit the destructors of the array elements other than by the deprecated zeroing.

Is it possible to solve this by nesting the array inside a struct, other than nesting it inside Option?

Edit: Here is (playpen) such a fixed size iterator, but it’s probably quite inefficient. It can be improved by enforcing the invariant of never being None outside of the destructor, and some wild assume magic. => this is essentially a drop flag.