'How to specify rust Box type in Box::<_>::new()

It is strange that in the code snippet below, the second function compiles, but not the third.

pub fn foo1(iter: Box<dyn Iterator<Item = u8>> ) -> Box<dyn Iterator<Item = u8>> {
      Box::new(iter.map(|n| n + 1)) 
} // This compiles

pub fn foo2(iter: Box<dyn Iterator<Item = u8>> ) -> Box<dyn Iterator<Item = u8>> {
    let a: Box::<dyn Iterator<Item = u8>> = Box::<_>::new(iter.map(|n| n + 1));
    a
} // This also compiles

pub fn foo3(iter: Box<dyn Iterator<Item = u8>> ) -> Box<dyn Iterator<Item = u8>> {
    let a: Box::<dyn Iterator<Item = u8>> = Box::<dyn Iterator<Item = u8>>::new(iter.map(|n| n + 1));
    a   
} // This does not compile

How should we specify Box::<_>::new in the third funciton to make it compiles, and why?

Playground



Solution 1:[1]

In the first and second version, the function you call is not <Box<dyn Iterator<Item = u8>>>::new(). This function requires T: Sized, but dyn Iterator: !Sized. Rather, you call <Box<SomeConcreteType>>::new(), and coerce the result to Box<dyn Iterator<Item = u8>>.

The fully type-ascribed version is:

pub fn foo3(iter: Box<dyn Iterator<Item = u8>>) -> Box<dyn Iterator<Item = u8>> {
    let a: Box<dyn Iterator<Item = u8>> = Box::<
        std::iter::Map<
            Box<dyn Iterator<Item = u8>>, // The original iterator type
            _,                            // The callback type (cannot be named using stable Rust)
        >,
    >::new(iter.map(|n| n + 1))
        as Box<dyn Iterator<Item = u8>>;
    a
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Chayim Friedman