Is it a bug that stop recognize &[i32;3] as &[i32]?

When I tried to construct an iter with

    std::iter::once(&[1001, nums[0], nums[1]])
        .chain(std::iter::once(&[nums[nums.len() - 2], nums[nums.len() - 1], 1001]))

rustc tells me,

Line 4, Char 10: type mismatch resolving `<Windows<'_, i32> as IntoIterator>::Item == &[i32; 3]` (
4   |         .chain(
    |          ^^^^^ expected array `[i32; 3]`, found slice `[i32]`
    = note: expected reference `&[i32; 3]`
               found reference `&[i32]`
note: required by a bound in `std::iter::Iterator::chain`
Line 5, Char 10: the method `chain` exists for struct `std::iter::Chain<std::iter::Once<&[i32; 3]>, Windows<'_, i32>>`, but its trait bounds were not satisfied (
5    |           .chain(std::iter::once(&[nums[nums.len() - 2], nums[nums.len() - 1], 1001]))
     |            ^^^^^ method cannot be called on `std::iter::Chain<std::iter::Once<&[i32; 3]>, Windows<'_, i32>>` due to unsatisfied trait bounds
     = note: the following trait bounds were not satisfied:
             `<Windows<'_, i32> as Iterator>::Item = &[i32; 3]`
             which is required by `std::iter::Chain<std::iter::Once<&[i32; 3]>, Windows<'_, i32>>: Iterator`
             `std::iter::Chain<std::iter::Once<&[i32; 3]>, Windows<'_, i32>>: Iterator`
             which is required by `&mut std::iter::Chain<std::iter::Once<&[i32; 3]>, Windows<'_, i32>>: Iterator`
Some errors have detailed explanations: E0271, E0599.
For more information about an error, try `rustc --explain E0271`.
error: could not compile `prog` due to 2 previous errors

I believed that, it is due to the incompleteness of rust's type inference system.

Thus I put .as_slice to the first element,

    std::iter::once([1001, nums[0], nums[1]].as_slice())
        .chain(std::iter::once(&[nums[nums.len() - 2], nums[nums.len() - 1], 1001]))

but there is still an error:

Line 5, Char 10: type mismatch resolving `<std::iter::Once<&[i32; 3]> as IntoIterator>::Item == &[i32]` (
5   |         .chain(std::iter::once(&[nums[nums.len() - 2], nums[nums.len() - 1], 1001]));
    |          ^^^^^ expected slice `[i32]`, found array `[i32; 3]`
    = note: expected reference `&[i32]`
               found reference `&[i32; 3]`
note: required by a bound in `std::iter::Iterator::chain`
For more information about this error, try `rustc --explain E0271`.
error: could not compile `prog` due to previous error

I know that, put as_slice to both line could make the program compiles, but why rust could not corece this array to slice here?

Well, the conversion to &[i32] has to happen before you pass it as an argument to once, but the compiler will only coerce it there if &[i32] is the only type that once accepts. Since once can accept an &[i32; 3] too, it will not be coerced automatically in that position, even if that choice leads to trouble later.


Because type inference and coercion are mortal enemies.

The eventual answer to your problem will be, since you would rather get arrays than slices anyway,

-        .chain(
+        .chain(nums.array_windows())

but for now you'll just need

-    std::iter::once(&[1001, nums[0], nums[1]])
+    std::iter::once(&[1001, nums[0], nums[1]][..])



This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.