Skip to content

Type inference cannot propagate through map combinator #89350

Open
@Kobzol

Description

@Kobzol

Hi! I was surprised to see that in the following code, explicit return type (or map turbofish) annotation has to be specified for the map combinator for the code to compile:

struct A;
struct B;

trait Trait {}

impl Trait for A {}
impl Trait for B {}

fn foo(arg: bool) {
    // Compiles
    let _: Option<Box<dyn Trait>> = match arg {
        true => Some(Box::new(A)),
        false => Some(Box::new(B)),
    };

    // Doesn't compile
    /*let _: Option<Box<dyn Trait>> = match arg {
        true => Some(()).map(|v| Box::new(A)),
        false => Some(()).map(|v| Box::new(B)),
    };*/

    // Compiles
    let _: Option<Box<dyn Trait>> = match arg {
        true => Some(()).map(|v| -> Box<dyn Trait> { Box::new(A) }), // or Some(()).map::<Box<dyn Trait>, _>(...)
        false => Some(()).map(|v| -> Box<dyn Trait> { Box::new(B) }),
    };
}

The inference can work it out if I construct the Option directly, but once map is added, it cannot see that both of the maps should coerce to Box<dyn Trait>. Is this a limitation of the current type inference or should this work?

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-closuresArea: Closures (`|…| { … }`)A-coercionsArea: implicit and explicit `expr as Type` coercionsA-inferenceArea: Type inferenceT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions