Repository: rust
Issue:  Confusing behavior and mismatched error reports for `impl_trait_in_fn_trait_return` && `type_alias_impl_trait`
Labels: T-compiler,C-bug,F-type_alias_impl_trait,F-impl_trait_in_fn_trait_return

I tried this code in my lib for curring function with generics:

```rust
#![feature(impl_trait_in_fn_trait_return)]
#![feature(type_alias_impl_trait)]
#![allow(clippy::let_and_return)]

use std::fmt::Display;

// Failed to compile
fn concat_1<T: Display>(a: T) -> impl FnOnce(T) -> impl FnOnce(T) -> String {
    move |b: T| move |c: T| format!("{a} {b} {c}")
}

// Successful
fn concat_2<T: Display>(a: T) -> impl FnOnce(T) -> impl FnOnce(T) -> String {
    let f = move |b: T| move |c: T| format!("{a} {b} {c}");
    f
}

// Failed to compile
type A3<T: Display> = impl FnOnce(T) -> B3<T>;
type B3<T: Display> = impl FnOnce(T) -> String;
fn concat_3<T: Display>(a: T) -> A3<T> {
    move |b: T| move |c: T| format!("{a} {b} {c}")
}

// Successful
type A4<T: Display> = impl FnOnce(T) -> B4<T>;
type B4<T: Display> = impl FnOnce(T) -> String;
fn concat_4<T: Display>(a: T) -> A4<T> {
    let f = move |b: T| move |c: T| format!("{a} {b} {c}");
    f
}

fn main() {}
```




### 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.78.0-nightly (2d24fe591 2024-03-09)
binary: rustc
commit-hash: 2d24fe591f30386d6d5fc2bb941c78d7266bf10f
commit-date: 2024-03-09
host: x86_64-unknown-linux-gnu
release: 1.78.0-nightly
LLVM version: 18.1.0
```

### Error output

- for `concat_1`:

```txt
error: concrete type differs from previous defining opaque type use
 --> src/main.rs:9:17
  |
9 |     move |b: T| move |c: T| format!("{a} {b} {c}")
  |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `impl FnOnce(T) -> String`, got `{closure@src/main.rs:9:17: 9:28}`
  |
note: previous use here
 --> src/main.rs:9:5
  |
9 |     move |b: T| move |c: T| format!("{a} {b} {c}")
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0720]: cannot resolve opaque type
 --> src/main.rs:8:52
  |
8 | fn concat_1<T: Display>(a: T) -> impl FnOnce(T) -> impl FnOnce(T) -> String {
  |                                                    ^^^^^^^^^^^^^^^^^^^^^^^^ cannot resolve opaque type

For more information about this error, try `rustc --explain E0720`.
```

- for `concat_3`:

```txt
error: concrete type differs from previous defining opaque type use
  --> src/main.rs:22:17
   |
22 |     move |b: T| move |c: T| format!("{a} {b} {c}")
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `B3<T>`, got `{closure@src/main.rs:22:17: 22:28}`
   |
note: previous use here
  --> src/main.rs:22:5
   |
22 |     move |b: T| move |c: T| format!("{a} {b} {c}")
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```

Why there is `E0720` error in a piece of code where recursion does not occur?
(An `impl Trait` type must be expandable to a concrete type that contains no `impl Trait` types.)

Temporary solution:

```rust
fn concat<T: Display + 'static>(a: T) -> Box<dyn FnOnce(T) -> Box<dyn FnOnce(T) -> String>> {
    Box::new(move |b: T| Box::new(move |c: T| format!("{a} {b} {c}")))
}
```

[playground](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=7c0a61f5a924c92a0157f11e5e582068)