Repository: rust
Issue: Inconsistent `fn` casting behavior in `if`-`else` branches for tuple and struct
Labels: T-compiler,C-bug,needs-triage

<!--
Thank you for filing a bug report! 🐛 Please provide a short summary of the bug,
along with any information you feel relevant to replicating the bug.
-->

I tried this code:

#### Version 1 (Compiles successfully):
```rust
use std::hint::black_box;
use std::any::type_name_of_val;

fn foo() {}
fn bar() {}

fn main() {
    let x = if black_box(true) { foo } else { bar };
    println!("{}", type_name_of_val(&x)); // observing `fn` items being cast to `fn` pointers, output: `fn()`
}
```

#### Version 2 (Fails to compile, tuple)
```rust
use std::hint::black_box;
use std::any::type_name_of_val;

fn foo() {}
fn bar() {}

fn main() {
    let x = if black_box(true) { (foo,) } else { (bar,) }; // mismatched types, no casting observed
    println!("{}", type_name_of_val(&x.0));
}
```

#### Version 3 (Fails to compile, struct)
```rust
use std::any::type_name_of_val;
use std::hint::black_box;

fn foo() {}
fn bar() {}

struct F<T>
where
    T: Fn(),
{
    inner: T,
}

fn main() {
    let x = if black_box(true) {
        F { inner: foo }
    } else {
        F { inner: bar }
    }; // mismatched types, no casting observed
    println!("{}", type_name_of_val(&x.inner));
}
```

I expected to see this happen:
In all versions, I expected the code to either compile successfully or fail with the same type mismatch error.

Instead, this happened:
Version 1 compiles successfully, while version 2 and version 3 fail with the same error `expected fn item, found a different fn item`. Explicitly specifying the `fn` pointer type for `x` resolves the issue. By the way, the use of `impl_trait_in_bindings` feature does not affect this behavior.

### Meta
<!--
If you're using the stable version of the compiler, you should also check if the
bug also exists in the beta or nightly versions.
-->

`rustc --version --verbose`:
```
rustc 1.86.0-nightly (99768c80a 2025-01-23)
binary: rustc
commit-hash: 99768c80a1c094a5cfc3b25a04e7a99de7210eae
commit-date: 2025-01-23
host: x86_64-unknown-linux-gnu
release: 1.86.0-nightly
LLVM version: 19.1.7
```

<!--
Include a backtrace in the code block by setting `RUST_BACKTRACE=1` in your
environment. E.g. `RUST_BACKTRACE=1 cargo build`.
-->
<details><summary>

`RUST_BACKTRACE=1` doesn't provide additional information for any of the versions.

Version 1 only provides `Finished ...` and no other information.
</summary>
<p>

**Version 2**
```
   Compiling rust-test v0.1.0 (.../rust-test)
error[E0308]: `if` and `else` have incompatible types
 --> src/main.rs:8:50
  |
8 |     let x = if black_box(true) { (foo,) } else { (bar,) }; // mismatched types, no casting observed
  |                                  ------          ^^^^^^ expected `(fn() {foo},)`, found `(fn() {bar},)`
  |                                  |
  |                                  expected because of this
  |
  = note: expected tuple `(fn() {foo},)`
             found tuple `(fn() {bar},)`

For more information about this error, try `rustc --explain E0308`.
error: could not compile `rust-test` (bin "rust-test") due to 1 previous error
```

**Version 3**
```
   Compiling rust-test v0.1.0 (.../rust-test)
error[E0308]: `if` and `else` have incompatible types
  --> src/main.rs:18:9
   |
15 |       let x = if black_box(true) {
   |  _____________-
16 | |         F { inner: foo }
   | |         ---------------- expected because of this
17 | |     } else {
18 | |         F { inner: bar }
   | |         ^^^^^^^^^^^^^^^^ expected `F<fn() {foo}>`, found `F<fn() {bar}>`
19 | |     }; // mismatched types, no casting observed
   | |_____- `if` and `else` have incompatible types
   |
   = note: expected struct `F<fn() {foo}>`
              found struct `F<fn() {bar}>`

For more information about this error, try `rustc --explain E0308`.
error: could not compile `rust-test` (bin "rust-test") due to 1 previous error
```

</p>
</details>