- Traits that contain
async fnor impl trait in traits can still be dyn safe
- Costs like boxing of futures are limited to code that uses
dyn Traitand not to all users of the trait
- Reasonable defaults around things like
Send + Syncand what kind of boxing is used
- Ability to customize those defaults for individual traits or on a crate-wide or module-wide basis
- Permit a trait
async fnor impl trait in traits to be used with
dyn TheTrait, at least if other criteria are met.
- Do not require annoying annotations.
- Permit the user to select, for
TheTrait, how the futures will be boxed or otherwise represented, which would permit us to use
Boxor potentially other types like
- User should also be able to control whether the resulting futures are assumed to be send.
The most basic desugaring of async fn in traits will make the trait not dyn-safe. "Inline" async fn in traits is one way to circumvent that, but it's not suitable for all traits that must be dyn-safe. There are other efficient options:
- Return a
Box<dyn Async<...>>-- but then we must decide if it will be
Send, right? And we'd like to only do that when using the trait as a
dyn Trait. Plus it is not compatible with no-std (it is compatible with alloc).
- This comes down to needing some form of opt-in.
This concern applies equally to other "
-> impl Trait in trait" scenarios.
We have looked at revising how "dyn traits" are handled more generally in the lang team on a number of occasions, but this meeting seems particularly relevant. In that meeting we were discussing some soundness challenges with the existing dyn trait setup and discussing how some of the directions we might go enabled folks to write their own
impl Trait for dyn Trait impls, thus defining for themselves how the mapping from Trait to dyn Trait. This seems like a key piece of the solution.
One viable route might be:
- Traits using
async fnare not, by default, dyn safe.
- You can declare how you want it to be dyn safe:
#[derive(dyn_async_boxed)]or some such
- to take an
- to take an
- It would be nice if users can declare their own styles. For example, Matthias247 pointed out that the
Boxused to allocate can be reused in between calls for increased efficiency.
- It would also be nice if there's an easy, decent default -- maybe you don't even have to opt-in to it if you are not in
"It's complicated". A lot of no-std code does have an allocator (it depends on alloc), though it may require fallible allocation, or permit allocation of fixed quantities (e.g., only at startup, or so long as it can be known to be O(1)).