Skip to content

Option map won't compile while match works well #47212

@andreytkachenko

Description

@andreytkachenko

Consider this snippet:

fn xxx() -> Option<&'static str> {
    Some("word1 word2 word3")
}

fn to_words<'a>() -> Option<Box<Iterator<Item = &'a str> + 'a>> {
    xxx().map(|x|Box::new(x.split(' ')))
}

fn main() {
    println!("{}", to_words().unwrap().count());
}

it won't compiles with the error:

error[E0308]: mismatched types
 --> src/main.rs:6:5
  |
5 | fn to_words<'a>() -> Option<Box<Iterator<Item = &'a str> + 'a>> {
  |                      ------------------------------------------ expected `std::option::Option<std::boxed::Box<std::iter::Iterator<Item=&'a str> + 'a>>` because of return type
6 |     xxx().map(|x|Box::new(x.split(' ')))
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait std::iter::Iterator, found struct `std::str::Split`
  |
  = note: expected type `std::option::Option<std::boxed::Box<std::iter::Iterator<Item=&'a str> + 'a>>`
             found type `std::option::Option<std::boxed::Box<std::str::Split<'_, char>>>`

but match in exactly same case compiles well:

fn xxx() -> Option<&'static str> {
    Some("word1 word2 word3")
}

fn to_words<'a>() -> Option<Box<Iterator<Item = &'a str> + 'a>> {
    match xxx() {
        Some(x) => Some(Box::new(x.split(' '))),
        None => None
    }
}

fn main() {
    println!("{}", to_words().unwrap().count());
}

And if I explicitly define closure's argument type and returning value type it also compiles well:

fn xxx() -> Option<&'static str> {
    Some("word1 word2 word3")
}

fn to_words<'a>() -> Option<Box<Iterator<Item = &'a str> + 'a>> {
    let f: fn(x: &'a str) -> Box<Iterator<Item = &'a str>> = |x| {
        Box::new(x.split(' '))
    };
    
    xxx().map(f)
}

fn main() {
    println!("{}", to_words().unwrap().count());
}

I am sure there should not be differences between match and map at all.

This issue is reproduceble on rust stable and nightly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-coercionsArea: implicit and explicit `expr as Type` coercionsC-enhancementCategory: An issue proposing an enhancement or a PR with one.T-langRelevant to the language team

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions