Nested closures - refence escapes closure body

So, I have the following trait Input:

trait Input: Sized {
    // This should be Self but with a generic lifetime
    // I tried it with FnOnce(Self), but the the impl Input for &[i32] doesn't
    // work as the lifetime of the arg is shorter than the one of Self
    type Mapped<'a>;
    fn with_input<F>(self, f: F)
    where
        for<'a> F: FnOnce(Self::Mapped<'a>);
}

Input is basically a trait which is implemented by a specific value or slices/arrays of that value (e.g. &[[i32; N]] could be an input). Calling with_input should construct a value that has the same "shape" as Self (which currently means that slices and array have the same length) and passes this to the closure.
Now I wish to implement Input on tuples of values which implement Input.

impl<I1: Input, I2: Input> Input for (I1, I2)
{
    type Mapped<'a> = (I1::Mapped<'a>, I2::Mapped<'a>);

    fn with_input<F>(self, f: F)
    where
        for<'a> F: FnOnce(Self::Mapped<'a>),
    {
        self.0.with_input(|i1| {
            self.1.with_input(|i2| {
                f((i1, i2)); 
            })
        })
    }
}
Unfortunately, this fails to compile with the error:
error[E0521]: borrowed data escapes outside of closure
  --> src/main.rs:78:17
   |
76 |         self.0.with_input(|i1| {
   |                            -- `i1` declared here, outside of the closure body
77 |             self.1.with_input(|i2| {
   |                                -- `i2` is a reference that is only valid in the closure body
78 |                 f((i1, i2));
   |                 ^^^^^^^^^^^ `i2` escapes the closure body here

error[E0521]: borrowed data escapes outside of closure
  --> src/main.rs:78:17
   |
76 |         self.0.with_input(|i1| {
   |                            --
   |                            |
   |                            `i1` is a reference that is only valid in the closure body
   |                            has type `<I1 as Input>::Mapped<'1>`
77 |             self.1.with_input(|i2| {
78 |                 f((i1, i2));
   |                 ^^^^^^^^^^^
   |                 |
   |                 `i1` escapes the closure body here
   |                 argument requires that `'1` must outlive `'static`

I'm not sure where the problem lies. Curiosly, the impl for a single element tuple works, so the nested closures must be part of the problem. I've also tried to implement the trait without the GAT and receiving Self as the argument to the closure of with_input but this breaks the implementation for &[i32].

The code plus additional impls are here: Playground.

I'd be really happy if someone could help me out. I've already spent quite some time banging my head against the wall on this and similar problems.

I think I kind of understand where the problem is. The Mapped GAT provides the same lifetime 'a for the left and right part of the tuple and the provided closure should work for any lifetime 'a.
But the values i1 and i2 don't have the same lifetime. For some reason this has the same effect as if the closure was declared as F: FnOnce(Self::Mapped<'static>) (leads to the exact same error message).

But I think I found a workaround. I wanted to define Input on tuples to make the following more succint

fn outer(i1: &[i32], i2: &[i32]) {
    fn inner_fn(i1: &[i32], i2: &[i32]) {}
    
    i1.with_input(|i1| {
        i2.with_input(|i2| {
            inner_fn(i1, i2)
        })
    })
}

but, since this code will be generated by a proc macro anyway, it's not terribly important.

However, if someone has an idea why the impl for the tuple is not working or a way how to get it to compile, I'd be happy to hear it :)

My best guess was something like this thread, where it's possible for the closures to "steal" from one another. I tried breaking the lifetimes apart at the trait/GAT level, but then it said each one needed to outlive the other (i.e. they need to be the same).

That's as far as I got.

Migrate-mode error with GAT emulation. The emulation makes your lifetimes definitely invariant... but I think the same is true of GAT lifetimes. Stares into distance... Yeah I think it has to be, implementor A could use a covariant type while implementor B uses a contravariant type.

Related.

I don't think it can work without further changes; you can't unify or even really enforce an ordering between the two anonymous/higher-ranked lifetimes of the nested closures. Or to put it another way, the inner closure can never be fully higher ranked as its validity is capped by the outer closure it captures from.