Chaining iterators: can't make types match [E0271, related to iter::map]

Background

Given a vector of objects, I want to consider each item in the iterator together with its two precursors and successors in the vector.
Not every item has two precursors or successors (e.g., the first item in the iterator doesn't), hence I want to extend my iterator with additional "dummy items" at the beginning and the end. The iter::chain method should do what I want; I just can't make the types line up.

Reduced code example, playground link.

fn main() {
    enum Token { A, B }
    let tokens = vec!(Token::A, Token::B);
    let try1 = [None, None].iter()
        .chain(tokens.into_iter().map(|t| Some(t)));
}

In reality, the enum Token is more complex and my vector tokens will contain more than two elements.

I expected the code to compile: both iterators should be iterators over items of type Option<Token>.

Instead, I get an error message "expected enum Option<Token>, found reference &Option<_>" with the error code E0271.

Can anybody help me to understand why so? Thanks a lot!

This is because iter() on arrays returns iterator over references. You can use IntoIter explicitly to get an iterator over values:

use std::array;

fn main() {
    enum Token { A, B }
    let tokens = vec![Token::A, Token::B];
    let try1 = array::IntoIter::new([None, None]).chain(tokens.into_iter().map(|t| Some(t)));
}

1 Like

I had no idea about this --- thanks a lot!