# Generic trait polymorphism and async send bounds

**URL:** <https://internals.rust-lang.org/t/generic-trait-polymorphism-and-async-send-bounds/19696>\
**Category:** language design\
**Created:** [October 11, 2023, 4:55pm UTC](https://internals.rust-lang.org/t/generic-trait-polymorphism-and-async-send-bounds/19696 "2023-10-11T16:55:56Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![lightmelodies](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/lightmelodies/32/11409_2.png) [@lightmelodies](https://internals.rust-lang.org/u/lightmelodies)\
**Post date:** [October 11, 2023, 4:55pm UTC](https://internals.rust-lang.org/t/generic-trait-polymorphism-and-async-send-bounds/19696/1 "2023-10-11T16:55:56Z")

</div>

Currently it's hard to specific **Send** bounds in async trait, and solutions like **Return type notation** or **Inferred async send bounds** are not quite consistent and extensible.

If we have generic trait parameters(similar to ,generic type/lifetime/const parameters), the `Send` bounds can be represent like:

```rust
trait AsyncIterator<trait R = Unbound> {
    type Item;

    fn next(&mut self) -> impl Future<Output = Option<Self::Item>> + R + '_;
}

/// or with symbol like ' in lifetime notation.
trait AsyncIterator<`R = Unbound> {
    type Item;

    fn next(&mut self) -> impl Future<Output = Option<Self::Item>> + R + '_;
}

// or with async syntax sugar
trait AsyncIterator<`R = Unbound> {
    type Item;

    async fn next(&mut self) -> Option<Self::Item> + R;
}

async fn traverse_no_send<I: AsyncIterator>(mut iter: I) { /* ... */ }

async fn traverse_send<I: AsyncIterator<Send>>(mut iter: I) { /* ... */ }

```

Where trait parameters can be contravariant, i.e. `AsyncIterator<Send + Sync>` is `AsyncIterator<Send>`.

The existential quantification way(associated trait) may be written as:

```rust
trait AsyncIterator {
    trait R = Unbound;

    type Item;

    async fn next(&mut self) -> Option<Self::Item> + Self::R;
}

```

Refers:

- [Async trait send bounds, part 1: intro · baby steps](https://smallcultfollowing.com/babysteps//blog/2023/02/01/async-trait-send-bounds-part-1-intro/)
- [Associated traits · Issue #2190 · rust-lang/rfcs · GitHub](https://github.com/rust-lang/rfcs/issues/2190)

---

<div class="post-metadata">

**Author:** ![cjwcommuny](https://avatars.discourse-cdn.com/v4/letter/c/7cd45c/32.png) [@cjwcommuny](https://internals.rust-lang.org/u/cjwcommuny)\
**Post date:** [October 13, 2023, 3:24am UTC](https://internals.rust-lang.org/t/generic-trait-polymorphism-and-async-send-bounds/19696/2 "2023-10-13T03:24:52Z")

</div>

Actually, the mentioned "Generic trait polymorphism" can also be used to implement the **real** `Functor` trait in Rust...

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [January 11, 2024, 3:25am UTC](https://internals.rust-lang.org/t/generic-trait-polymorphism-and-async-send-bounds/19696/3 "2024-01-11T03:25:10Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
