Search code examples
rustiteratortraits

Why does the IntoIterator trait require explicitly specifying the associated type Item?


Since the associated type IntoIter of the IntoIterator trait, implements the Iterator trait, isn't that sufficient to infer the associated type Item?


Solution

  • Why does the IntoIterator trait require explicit type Item declaration?

    It doesn't. You are correct that when you impl IntoIterator for ... then Item is redundant, and could be obtained through IntoIter.


    This was introduced in PR #22313. In short, the reason is was introduced was to simplify where clauses. If you have to specify IntoIter then that can quickly become cumbersome.

    where I: IntoIterator<IntoIter = ...>
    

    In that case it is much easier to do:

    where I: IntoIterator<Item = ...>
    

    Let's consider a random example, like print_strings. Then before you needed to do something like this:

    fn print_strings<I, T>(iter: I)
    where
        I: IntoIterator<IntoIter = T>,
        T: Iterator<Item = &'static str>,
    {
        for s in iter {
            println!("{}", s);
        }
    }
    

    Whereas now that can be simplified to just:

    fn print_strings<I>(iter: I)
    where
        I: IntoIterator<Item = &'static str>,
    {
        for s in iter {
            println!("{}", s);
        }
    }
    
    fn main() {
        print_strings(vec!["foo", "bar", "baz"]);
    }