Beginner lifetime question on AsyncFnOnce vs FnOnce -> impl Future

โš“ rust    ๐Ÿ“… 2025-05-17    ๐Ÿ‘ค surdeus    ๐Ÿ‘๏ธ 4      

surdeus

Warning

This post was published 44 days ago. The information described in this article may have changed.

Currently developping a backend in axum, and ended up creating this function :

pub async fn publish_job<T: Send + 'static, E>(
        &self,
        f: impl AsyncFnOnce(Arc<RwLock<dyn JobProducerInterface>>) -> Result<T, E>,
    ) -> Result<T, MyErrorType>
    where
        E: Into<MyErrorType>,
    {

Which triggered this compilation error somewhere high up the stack (at the axum router) :

> "implementation of `AsyncFnOnce` is not general enoughโ€ฆ
> โ€ฆ
> โ€ฆnote: `{async closure@src/biz/account.rs:81:27: 81:52}` must implement `AsyncFnOnce<(Arc<tokio::sync::RwLock<(dyn producer::JobProducerInterface + '0)>>,)>`, for any lifetime `'0`...
>    = note: ...but it actually implements `AsyncFnOnce<(Arc<tokio::sync::RwLock<dyn producer::JobProducerInterface>>,)>`

I ended up changing the signature of the function to something i thought was strictly equivalent :

pub async fn publish_job<T: Send + 'static, Fut, E>(
        &self,
        f: impl FnOnce(Arc<RwLock<dyn JobProducerInterface>>) -> Fut,
    ) -> Result<T, MyError>
    where
        Fut: Future<Output = Result<T, E>>,
        E: Into<MyError>,

And to my surprise, the compilation error disappeared. Note that the underlying code hasn't changed. It's strictly the same, i only changed the signature.

Does someone has an explanation ?

1 post - 1 participant

Read full topic

๐Ÿท๏ธ rust_feed