Hidden type for captures lifetime that does not appear in bounds

⚓ Rust    📅 2025-07-24    👤 surdeus    👁️ 2      

surdeus

This is almost minimal reproducible example for my case, I left some details for clarity

#![feature(type_alias_impl_trait)]

use std::marker::PhantomData;

mod crate1 {
    use super::*;

    pub struct Request<'a, R>(PhantomData<&'a R>);
    pub struct RequestReader<'a, R>(PhantomData<&'a R>);
    pub trait Handler {
        async fn call<R>(&self, request: Request<'_, R>);
    }

    impl<'a, R> Request<'a, R> {
        pub fn reader<'b>(&'b self) -> RequestReader<'b, R> {
            RequestReader(PhantomData)
        }
    }
}

mod crate2 {
    use super::*;

    use crate1::{Handler, Request};

    trait Provider {
        async fn provide<R, P: Provider>(&self, f: SaverFn<R, P>);
    }

    struct Saver<P: Provider> {
        provider: P,
    }
    type SaverFn<R, P: Provider> = impl AsyncFnOnce(&mut ());

    impl<P: Provider> Handler for Saver<P>
    where
        P: Provider,
    {
        #[define_opaque(SaverFn)]
        async fn call<R>(&self, request: Request<'_, R>) {
            let reader = request.reader(); // Without this reborrow I can make it compile
            // Hopefully `super let` will be stabilized and it would
            // become `let writer = (self.provide)().await;`
            self.provider.provide::<R, P>(async |writer| {
                core::hint::black_box((reader, writer));
            });
        }
    }
}

First of all, if replace TAIT AsyncFnOnce with a struct that has async method, error goes away immediately.

Second, if add a lifetime to SaverFn, you need to add lifetime to provide. But it will trigger that error:

 1  error[E0581]: return type references lifetime `'a`, which is not constrained by the fn input types
   --> src/main.rs:27:9
    |
 27 |         async fn provide<'a, R, P: Provider>(&self, f: SaverFn<'a, R, P>);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

My question is, should I open an issue or two? Or maybe it is expected and you can tell me what I did wrong?

1 post - 1 participant

Read full topic

🏷️ Rust_feed