Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't coerce closure to fn in a tuple #101705

Open
camsteffen opened this issue Sep 12, 2022 · 2 comments
Open

Can't coerce closure to fn in a tuple #101705

camsteffen opened this issue Sep 12, 2022 · 2 comments
Labels
A-closures Area: Closures (`|…| { … }`) A-coercions Area: implicit and explicit `expr as Type` coercions C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@camsteffen
Copy link
Contributor

The following code:

fn tuple_closures_test(n: u32) {
    let (print_it, is_zero) = match 0 {
        0 => (|| println!("zero"), true),
        _ => (|| println!("other"), false),
    };
    print_it();
}

Produces this error:

error[[E0308]](https://doc.rust-lang.org/stable/error-index.html#E0308): `match` arms have incompatible types
  --> src/lib.rs:13:14
   |
11 |       let (print_it, is_zero) = match 0 {
   |  _______________________________-
12 | |         0 => (|| println!("zero"), true),
   | |              ---------------------------
   | |              ||
   | |              |the expected closure
   | |              this is found to be of type `([closure@src/lib.rs:12:15: 12:34], bool)`
13 | |         _ => (|| println!("other"), false),
   | |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected closure, found a different closure
14 | |     };
   | |_____- `match` arms have incompatible types
   |
   = note: expected tuple `([closure@src/lib.rs:12:15: 12:34], _)`
              found tuple `([closure@src/lib.rs:13:15: 13:35], _)`
   = note: no two closures, even if identical, have the same type
   = help: consider boxing your closure and/or using it as a trait object

But I think it should compile by coercing the closures to fn types. The following compiles:

fn test(n: u32) {
    let print_it = match n {
        0 => || println!("zero"),
        _ => || println!("other"),
    };
    print_it();
}
@BGR360
Copy link
Contributor

BGR360 commented Sep 12, 2022

@rustbot label C-bug T-compiler A-closures A-coercions

@rustbot rustbot added A-closures Area: Closures (`|…| { … }`) A-coercions Area: implicit and explicit `expr as Type` coercions C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Sep 12, 2022
@compiler-errors
Copy link
Member

As far as I'm aware, coercion only really goes one level deep when it comes to types -- we don't make an attempt to coerce similar cases when the closures are boxed, wrapped in a struct, etc., so this seems like consistent behavior for tuples.

So I'm not really certain this is a bug, or an extension to coercion behavior that needs to be better well-defined and investigated for feasibility.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-closures Area: Closures (`|…| { … }`) A-coercions Area: implicit and explicit `expr as Type` coercions C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants