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 :
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.
jonh found the solution. But in case you want to reproduce :
the code only stopped compiliing once i started using that function with a specific closure containing a specific code :
The Future is just an associated type, it doesn't "use" anything by itself. Depending on the kind of data you put into it, however - some additional bounds may or may not be required.
Might be - since the error simply vanished when you turned your impl AsyncFnOnce into an impl FnOnce without changing the Arc<RwLock<dyn JobProducerInterface>> passed to it, in any way.
Going back to the error (with a few omissions for the sake of clarity):
`{async closure@<...>}` must implement `X<(Y<(dyn Z + '0)>>,)>`, for any lifetime `'0`...
... but it actually implements `X<(Y<dyn Z>>,)>`
That phrasing alone is (usually) quite a clear indicator that HRTBs need to enter the picture. In your case, the compiler has inferred your closure is only able to handle the X<(Y<dyn Z>>,)>specific to the place/scope in which you've defined it. Meanwhile, the {async closure} is required to be able to tackle any X<(Y<dyn Z + 'a>>,)> for any'a.
The (beginner's) book only has a chapter on the difference between functions and closures, which isn't going to be of much help here. Take a look at @quinedot's blog instead: [1] and [2].
as @jonh pointed out, though - it might not be wise to let your closure "loose" over any, arbitrarily short lifetime; the explicit 'static bound makes a lot more sense. ↩︎