Repository: rust
Issue: "implementation of `Fn` is not general enough" on some conditions when using closures
Labels: A-diagnostics,A-lifetimes,T-compiler,C-bug,needs-triage

Hello rust team!

I crossed the following compiler error.
There is a lifetime elision problem on closures on some specific conditions
- they accept as input a struct with a lifetime
- they are transmited to a function accepting multiple of them as generics

Quite hard to explain with words, so here is the simplified example:

## The code:
```rust
pub struct InodeMapper;

pub struct ValueCreatorParams<'a> {
    pub child_name: &'a u32,
}

impl InodeMapper {
    pub fn batch_insert<F, G>(
        &self,
        f1: F,
        f2: G
    )
    where
        F: for <'a> Fn(ValueCreatorParams<'a>) -> u32,
        G: for <'b> Fn(ValueCreatorParams<'b>) -> i32
    {
        todo!()
    }
}

fn test_batch_insert_large_entries_varying_depths() {
    let mapper = InodeMapper{};
    let f1 = |_| 1;
    let f2 = |_| 2;

    // *** ERROR ON FOLLOWING LINE ***
    mapper.batch_insert(f1, f2);
}
```

## The error
```text
implementation of `Fn` is not general enough
closure with signature `fn(test::ValueCreatorParams<'2>) -> u32` must implement `Fn<(test::ValueCreatorParams<'1>,)>`, for any lifetime `'1`...
...but it actually implements `Fn<(test::ValueCreatorParams<'2>,)>`, for some specific lifetime `'2`rustc[Click for full compiler diagnostic](rust-analyzer-diagnostics-view:/diagnostic%20message%20[4]?4#file:///home/alogani/Coding/easy_fuser/src/types/test.rs)
implementation of `FnOnce` is not general enough
closure with signature `fn(test::ValueCreatorParams<'2>) -> u32` must implement `FnOnce<(test::ValueCreatorParams<'1>,)>`, for any lifetime `'1`...
...but it actually implements `FnOnce<(test::ValueCreatorParams<'2>,)>`, for some specific lifetime `'2`rustc[Click for full compiler diagnostic](rust-analyzer-diagnostics-view:/diagnostic%20message%20[5]?5#file:///home/alogani/Coding/easy_fuser/src/types/test.rs)
```

## The solution:
Fully qualify the types of the closure arguments (for both)!
```rust
fn test_batch_insert_large_entries_varying_depths() {
    let mapper = InodeMapper{};
    let f1 = |_: ValueCreatorParams| 1;
    let f2 = |_: ValueCreatorParams| 2;

    mapper.batch_insert(f1, f2);
}
```
And now it works like a charm !

### Meta

`rustc --version --verbose`:
```
rustc 1.82.0 (f6e511eec 2024-10-15)
binary: rustc
commit-hash: f6e511eec7342f59a25f7c0534f1dbea00d01b14
commit-date: 2024-10-15
host: x86_64-unknown-linux-gnu
release: 1.82.0
LLVM version: 19.1.1
```

## Suggestions

Obviously, it has a solution, but I fill the bug report, because:
- this is a situation where I don't understand why the compiler can't infer the lifetime. (Maybe there is a reason a good reason and it shall not be corrected? To be honest, I am not sure to understand the intrinsics) 
- the error is not explicit (it took me several hours to isolate correctly the cause of the problem in my more complex codebase, I thought the problem were on signatures of the receiving function). So is there an improvement possible on compiler message ? Especially the compiler don't say how it infers a different lifetime for the two closures to help resolve the problem.

Thanks!