Search code examples
rusttypesclosuresrust-analyzer

What is the type for the closure |a: i32, b: i32| {a + b}?


I tried to type in what vscode was showing for my closure type definition, but it's wrong. What should I use instead?

My code:

let x = |a: i32, b: i32| {a + b};

rust-analyzer extension:

let x: impl Fn(i32,i32) -> i32 = |a: i32, b: i32| {a + b};

I want to manually define the types, so I usually will just type in what rust-analyzer provides me with, but in this situation it doesn't work. Since that is the improper way to use impl. What would I use instead?


Solution

  • Closure types don't have names in stable Rust, so you cannot actually name the type currently.

    You will be able to name them when the type_alias_impl_trait feature is stabilized. For example, on nightly you can do this, which aliases the closure type as SumI32:

    #![feature(type_alias_impl_trait)]
    
    type SumI32 = impl Fn(i32, i32) -> i32;
    
    fn create_sum_i32() -> SumI32 {
        |a, b| { a + b }
    }
    

    (Playground)

    Note that every closure has a distinct type, so this won't let you create arbitrary closures (even a completely identical one!) and treat it as a SumI32.

    fn create_sum_i32_2() -> SumI32 {
        |a, b| { a + b }
    }
    
    error: concrete type differs from previous defining opaque type use
      --> src/lib.rs:10:5
       |
    10 |     |a, b| { a + b }
       |     ^^^^^^^^^^^^^^^^ expected `{closure@src/lib.rs:6:5: 6:11}`, got `{closure@src/lib.rs:10:5: 10:11}`
       |