Workaround to tie lifetime of `T` behind `F: for<'b> FnOnce(RefMut<'b, T>)` to this closure?

Consider this code (playground):

use std::cell::{RefCell, RefMut};
use std::ops::{Deref, DerefMut};
use std::rc::{Rc, Weak};

fn main() {}

trait Upgrade {
    type Strong;

    fn upgrade(&self) -> Option<Self::Strong>;
}

impl<T> Upgrade for Weak<T> {
    type Strong = Rc<T>;

    fn upgrade(&self) -> Option<Self::Strong> {
        self.upgrade()
    }
}

trait CaptureAndProvideMutRef<T> {
    type Reference<'a>: DerefMut<Target = T>
    where
        T: 'a;

    fn capture<F, O>(&self) -> impl Fn(F) -> O
    where
        // T: 'static, // This makes it work, but also spreads downstream, which is a no-go.
        F: for<'b> FnOnce(Self::Reference<'b>) -> O,
        O: Default;
}

impl<W, T> CaptureAndProvideMutRef<T> for W
where
    W: Clone + Upgrade,
    W::Strong: Deref<Target = RefCell<T>>,
{
    type Reference<'a> = RefMut<'a, T> where T: 'a;

    fn capture<F, O>(&self) -> impl Fn(F) -> O
    where
        // T: 'static,
        //F: for<'b> FnOnce(Self::Reference<'b>) -> O,
        F: for<'b> FnOnce(RefMut<'b, T>) -> O, // Reduces errors from 5 to 3.
        O: Default,
    {
        let weak = W::clone(self);

        move |f| {
            if let Some(strong) = weak.upgrade() {
                f(strong.deref().borrow_mut())
            } else {
                O::default()
            }
        }
    }
}

This generates the error error[E0311]: the parameter type `T` may not live long enough. The compiler tells me to add the explicit lifetime bound T: 'b, which is nonsense, because 'b is inaccessible outside the HRTB (there are GitHub issues already mentioning this).

What are my options to work around this issue and still be able to provide the caller-defined FnOnce closure a reference that can't last longer than the closure run, so the compiler doesn't complain about f(strong.deref().borrow_mut())?

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.