async_fn_traits icon indicating copy to clipboard operation
async_fn_traits copied to clipboard

Extend for futures with Send bounds?

Open cbeck88 opened this issue 1 month ago • 0 comments

I find this crate very helpful, but lately, I needed to combine two things:

  • An AsyncFn trait bound for a function that takes references, and for one of the lifetimes, needs to use a for <'b> ... higher order bound
  • A bound that promises that the OutputFuture is Send.

I tried writing a bound like this:

    where
        F: for <'b> AsyncFn2<&'a AppState, &'b mut i64, Output = Result<WorkFnStatus, Error>>,
        for <'b> <F as AsyncFn2<&'a AppState, &'b mut i64>>::OutputFuture: Send

and I get complex compiler errors:

error[E0277]: `<_ as AsyncFn2<&AppState, &'b mut i64>>::OutputFuture` cannot be sent between threads safely
    --> funding/service/src/app_state.rs:3199:21
     |
3196 |                 .generic_background_worker_entrypoint(
     |                  ------------------------------------ required by a bound introduced by this call
...
3199 |                     AppState::deposit_cooldown_background_worker_do_work,
     |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `<_ as AsyncFn2<&AppState, &'b mut i64>>::OutputFuture` cannot be sent between threads safely
     |
     = help: the trait `for<'b> std::marker::Send` is not implemented for `<_ as AsyncFn2<&AppState, &'b mut i64>>::OutputFuture`
note: this is a known limitation of the trait solver that will be lifted in the future
    --> funding/service/src/app_state.rs:3199:21
     |
3195 | /             worker_state
3196 | |                 .generic_background_worker_entrypoint(
3197 | |                     "deposit-cooldown",
3198 | |                     |st| &st.notify_deposit_cooldown_background_worker,
3199 | |                     AppState::deposit_cooldown_background_worker_do_work,
     | |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait solver is unable to infer the generic types that should be inferred from this argument
3200 | |                 )
     | |_________________- add turbofish arguments to this call to specify the types manually, even if it's redundant
note: required by a bound in `AppState::generic_background_worker_entrypoint`

It used to work before the Send bound was required.

I wonder if my problem would be fixed if there was a version of AsyncFnN that contained the Send constraint on the output future, so like perhaps AsyncFnNSend is like AyncFnN plus a Send constraint on OutputFuture.

What do you think, would you take a patch that introduces additional traits like that, or you think it's a bad direction?


Probably for now what I'm going to do is try to pass my &'b parameter as Arc<Mutex> so that there is no lifetime.

cbeck88 avatar May 07 '24 17:05 cbeck88