Iterator and differences between array and &array

Hi,

I was wondering why this simple little code doesn't compile and generare a lot of errors:

fn main() {
    let array = [1, 2, 3];
    for a in array {
        println!( "{}", a);
    }
}

While just changing array with &array (in the for loop) it works without any problem.
Is it something related how the deference operator works with &array?

Thanks.

P.S.:
These are the errors generated by the little example code:

array.rs:4:5: 6:6 error: the trait `core::iter::Iterator` is not implemented for the type `[_; 3]` [E0277]
array.rs:4     for a in array {
array.rs:5         println!("{}", a);
array.rs:6     }
note: in expansion of for loop expansion
array.rs:4:5: 6:6 note: expansion site
array.rs:4:5: 6:6 note: `[_; 3]` is not an iterator; maybe try calling `.iter()` or a similar method
array.rs:4     for a in array {
array.rs:5         println!("{}", a);
array.rs:6     }
note: in expansion of for loop expansion
array.rs:4:5: 6:6 note: expansion site
array.rs:4:5: 6:6 error: the trait `core::iter::Iterator` is not implemented for the type `[_; 3]` [E0277]
array.rs:4     for a in array {
array.rs:5         println!("{}", a);
array.rs:6     }
note: in expansion of for loop expansion
array.rs:4:5: 6:6 note: expansion site
array.rs:4:5: 6:6 note: `[_; 3]` is not an iterator; maybe try calling `.iter()` or a similar method
array.rs:4     for a in array {
array.rs:5         println!("{}", a);
array.rs:6     }
note: in expansion of for loop expansion
array.rs:4:5: 6:6 note: expansion site
array.rs:4:5: 6:6 error: the trait `core::iter::Iterator` is not implemented for the type `[_; 3]` [E0277]
array.rs:4     for a in array {
array.rs:5         println!("{}", a);
array.rs:6     }
note: in expansion of for loop expansion
array.rs:4:5: 6:6 note: expansion site
array.rs:4:5: 6:6 note: `[_; 3]` is not an iterator; maybe try calling `.iter()` or a similar method
array.rs:4     for a in array {
array.rs:5         println!("{}", a);
array.rs:6     }
note: in expansion of for loop expansion
array.rs:4:5: 6:6 note: expansion site
error: aborting due to 3 previous errors

The for loop is desugared to an invocation of IntoIterator::into_iter() on the given expression. If the type doesn't implement IntoIterator (like the owned array types), you can't loop over it. The slice type &[T] does implement IntoIterator.

The error message is a bit confusing because there is a blanket implementation for IntoIterator for all types that already are Iterator (iterating over any iterator should always work without you having to implement into_iter). That's why the message says "Iterator is not implemented for..."

1 Like

I don't know why it reported 3 times the same thing, but one would be enough, perhaps it is a problem in the error handler for this type of error?

It is not that is a long report, it is that is printed 3 times.

<anon>:3:5: 5:6 error: the trait `core::iter::Iterator` is not implemented for the type `[_; 3]` [E0277]
<anon>:3     for a in array/*.iter()*/ {
<anon>:4         println!( "{}", a);
<anon>:5     }
note: in expansion of for loop expansion

Also see that it try to help with suggesting to use iter().

<anon>:3:5: 5:6 note: `[_; 3]` is not an iterator; maybe try calling `.iter()` or a similar method

That's a good point :slight_smile: You might want to search for a bug on Rust's tracker, and open one if you don't find it.

Which should also work, yes.

it is because rust/object_safety.rs at 7ae4a8e9f3150f62964151ef54b3da3cd24ee123 · rust-lang/rust · GitHub there is a report on a similar one like this "note: the trait cannot require ..." printed twice for object-safety violations · Issue #20692 · rust-lang/rust · GitHub

Ah... Ok, since I'm using & the type is not [T] anymore, but &[T] and slice implements IntoIterator::into_iter().
Now it makes more sense. Thank you.

P.S.:
The duplication of errors is quite annoying. I noticed that you've just opened an issue
Good!

Yes, but I think it needs more "attention" I mean, I see that map is used for collect errors without really check if the reported errors are the same or not (semantically?) so that is why there should probably more than this 2 cases already spotted.