Can a lifetime parameter affect whether the parameterized type is Send?

⚓ Rust    📅 2026-03-20    👤 surdeus    👁️ 5      

surdeus

Is the following proposition true?

Proposition 1: Assume a type T<'l> parameterized on a lifetime. If T<'a>: Send for some lifetime 'a, then T<'l>: Send for all lifetimes 'l.

How about the following weaker version?

Proposition 2: Assume a type F: AsyncFnMut. If F::CallRefFuture<'a>: Send for some lifetime 'a, then F::CallRefFuture<'l>: Send for all lifetimes 'l.

Or the following even weaker version?

Proposition 3: Although proposition 2 may not be true in general, e.g. for hand-rolled implementations of AsyncFnMut that do weird things, it is true of all types F that are associated with an actual syntactic closure (i.e. something spelled as async (move)? |...| { ... }).

In all cases I am interested in counterexamples, ideally non-contrived ones, but contrived too if that's all that exists.


If you're interested in why I want to know this, I'm looking for a workaround for this issue, where it's difficult/impossible for an API to require the caller to provide a thread-safe AsyncFnMut without restricting to only 'static closures. I believe any of the propositions above would allow me to do the following:

  • Define my own trait for "is AsyncFnMut, and the returned future is Send for all lifetimes with which self can be borrowed".

    I believe this trait could be used as a bound without triggering the issue I'm working around, because no HRTB is required, as the trait builds in its own quantification over lifetimes.

  • Let users safely access an implementation of this trait by calling a macro that checks that the returned future is Send for one particular lifetime.

6 posts - 2 participants

Read full topic

🏷️ Rust_feed