Is empty closure a type that is implemented with `Copy` trait but its copy is exceptionally not the same type as the original one?

fn main() {
    let empty_closure = || {};
    let _ = vec![empty_closure, empty_closure]; // ❌: two separate types?

    let a = 1;
    let closure_ref = || {a};
    let _ = vec![closure_ref, closure_ref]; // ✅: same type

    let closure_move = move || {a};
    let _ = vec![closure_move, closure_move]; // ✅: same type
}

here is the error info:

2 |     let empty_closure = || {};
  |                         ----- the expected closure
3 |     let _ = vec![empty_closure, empty_closure]; // ❌
  |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected slice, found array of 2 elements
  |
  = note: expected struct `Box<[[closure@src/main.rs:2:25: 2:30]], _>`
             found struct `Box<[fn(); 2], std::alloc::Global>`

I know these codes work fine:

let _: Vec<fn()> = vec![empty_closure, empty_closure]; // ✅ same type: function pointer types
let _ = [empty_closure, empty_closure]; // ✅: same type

Just for curiosity, why Rust infers the types of two elements in vec![empty_closure, empty_closure] are different?

They are the same type; something else must be going on here. The error seems weird; should be worth opening an issue.

Edit: Actually, it only fails on stable; this might be an issue that’s already fixed.

Edit2: Apparently it’s fixed in

https://github.com/rust-lang/rust/pull/88147

So your example code will work with 1.57, released on December 2nd, 2021.

3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.