13

Consider this snippet:

fn main() {
    let arr_of_arr = [[1, 2], [3, 4]];
    let res = arr_of_arr
        .iter()
        .flat_map(|arr| arr.iter())
        .collect::<Vec<i32>>();
}

The compiler error is:

error[E0277]: the trait bound `std::vec::Vec<i32>: std::iter::FromIterator<&{integer}>` is not satisfied
 --> src/main.rs:6:10
  |
6 |         .collect::<Vec<i32>>();
  |          ^^^^^^^ a collection of type `std::vec::Vec<i32>` cannot be built from an iterator over elements of type `&{integer}`
  |
  = help: the trait `std::iter::FromIterator<&{integer}>` is not implemented for `std::vec::Vec<i32>`

Why does this snippet not compile?

In particular, I'm not able to understand the error messages: what type represents &{integer}?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
attdona
  • 17,196
  • 7
  • 49
  • 60
  • 1
    Related: [When are numeric literals assigned to default types?](https://stackoverflow.com/questions/39595782/when-are-numeric-literals-assigned-to-default-types). – ljedrz Apr 09 '18 at 08:55
  • [What is the {integer} in a compiler error message?](https://stackoverflow.com/q/41996784/155423) – Shepmaster Apr 09 '18 at 17:35

1 Answers1

14

{integer} is a placeholder the compiler uses when it knows something has an integer type, but not which integer type.

The problem is that you're trying to collect a sequence of "references to integer" into a sequence of "integer". Either change to Vec<&i32>, or dereference the elements in the iterator.

fn main() {
    let arr_of_arr = [[1, 2], [3, 4]];
    let res = arr_of_arr.iter()
        .flat_map(|arr| arr.iter())
        .cloned() // or `.map(|e| *e)` since `i32` are copyable
        .collect::<Vec<i32>>();
}
DK.
  • 55,277
  • 5
  • 189
  • 162
  • 1
    Can anyone explain why `|arr| arr.into_iter()` (instead of `.clone()`) doesn't work? I thought `into_iter` yields owned values rather than references, but that seems not to be the case? – joe Sep 05 '19 at 03:48
  • 2
    Prior to Rust 1.53, `inter_iter()` on arrays was implemented as a slicer iterator (like `iter()`); so, it _doesn't_ yield owned values. That behavior is still in the 2015/2018 editions. I can't tell you how many hours I spent trying to wrap my head around wtf was going on with a certain bug, just to realize I needed to read the docs on arrays. https://doc.rust-lang.org/std/primitive.array.html#editions – aaron Aug 18 '21 at 23:29