Will `impl IntoIterator for [T; N]` be a semver break?


#1

It was one of the things that makes me surprised when I learn Rust. Why can’t I write for v in [a, b, c] { .. }? I think this is due to the lack of const generics, but I can’t be sure. If anyone knows the historical context about it, please let me know :wink:

Anyway, we’re expecting that const generics will be land to stable soon™. With this feature It’s trivial to write impl IntoIterator for [T; N] in libcore. But, is it semver compatible? Or we don’t have any hope for it and should use for v in ArrayVec::new([a, b, c]) forever?


#2

Adding trait implementations to types is semver-compatible.


#3

This is an inference and trait resolution change, which is explicitly not considered to be a breaking change in Rust’s promise.

I’m sure this will cause some churn when we get it, but my_array.into_iter() is longer than .iter(), so we can start pushing people to be future-compatible ASAP. And the trait is too important to not add.


#4

Simply adding the impl causes widespread breakage, to the extent that we don’t just want to YOLO add it. There’s some work on figuring out a transition story here: https://github.com/rust-lang/rust/pull/49000


#5

Ok so the breakage is coming from into_iter being available on slices and arrays unsizing to slices.


#6

It comes from “autoderef / autoref” on methods :

fn main ()
{
    let a = [0_i32];
    let mut iterator = a.into_iter();
    /* // unsugars to:
    let mut iterator = IntoIterator::into_iter(&a); // &[i32] : IntoIterator<Item = &i32>
    // since `IntoIterator::into_iter(a)` is not valid, which "triggers an autoref" */
    let _: Option<&i32> = iterator.next();
}

So, if [T] were to impl IntoIterator, then IntoIterator::into_iter(a) would be valid, “autoref would not trigger” and the above code would fail to compile.