# Deep dive: AFIT Send bounds and keyword generics
Background (outdated)
* https://smallcultfollowing.com/babysteps/blog/2023/02/13/return-type-notation-send-bounds-part-2/
* https://blog.theincredibleholk.org/blog/2023/02/13/inferred-async-send-bounds/
###### tags: `deep-dive`
Leave questions, observations, discussion topics below.
---
```rust
trait ?async Iterator {
type Item;
?async fn next(&mut self) -> Option<Self::Item>;
fn size_hint(&self) -> (usize, Option<usize>) {..}
}
struct AsyncFile;
// always async impl!
impl async Iterator for AsyncFile { .. }
```
```rust
trait Foo {
async fn bar() {}
async fn baz() {}
async fn bin() {}
}
// ... and how do we mark all methods in `Foo` as `Send`
trait async Foo {
async fn bar() {}
}
```
## progression!
```rust
// say we start with this
trait async HealthCheck { .. }
async fn foo(check: impl async HealthCheck) { .. }
// .. but later on we realize `HealthCheck` may also
// be useful in !async contexts, so we change it to this:
trait ?async HealthCheck { .. }
// .. usage remains exactly as it was before!:
async fn foo(check: impl async HealthCheck) { .. }
// .. but maybe we want `foo` to also become `?async`, so we then can
// opt into instead changing it to:
?async fn foo(check: impl ?async HealthCheck) { .. }
```
```rust
trait async HealthCheck { .. }
async fn foo(check: impl async(Send) HealthCheck) { .. }
```
## Open Questions
### What is the default?
Are methods `Send` by default and we opt out? Or do we opt in to `Send`?
```rust
// Do we write this?
async fn foo(check: impl async(Send) HealthCheck) { .. }
// Or this?
async fn foo(check: impl async(?Send) HealthCheck) { .. }
```
### Does `async` show up in imports?
```rust
use my_crate::HealthCheck;
// Could you do...
use my_crate::async(Send) HealthCheck as async HealthCheck;
// What about aliases
type UsizeOption = Option<usize>;
trait AsyncHealthCheck = async HealthCheck;
fn foo(x: impl async(Send) AsyncHealthCheck) { .. }
```
If we can hide `async` behind a trait alias, we shouldn't require it on the trait definition.
```rust
trait async HealthCheck {
async fn check(...);
}
trait async SendHealthCheck = async(Send) HealthCheck;
fn foo(check: impl async HealthCheck) { .. }
fn bar(check: impl async SendHealthCheck) { .. }
```
```rust!
trait SendHealthCheck = async(Send) HealthCheck;
trait async HealthCheck {
async fn check(...);
}
trait async SendHealthCheck = async(Send) HealthCheck;
fn foo(check: impl HealthCheck + Send) { .. }
fn bar(check: impl SendHealthCheck) { .. }
```
### Supertraits
```rust
// Trait today!
trait FixedLengthIterator: Iterator { .. }
// Maybe-async variant
trait ?async FixedLengthIterator: ?async Iterator { .. }
// Always async variant
trait async FixedLengthIterator: async Iterator { .. }
```
### Are `async Trait` and `Trait` different names?
Can I do this?
```rust
trait Bar {
fn foo();
}
trait async Bar {
async fn baz();
}
```
Yosh: probably not; they live in the same namespace. But you could imagine an `async` and `!async` impl of the same `?async` trait on a single type.
```rust
struct ?async File { .. }
// either..
impl ?async Read
```