Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between [fn] vs [(fn, u8)] in terms of type-inference?

Why does this compile:

fn main() {
   let xs = [||1, ||2, ||3];
}

but this does not?

fn main() {
   let xs = [(||1, 1), (||2, 2), (||3, 3)];
}
error[E0308]: mismatched types
 --> src/main.rs:2:29
  |
2 |     let xs = [((|| 1), 1), ((|| 2), 2), ((|| 3), 3)];
  |                 --          ^^^^^^ expected closure, found a different closure
  |                 |
  |                 the expected closure
  |
  = note: expected closure `{closure@src/main.rs:2:17: 2:19}`
             found closure `{closure@src/main.rs:2:30: 2:32}`
  = note: no two closures, even if identical, have the same type
  = help: consider boxing your closure and/or using it as a trait object

error[E0308]: mismatched types
 --> src/main.rs:2:42
  |
2 |     let xs = [((|| 1), 1), ((|| 2), 2), ((|| 3), 3)];
  |                 -- the expected closure  ^^^^^^ expected closure, found a different closure
  |
  = note: expected closure `{closure@src/main.rs:2:17: 2:19}`
             found closure `{closure@src/main.rs:2:43: 2:45}`
  = note: no two closures, even if identical, have the same type
  = help: consider boxing your closure and/or using it as a trait object

To be clear, the question is not why does it not compile. It is what is the difference between these two that makes the first compile but the second does not?.


1 Answers

The first case is special cased in the compiler: when some types are required to unify (such as when all of them are elements of the same array), and all of them are non-capturing closures, the compiler automatically coerces them to function pointers. This does not work if they are tuple that contain non-capturing closures, however.

The relevant code in rustc is here, if you're interested.

like image 191
Chayim Friedman Avatar answered Dec 02 '25 03:12

Chayim Friedman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!