---
# System prepended metadata

title: Async fundamentals ere long ago (2021)

---

# Async fundamentals ere long ago (2021)

## 2021-12-20

### Problem with `with` clauses

```rust
fn deserialize_and_print_later(
    deserializer: &mut Deserializer,
    bytes: &[u8],
)
where in('static) T: Deserialize + Debug
{
    thread::spawn(|| {
        thread::sleep(1);
        let object = T::deserialize(deserializer)?;
        println!("{:?}", object);
    });
}
```

Not good enough.

```rust
trait ContextFree: Sealed {}

// This is stronger than we need, but works in
// all cases.
fn deserialize_and_print_later(
    deserializer: &mut Deserializer,
    bytes: &[u8],
)
where with(ContextFree) T: Deserialize + Debug
{ ... }
```

```rust
// This is exactly what we need.
fn deserialize_and_print_later(
    deserializer: &mut Deserializer,
    bytes: &[u8],
)
where with(Send + 'static) T: Deserialize + Debug
{ ... }
```


```rust
dyn Debug

// desugars to
dyn with(ContextFree) Debug + 'static

// or you could write..
dyn with(Bound) Debug + '_
```


```rust
where
    T: with(Send) AsyncTrait<async_fn: Send> + Send
```

`* Send`?

set interpretation

* `with(cap1, cap2)` vs `with(cap1) with(cap2)`
* `with(Bound)` means "all capabilities meet `Bound`"
* default for an impl is empty set
    * `with(_: Send)`
    * `with(Send)`
    * `with(cap1: Type)` or `with(cap1: impl Trait)`

:alternative-universe.gif:

* What if we ONLY HAD `Send * Bar` and no `+`...
* then you could do
    * `where T: Send * Debug` // in either order
    * `where T: Send, T: Debug` // distinct thing
* Meaning:
    * `T: Foo * Send` means "all RPITIT in Foo are Send"

Some form of opt-in for non-RPITIT?

```rust
trait Foo {
    // too strong! This makes `Foo * Send` != `Send`
    type Bar: if (Self: Send) Send
}

trait Foo {
    // not this, but like this, to mean that `T: Foo + Baz` where `Baz` is an auto trait
    // means `T: Foo<Bar: Baz> + Baz
    #[selfish]
    type Bar;
}
```




## 2021-12-16

### year end blog post

```rust
async fn main() {
    for await b in bottles() {
        send_request(b).await;
    }
}

async fn* bottles() yields String {
    for i in (0 .. 99).rev() {
        yield format!("{i} crabcakes on the wall");
    }
}
```

What are the pieces we need to make this beautiful code work

* Async fundamentals
    * Async functions
* Portability
    * async fn main
    * tcp stream or something
* Generator working group
    * Async iterator trait
    * Generator syntax
    * Await patterns
* Polish / tooling
* Beautiful diagram
    * draw.io!!!!

#### where we were

```rust
#[tokio::main]
async fn main() {
    for await b in bottles() {
        send_request(b).await;
    }
}

impl Stream for BottlesStream {
    fn foo(self: Pin<&mut Self>) {
        /* OMG I AM DEAD */
    }
}
```

```rust
Pattern = ...
        | await Pattern
        | ? Pattern

for await? x in fallible_io_thing() {
    
}

for? entry in dir.entry() {
    /* instead of let entry = entry? */
}

let await x = y; // equivalent to y.await;

let (await x, y) = foo(); // returns (impl Future, usize)

match foo() {
    (await x, y)
}

match foo() {
    Some(await x)
    None
}

match foo() {
    Some(await x) if something
    
}
```

```rust
for x.await? in y {

}
```

### tale of two dyns

#### goals

* supporting `async fn` calls;
* `impl Trait` in argument and return position, so long as `Trait` is dyn safe;
* supporting "by value" `self` methods;
* supporting cloning of trait objects[^caveat];
* supporting trait objects that are "partially dyn safe".

(what other things do we want for dyn that we are not trying to get now)

#### use cases

* embedded 1
    * library uses async fn in a trait and dyn trait
    * embedded user of library is able to invoke it without calling box to box futures
        * by e.g. inlining OR the enum solution?
* tight loop with reuse
    * reuse: invoke `foo.bar()` a lot for the same foo
    * something something uses `&mut` and avoids alloc
* regular code
    * uses box, it's easy, it can clone things
* async drop
    * I drop something
* embedded async drop
    * also in 
* tight loop up to N bytes
    * can handle this by making your own trait and doing the erased serde
    * question mark:
        * measure the size of futures?

#### "standard vtable format"

* `dyn Trait` it has a vtable that includes
    * all the regular fns like today
* for these cases...
    * argument position...
        * what we need
            * define how the caller will "package up" the argument in the way the vtable expects
            * how the vtable will "unpackage it" for the underlying fn
        * cases
            * Impl trait in argument position
                * vtable expects a dynx
                * dynx where the pointer type is
                    * &
                    * &mut
                    * or Box
                    * depending on our analysis of the trait
            * By value self in argument position
                * vtable takes a `*mut T`, effectively `&move`
                * iow, callee owns the `T` but not the memory the `T` resides in
                * vtable shim does `let x = *x` and then calls underlying fn with `x`
                    * perhaps some more efficient version
    * return position...
        * what we need
            * define how the callee will "package up" the argument in the way the vtable expects
            * how will the caller "unpackage it"
        * By value self in return position
            * vtable: always takes an out pointer
            * compiles `*outptr = underlying_fn()`
            * no normal caller :)
                * because `foo()` fails to type check if return type is `?Sized`
            * but there is an intrinsic that we add
                * `std::ptr::write` basically 
                * takes a `F: FnOnce() -> T` and a `*mut T` (or whatever) and calls the function, writing its result into the raw pointer
            * now we can write `Box<T: Clone>` impl to use this intrinsic
                * Eh! Problem `trait Clone: Sized` means we can't have `dyn Clone: Clone`, wtf do we do
        * Impl trait in return position
            * vtable returns a dynx
            * callee can use box
            * for the case of "inline wrappers" etc
                * we could customize the mapping
* for each of the above:

#### Impl trait in arg

```rust
fn foo(x: impl Len) {
    
    fn helper(x: &dyn Len) {
        ...
    }
    
    helper(&x)
}

```

you wrote

```rust
#[dynify]
fn foo(x: impl Len) {
    ...
}
```

```rust
fn foo(x: impl Len) {
    fn bar(x: dynx<'_> Len) {
        ...
    }
    bar(dynx!(x))
}
```

```rust
fn foo(x: impl Len) {
    foo::monomorphized(&x as &dyn Len)
}

impl fn#foo {
    fn monomorphized(x: impl Len) {
        
    }
    
    #[inline(always)]
    fn inline(x: impl Len) { .. }
}

foo(...);
foo::monomorphized(...);
```

```rust
#[salsa::jar]
struct Jar(
    foo,
    bar,
);

#[salsa::memoized]
fn foo(x: impl Len) {
    foo::monomorphized(&x as &dyn Len)
}

#[salsa::memoized]
fn bar(x: impl Len) {
    foo::monomorphized(&x as &dyn Len)
}

impl fn#foo {
    fn monomorphized(x: impl Len) {
        
    }
    
    #[inline(always)]
    fn inline(x: impl Len) { .. }
}

#### but

```rust
fn foo(x: impl AsyncIterator<next: Send> + Send)

// if it would be next::Output
fn foo(x: impl AsyncIterator<next(): Send> + Send)
fn foo(x: impl AsyncIterator<next(T1, T2): Send> + Send)
```

```rust
fn foo(x: Box<dyn AsyncIterator<next: Send> + Send>)
```


## 2021-12-13

### RPITIT

#### Bounding function types: What about `const` bounds?

```rust
trait Foo {
    fn foo(&self);
}

fn foo<T>(x: T)
where
    T: Foo,
    const T::foo,
    T::foo: const,
{}
```

things to think about

- in favor of the associated type being return
- but what doesn't work
    - can't impl traits or add assoc types for fn types
    - can't do const as a trait as above (Seems nice)
    - if you have `-> Vec<impl Trait>` or `-> (impl Trait, impl Trait)` , feels weird
        - whereas `::Output` is very clear about what it is

### dyn

Parts of the plan, in rough order (can stop at any point)

* Allow `&dyn Len: Len` and so on (see below)
* ABI hackery to make by value self work:
    * `-> Self` via out pointer
    * Allow `self` via "in pointer" and some stuff
* `impl Trait` in argument and return position: subject to **vtable strategy** (can be "always `dynX`") and **caller strategy**
    * caller strategy could be something like `dynX<Box>`
        * TODO: outline ways we could do this now, maybe with newtypes
* Allow strategies to choose arbitrary pointer types by abstracting with `dynX`
* Allow "slicing" traits with `dynX &Trait`
* Make `dynX` the newer, easier `dyn`

#### `&dyn Len: Len`

We can get pretty far with these, I think

(may require opt-in)

```rust
trait Len {
    fn len(&self) -> usize;
}

// Generated
impl<P, T> Len for P
where
    P: Deref<Target = T>,
    T: Len + ?Sized,
{
    fn len(&self) -> usize {
        Deref::deref(self).len()
    }
}
```

[playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=aa35f5729c35cd68dd81fe4be83e9276)

```rust
trait Iterator {
    type Item;
    fn next(&mut self) -> Option<Item>;
}

// Generated
impl<P, T> Iterator for P
where
    P: DerefMut<Target = T>,
    T: Iterator + ?Sized,
{
    fn len(&mut self) -> Option<Item> {
        T::next(&mut *self)
     
}
```

#### `DerefOwn`

* Allows moving out of a smart pointer
    * Including partial moves
* But requires more steps than Deref/DerefMut

```rust
trait DerefOwn: DerefMut {
    // This type manages the allocation, but does not
    // own the contents after a deref_own.
    type Residual;

    // Safety: The returned residual must outlive
    // the returned OwnedRef.
    // This will be enforced by the compiler.
    unsafe fn deref_own(self) -> (Self::Residual, OwnedRef<'static, Self::Target>);

    fn into_inner(self) -> Self::Target where Self: Sized, Self::Target: Sized {
        let x = self;
        deref_own!(x);
        x.into_inner()
    }
}
```

[playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=376974034ee30ed479b5e2315942b1ad)

## 2021-12-09

* RPITIT implementation
    * `'static` hack for lifetimes inherited from parent
    * We need to move these desugarings to something you would actually write
    * In particular, I'm concerned about `where T: Foo<'a>` when `'a` does not appear in the bounds -- when we use `'static`, that becomes `T: Foo<'static>'`, but that is not true
    * Desugared type alias has a conceptually different set of generics from the function; we should just copy them

### New RFC

* You can write `fn foo() -> impl Trait` in traits and in impls
    * it desugars to 
            * `type foo<...>: Trait` in a trait
        * `type foo<...> = impl Trait` in an impl
* You can write `fn foo() -> type` in an impl
    * but do you have to write `type foo = type` too?
    * if defined using impl trait in the trait, add it?
    * what happens if you put `type foo = impl Trait` and `fn foo() -> type`?
        * impl has to match signature from *outside* the defining scope
* how many lifetime parameters does the associated type get?
    * specifically for async fn, change the desugaring to add an extra fn parameter `'x` which is 
* introduce shorthand for `T::foo` where `foo` is a GAT
    * expands to `for<'a> T::foo<'a>`

```rust
trait Foo {
    fn foo(&self) -> impl Debug;
}

// Error: signature of `foo` is -> impl Debug not -> ()
impl Foo for () {
    type foo = impl Debug;
    fn foo(&self) -> () {
        ()
    }
}

// Error: two definitions of `foo`
impl Foo for () {
    type foo = ();
    fn foo(&self) -> impl Debug{
        ()
    }
}

// OK: Not refined
impl Foo for () {
    fn foo(&self) -> impl Debug{
        ()
    }
}

// OK: Refines to `()`
impl Foo for () {
    type foo = ();
    fn foo(&self) -> () {
        ()
    }
}

// OK: Refines to `()`
impl Foo for () {
    type foo = ();
    fn foo(&self) -> Self::foo {
        ()
    }
}

fn bar() {
    let x: <() as Foo>::foo = ...;
    //     ^^^^^^^^^^^^^^^^
    let x: _ = <() as Foo>::foo();
    //     ^ ??
}
```

```rust
trait Foo {
    type bar<'x>;
    fn bar<'a, 'b, 'c>(x: &'a u32, y: &'b u32) -> Self::bar<'c>
    where 'a: 'c, 'b: 'c;
}

impl Foo for () {
    type bar<'x>
    fn bar<'a, 'b, 'c>(...) -> Self::bar<'c>
    where 'a: 'c, 'b: 'c
    //    ^^^^^^^^^^^^^^ early bound (b/c 'c appears in where clauses)
    {}
}
```

```rust
fn foo<T: Foo>() where <T as Foo>::bar: Send {}
```

### Dyn

* [dyn trait design outline](https://hackmd.io/ZgcyvcklRba50m53pg3wkA)
* supporting clone for `Box<dyn Clone>`
    * extend `Clone` with an unsafe method
        * `unsafe fn clone_to_raw(&self, *mut ())`
    * extend `impl<T: Clone> Clone for Box<T>` to be
        * `impl<T: Clone + ?Sized> Clone for Box<T>`
        * you call `clone_to_raw`
    * another way to think about this
        * in the vtable for a `-> Self` fn, we put a fn that expects a `*mut Self` and "does the right thing"
        * need some intrinsic to call it
* Rc's copy-on-write methods e.g. `Rc::make_mut`
    * could make that work for `T: ?Sized`

```rust
struct DynX<trait B> {
    x: *mut dyn B
}
```

* if you want to support `-> impl Trait` with dynamic dispatch
    * you want to return a `DynX<Trait>`
    * in other words:
        * "some pointer to something that implements Trait"
        * "and has a vtable slot for how to drop that pointer"
* vtable interface:
    * in procedural macro, there wasn't one vtable interface
        * it was defined by this erased trait that carried the methods we wanted

### The dyner design

Introduce a `DynX<Trait>` type into the standard library:

* by some magic it holds a `*mut Trait` and knows how to drop itself

The vtable for an impl of a trait:

* If method has `-> impl Trait`, vtable expects to return a `DynX<Trait>`
    * each impl will require some "glue" to take the actual return value and make it a `DynX<Trait>`
    * for example, if it returns some future type `F`
        * that may need to be `Box::pin`'d to get a pointer `Pin<Box<F>>`
        * and then we attach the vtable to get a `DynX<Future>`
    * at the point where we generate the vtable for a given type:
        * there is a point in compilation where we are coercing from a known type to a dyn type
        * and that is where we do whatever adaptation we have to do
        * how do we determine that adaptation?
            * for now just assume there is an oracle
                * `Oracle(Trait) = adaptation`
    * somehow can be overriden on a per-impl basis
        * some fixed set of strategies you can pick from
* If method has a `impl Trait` argument, table expects a `DynX<Trait>` as well
    * as above, there is some glue, but this glue has to be the same for all instances of the trait
    * has to be customized per trait or perhaps some "wrapper" type
    * we could probably do some kind of `&move` thing
        * so long as trait doesn't have a `'static` bound
* If method returns `-> Self`, we .. do something like we descirbed earlier so that you can invoke this with a custom return pointer
    * the vtable has a method takes an explicit `*mut Self`
        * the vtable can do whatever ABI needs to make this work
    * need an intrinsic to call a fn whose return type is `?Sized` and you supply the pointer where the result goes
        * at monomorphization time, if return type is sized, this is just a regular call (`std::ptr::write(...)`)
        * if it is unsized (e.g., dyn) we invoke the vtable method
        * we do the right for `[T]` whtaever that is (memcpy?)

Are the idea of `&Trait` bounds important?

You write `dyn trait` on your trait and we enforce:

* it will add `impl<T> Trait for &T` and friends (not really needed, because we are passing a dynx now)
* you only use `impl Trait` with other dyn trait traits
* niko wants this for soundness

```rust=
trait MyTrait {
    fn adapt(
        &self, 
        x: impl(Box::pin) FnOnce(),
    ) -> impl Iterator<Item = u32>;
}

impl MyTrait for MyType {
    fn adapt(
        &self, 
        x: impl FnOnce(),
    ) -> impl(Box::pin) Iterator<Item = u32>; 
}
```

* individual impls can't "fail" to produce a vtable
    * would be a post-monomorphization failure
    * but they could "panic" in 


## 2021-12-06

tmandry `with` blog post draft: https://hackmd.io/LkzoeLaaQV2MMh512WSG7A?view

https://github.com/nikomatsakis/dyner/blob/main/src/dynerx.rs

### what is the "built in" story

* you will create a `dyner Trait` from some "pointer to T where T: Trait"
    * "pointer" is anything that supports `into_raw` and `from_raw`
    * e.g. could be `Box<T>` or `Rc<T>` or `&T` or `&mut T`
    * `dyner Trait: Sized`
    * `dyner Trait: Trait`
* but wait: for `Rc<T>` or `T`, you can only get `&self`
    * for `&mut T`, can only get `&self` or `&mut self`
    * for some traits, that's okay
    * so `&'a T` can become a `dyner Debug + 'a`
    * but for other traits, not so ok
    * but a `&'a T` cannot be made into a `dyner Iterator`
        * so what do we do?
* answer: introduce `&Trait` and `&mut Trait` bounds
    * intuitively these are either "views" on to Trait that select a subset of methods
    * or perhaps they are equivalent to `Deref<Target: Trait>` and `DerefMut<Target: Trait>`
    * but in any case you can make a `dyner &Iterator` from `&T`
* whichever way:
    * `dyner &Iterator: Deref<Target = dyner Iterator>`
* observation: `&dynx Debug` has "double indirection"
    * if you have an `&impl Debug`, and you want to use it in dyn form *without* double indirection
        * you could do `dyner Debug + Copy` (for this case)

impl/dynx symmetry:

```rust
fn foo(x: impl Debug) { }
// you can do `foo(22)` or `foo(&22)`

fn bar(x: dynx Debug) { }
// would like if you could do `bar(22)` or `bar(&22)`
//                             ^^^^^^^ but this requires some kind of "auto-ref"
```

observation:

each trait has a "natural pointer type"

* if only `&` or `*const`, then `&`
* if only `&mut` or `*mut`, then `&mut`
* else `Box`

```rust
fn foo(x: &impl Debug + ?Sized) {
    bar(x)
}

fn bar<T: Debug>(x: &T) { ... }

```

Questions:

* How do you create a `dyner`? Coercion? Is there an explicit form?
* If the answer is coercion, what can you create a `dyner` from:
    * from the pointer? (most explicit, need to have this option)
    * from the pointee? (requires auto-ref of some kind)
    * maybe sometimes one, sometimes the other?

If we limit ourselves to pointer, then, if you start with this code:

```rust
fn foo(x: impl Debug) { ... }
foo(22)
```

and you change `foo` to use `dyner`, you start to get errors:

```rust
fn foo(x: dyner Debug) { ... }
foo(22) // ERROR
```

arguably that is the wrong code, and what you wanted is

```rust
fn foo(x: impl Debug) {
    bar(&x)
    fn bar(x: dynx Debug) { ... }
}
foo(22) // ERROR
```

maybe we just want to make that more syntactically pleasant.

Niko's conclusions:

* Trying to make a super smart coercion will be a leaky abstraction and wind up both unsatisfying and confusing
* We need another mechanism to avoid monomorphization costs (e.g., dyn type parameters)
* We should have coercions *from* a pointer
    * we might want an explicit form like `expr.dyner`, plausibly that could do auto-ref though

Challenge is that we sort of want a few constructors. Function of both the trait and the pointer.

| (pointer) | Trait has &self | Trait has &mut self | Other |
| ---       | ---             | ---                 | ---   |
| `Box`     | `Trait`         | `Trait`             | `Trait` |
| `&T`      | `Trait`       | `&Trait`            | `&Trait` |
| `Rc<T>`   | `Trait`         | `&Trait`            | `&Trait` |
| `&mut T`  | `Trait`       | `Trait`             | `&mut Trait` |

The set of traits that the pointer must implement depends on the `Bounds` in `dyner Bounds`:

* Must always implement `IntoRaw` (a new trait afawk)
* If `Bounds` includes has an element with a `self: &Self` method:
    * must implement `Deref`
* If `Bounds` includes has an element with a `self: &mut Self` method:
    * must implement `DerefMut`
* If `Bounds` includes has an element with a `self` method:
    * must implement `IntoInner` (a new trait afawk)
        * or `DerefMove`
* If `Bounds` includes has an element with a `Box<Self>` method:
    * must be `Box<?>`
* If `Bounds` includes has an element with `Pin<&Self>` method:
    * must implement `Pinned` (where `Pinned` is an unsafe trait implemented by `Pin<P>`)
    * must implement `Deref`
* If `Bounds` includes has an element with `Pin<&mut Self>` method:
    * must implement `Pinned` (where `Pinned` is an unsafe trait implemented by `Pin<P>`)
    * must implement `DerefMut`
* If `Bounds` includes has an element with `Pin<Box<Self>>` method:
    * must implement `Pinned` (where `Pinned` is an unsafe trait implemented by `Pin<P>`)
    * must implement `DerefMut`
    * must be `Pin<Box<?>>`



less is more design:

* `dyn trait Trait`
    * automatically provides the `impl Trait for &dyn Trait` impls
    * automatically provides the `impl Trait for &mut dyn Trait` impls
    * automatically provides the `impl Trait for Box<Trait>` impls
    * errors if Trait is not dyn safe
* Question:
    * how does it handle `-> impl Trait`?
        * Answer: Trait must also be `dyn` 
        * the associated type for `dyn Trait` is hardcoded to `Box<Trait>`
        * generates the vtable shim; we know that `Box<Trait>: Trait` because `dyn trait` guaranteed that
    * how does it handle `impl Trait` in argument position
        * Answer: Trait must also be dyn
        * can invoke with `&x`/`&mut`/`Box::new` of the parameter depending:
            * if the trait has only borrowing methods and does not require `'static`, can use `&` or `&mut`
        * else must use `Box`
    * what about `-> Self`? (notably `Clone`)
        * uses `Box`
    * final methods can be handled and have no restrictions
        * or even defaulted -- we just say that the default is what gets invoked
            * probably with some opt-in
            * replaces `where Self: Sized`

### niko noodles post meeting

* challenging cases
    * impl trait in APIT:
        * in general case need something like `Box`
        * how to make this "no-std compatible"
            * what type does the thing in the vtable expect?
        * something like the dyner version would be good
            * it has a `*mut dyn Trait` and a vtable extension that lets it be dropped
    * what about `-> Self`?
        * we want to return the same type we got in -- well, probably?
        * so if you have `Box<dyn Trait>` you want `Box<dyn Trait>` afterwards?
            * is that true? I often have `&T` and I invoke clone to get `T`
            * maybe with `&dyn Trait` I want `Box<dyn Trait>`
            * then conceivably implement Clone for `&dyn Trait` where `Trait: Clone` that returns `Box<dyn Trait>`
                * vtable would include a wrapper that 

## 2021-12-02

https://dyner.netlify.app/faq#does-dyner-have-a-theme-song

[with clause post](https://hackmd.io/LkzoeLaaQV2MMh512WSG7A?view)

### Built-in `dyner`

What is dyner...

* you make a type `DynFoo` that represents a particular "configuration" of dynamic dispatch
    * how to "box" `-> impl Trait` 
    * how to "box" the dyn value itself (if you do box it)
    * this type encapsulates the pointer + the pointee (so it is sized)
        * i,e., you don't do `Box<DynFoo>`, you just do `DynFoo` (or `&DynFoo` etc)
        * if you make a `DynFoo` from an `&impl Foo` you get a `Ref<DynFoo>`, which only supports `Deref` trait
            * side note: can prob get rid of that "bit twiddling" to track whether to free
* maybe in the future
    * which functions to "devirtualize"
    * instead of `where Self: Sized`, making a 'default' that runs 
* ergonomic easy path
    * possible other paths


```rust
dyn trait Foo {
    
}
```

```rust
dyn<Box> Foo
&dyn<Box> Foo
```

```rust
trait SomeTrait {
    fn link(self: Rc<Self>);
}

x: Rc<dyn SomeTrait>
x.link();


x: exists<R: SomeTrait> Rc<Rc<R>>

x: dyn<R: SomeTrait> Rc<Rc<R>>
fn foo<dyn T: SomeTrait>(x: &T, y: &T) {
    ....
    
}
```

---

let's use virtual

```rust
virtual trait Foo {
    
}

let x: virtual Foo = Box::new(some_foo);
let x = DynFoo::boxed(some_foo);
let x = virtual Foo::boxed(some_foo);

let x = virtual some_foo;


fn foo(x: virtual FnMut<Item = u32>) {}
```

today I write:

```rust
foo(|| ...)
fn foo(x: impl FnMut<Item = u32>) {}
```

to make it dynamic today I have to add `&mut` both places

```rust
foo(&mut || ...)
fn foo(x: &mut dyn FnMut<Item = u32>) {}
```

this would be nicer..

```rust
foo(|| ...) // compiler autorefs
// foo(&mut || ...)
// relying on:
// &mut dyn FnMut<Item = u32>: dyn FnMut<Item = u32>
fn foo(x: dyn FnMut<Item = u32> + '_) {}
```


```rust
fn foo(x: impl Debug) {}

```

https://pol.is/report/r2p6mj8dka3kpsnymv6aj

https://rust-lang.github.io/async-fundamentals-initiative/evaluation/challenges/dyn_traits.html
https://rust-lang.github.io/async-fundamentals-initiative/design-discussions/dyn_trait.html
https://rust-lang.github.io/async-fundamentals-initiative/design-discussions/dyn_async_trait.html

```rust
fn foo(x: impl FnMut<Item = u32>) {
    fn bar(x: &mut dyn FnMut<Item = u32>) { ... }
    bar(&mux x)
}
```

```rust
trait VtableFoo {
    fn vtable_foo(&mut self, x: DynRef<Item = u32>)
}

fn foo(&mut self, x: impl FnMut<Item = u32>) {
    self.vtable_foo(DynRef::from_mut_ref(&mut x))
}
```

```rust
dynX Foo
dynX<Rc> Foo
&dynX<Rc> Foo

// Defaults to allocating a Box; erases that knowledge
let x: dynX Future = /*box*/ some_async_fn();

// Defaults to <unknown container>
fn foo(x: dynX Future) {}

// Can also support
fn foo(x: dynX<Rc> Future) {}
```

`dyn &Future`
`dyn &mut Future`

`&dyn &Future` => `&dyn Future`
`&mut dyn &mut Future` => `&mut dyn Future`

`dyn &Future: Deref<Target = dyn Future>`

```rust
trait MyCollection {
    fn push(&mut self);
    fn len(&self);
}
fn foo<T: &MyCollection>(t: T) { }
fn foo<T: Deref<Target: MyCollection>>(t: T) { }

dyn &mut Iterator<Item = u32>
X = dyn DerefMut<Target: Iterator<Item = u32>>
&mut X => &mut dyn Iterator<Item = u32>> // deref coercion
```

## 2021-11-29

### stakeholder meeting retrospective?

* publish minutes "as is" / or try to write a summary
* email people that we plan to, give them a chance to raise any concerns
* defer: write a blog post that tells about the lessons and experience and summarizes
* https://hackmd.io/SwLsaDDmTSCLKQfE2DYk1Q

### RPITIT / async fn

How Niko is thinking about things

#### Step -1

What is missing from the impl trait in traits RFC?

```rust
trait Iterator {
    fn next(&mut self) -> Option<impl Sized>;
}
```


```rust
trait AsyncTrigger {
    fn start(&mut self) -> impl Future<Output = ()>;
}
```

```rust=
fn foo(x: impl AsyncTrigger)
where
    /* typeof x.start() */: Send, // <-- thing we want conceptually
    x::start: Send, // <-- shorthand
    for<'me> x::start<'me>: Send, // <-- longhand
{
    tokio::task::spawn(async move {
        x.start().await;
        // type of x.start() is some "impl future"
    });
}
```

#### Step 0

```rust
trait LendingIterator {
    type Item<'me>;
    
    fn next(&mut self) -> Self::Item<'me>;
}

impl<T> LendingIterator for Vec<T> {
    type Item<'me> = &'me T;
    // Error: not WF, `T: 'me` not known
    
    fn next(&mut self) -> Self::Item<'me> {
        self.iter()
    }
}
```

#### Step 1

```rust
trait LendingIterator {
    type Item<'me>
    where
        Self: 'me;
    
    fn next(&mut self) -> Self::Item<'me>;
    //      ^^^^^^^^^ implied bound of Self: 'me
}

impl<T> LendingIterator for Vec<T> {
    // compiles!
    type Item<'me> = &'me T
    where
        Vec<T>: 'me; // => T: 'me
    
    fn next(&mut self) -> Self::Item<'me> {
        self.iter()
    }
}
```

Status for GATs as of a few weeks ago:

* Algorithm for finding which where clauses ought to be included by default on GATs
* Current compromise:
    * force user to write where clauses explicitly
    * thus backwards compatible to make them appear by default OR make them not required

#### Step 2

```rust
trait LendingIterator {
    fn next(&mut self) -> impl Sized + '_;
    // desugars to:
    fn next(&mut self) -> Self::next<'_>;
    type next<'me>: Sized
    where // <-- talk about impl details here
        Self: 'me;
}
```

#### Step 3

```rust
trait LendingIterable {
    fn iter(&self) -> impl LendingIterator + '_;
}
```

But what if you want to know "what kind of item is going to be producted by the iterable that iter returns"... `IntoIterator` has `IntoIter` (type of iterator that is produced) and `Item` (type of item yielded by that iterator).

```rust
trait Iterable {
    final type Item<'me> =
        Self::iter<'me>::Item; // <-- error!

    fn iter(&self) -> impl Iterator + '_;
}

impl<A: Debug> Iterable for A {
    default type Item<'me> = ...;
    // if there is no specializing impl, then ITem will be this

    fn iter(&self) -> impl Iterator + '_;
}
```

#### Step 3.5

```rust
trait Iterable {
    final type Item<'me> = Self::iter<'me>::Item
    where
        Self: 'me;

    fn iter(&self) -> impl Iterator + '_;
    // implied bound: where Self: '_
}
```

#### Step 4

```rust
struct MustBeEq<T: Eq>(T);

// no error:
type Foo<T> = MustBeEq<T>;

// use it with something that is not Eq, I get an error at that point
```

```rust
struct MustBeEq<T: Eq>(T);

type Foo<T> where T: Ord = MustBeEq<T>;
//          ^^^^^^^^^^^^ unenforced
```

```rust
struct MustBeEq<T: Eq>(T);

type Foo<T> = MustBeEq<T>
where // <-- default
    MustBeEq<T>: OK;

// in libcore
trait OK { }
impl<T: ?Sized> OK for T { }
```

#### Step 5

```rust
trait Iterable {
    final type Item<'me> =
        Self::iter<'me>::Item;
    // compiler default:
    // where Self::iter<'me>::Item: OK
    // from which we can infer that Self: 'me

    fn iter(&self) -> impl Iterator + '_;
    
    // desugars to:
    fn iter(&self) -> Self::iter<'_>;
    type iter<'me>
    where
        &'me Self: OK; // => Self: 'me
}
```

What does this need?

* OK trait and our handling of WF would have to be tweaked
    * callee gets to assume its where clauses are well formed
    * not just its input arguments
    * tweak to "implied bounds"

```rust=
struct Foo<'me, T>(&'me T);
// inferred where clausE: where T: 'me

fn bar<'me, T>()
where
    Foo<'me, T>: OK
{
    // Today: error unless you add
    // where T: 'me
    //
    // Under Niko's proposal above: compiles fine
}
```

```rust
struct Foo<T: Eq> { }

// T: Eq => Foo<T> WF
//
// can I say the other direction?
//
// Foo<T> WF => T: Eq -- semver question
//
// but we would add the `=>` direction for outlives bounds, so that's a little wacky
```


#### foo

```rust=
fn foo<'a, T>(x: &'a T) -> impl Sized
where 
    T: Foo<'a>,
{
    
}

type Foo<'a, T> = impl Sized
where
    T: Foo<'a> // <-- weird;
// T: Foo<'static> // not true

fn foo<'a, T>(x: &'a T) -> Foo<'static, T>
where 
    T: Foo<'a>,
{
       
}

type Foo<'a, 'b, T> = impl Sized
where
    T: Foo<'a> // <-- weird;
// T: Foo<'static> // not true

fn foo<'a, T, 'b>(....) -> Foo<'static, 'b, T>
where 
    T: Foo<'a>,
{
    
}

```

###

```rust
trait LendingIterable {
    final type Item<'me> = Self::iter<'me>::Item
    /* implied: where Self::iter<'me>::Item: OK */
    ;

    fn iter(&self) -> impl LendingIterator + '_;
}
```

### existential lifetimes in impl trait

https://github.com/rust-lang/rust/issues/60670

### with types?

## 2021-11-19

### Stakeholders retrospective

* Call on people to give feedback
* Got a little sidetracked
* Need to talk about overall roadmap

## 2021-11-18

* [ ] Stakeholder meeting
* [ ] "dyn adaptation"
    * [ ] Can we make it implementable by macros outside the crate defining the trait?
    * [ ] What's the ergonomic path?
* [ ] `dynX` idea
    * [ ] What are the problems facing it?
* [ ] Idea for conditional bounds (Niko)
* [ ] How to help
* [Stakeholder explainer](https://hackmd.io/_fnM79SsSIWo86bdZXuNPw)
* `DynTrait<'lt>`
    * before: this always encloses a `Box`
    * after:
        * can initialize from box
        * or from &T or &mut T
        * and can avoid giving access to the methods that would not be accessible in the latter case

---

```rust
trait Foo {
    fn foo(&self) -> impl Debug;
}

trait Foo {
    type foo<'me>: Debug;
    fn foo(&self) -> Self::foo<'me>;
}

impl Foo for Bar {
    // because foo was declared in trait as RPITIT...
    fn foo(&self) -> XXX { }

    // ...it becomes...
    type foo<'me> = XXX;
    fn foo(&self) -> Self::foo<'me> { 
        // so you don't have to put impl trait if you don't want to
    }
}

fn method<T>()
where 
    T: Foo<foo: Send>,

    for<'a> T: Foo<foo<'a>: Send>

    T: Foo<foo<..>: Send>,
    //        ^^^^

```

* `'_` in where clause == forall
* turbofish rules for these GATs:
    * if there are APIT, cannot use turbofish
    * if you do not supply any lifetimes: use `'_` for all of them
        * if you *do*, there cannot be any late-bound lifetimes (else error) (this rule isn't actually needed for this idea)
        * else must supply all
    * must supply all type parameters
* for other GATs:

```rust
struct Foo<T: FnOnce()> { }

struct Foo<T: FnOnce(), const F: T> { }
impl<T: FnOnce(), const F: T> Foo<T, F> { 
    fn foo() {
        F();
    }
}

```

```rust
const fn<T: FnOnce(C), C>(f: T) -> fn(C) {
    assert!(sizeof::<T>() == 0);
    
}

const fn<T: FnOnce(C)>(const f: T) -> fn(C) {
    assert!(sizeof::<T>() == 0);
    
}

// "Non-stateful closure"

```

---

```rust
struct Ref<T> { t: T }

impl<T> Deref for Ref<T> {
    type Target = T;
    
    fn deref(&self) -> &T {
        &self.t
    }
}

struct RefMut<T> { t: T }

impl<T> Deref for RefMut<T> {
    type Target = T;
    
    fn deref(&self) -> &T {
        &self.t
    }
}

impl<T> DerefMut for RefMut<T> {
    fn deref_mut(&mut self) -> &T {
        &mut self.t
    }
}



```

```rust
type DynTraitRef<'lt> = Shared<DynTrait<'lt>>;

struct Custom<T> { t: T }

impl<T> Deref for Custom<'lt, T>
where
    T: Deref,
T::Target: 
{
    type Target = DynTrait<'lt>;
    
    fn deref(&self) -> &T {
        &*self.t
    }
}

impl DynTrait<'lt> {
    fn boxed<T>(x: T) -> DynTrait<'lt>
    where 
        T: Trait,
    {
        
    }
    
    fn from_ref<T>(x: &'lt T) -> Ref<DynTrait<'lt>>
    where 
        T: Trait,
    {
        
    }
    
    fn from_mut<T>(x: &'lt mut T) -> Mut<DynTrait<'lt>>
    where 
        T: Trait,
    {
        
    }
        
    fn from_mut<T>(x: T) -> Custom<DynTrait<'lt>>
    where 
        T: Deref,
        T::Target: Trait,
    {
        
    }
}
```

```rust
fn foo(x: &DynTrait<'_>) {
    
}

fn bar() {
    let y = ...;
    let x = DynTrait::from_shared(&y);
    foo(&x)
}
```

## 2021-11-15

* [Niko wrote some stuff](https://hackmd.io/78T_K20VQVe-vBxBWWuUlw)
    * Bridging [poll traits](https://docs.rs/hyper/0.14.14/hyper/body/trait.HttpBody.html) with async traits
        * Hard with multiple poll functions
            * Something something resume args ((with?))
        * Easier with single poll: inline async fn

## 2021-11-11

* [x] WIP updates
    * [x] dyn conversation
    * [x] implementation
* [ ] Stakeholder meeting
* [ ] "dyn adaptation"
    * [ ] Can we make it implementable by macros outside the crate defining the trait?
    * [ ] What's the ergonomic path?
* [ ] `dynX` idea
    * [ ] What are the problems facing it?
* [ ] Idea for conditional bounds (Niko)
* [ ] How to help

### Action items

* (Niko by Monday) Turn outline into something for the repo
* (Spastorino by Monday) "code"
* Future: Writing up issues for things like inline etc.

### Notes

* Going to pursue RPITIT to start
* what we will ship
    * stage 0
        * stable compiler supports impl Trait and GATs
    * stage 1
        * stable compiler can compile async fn in traits
            * no dyn 
        * crate published by rust-lang available on crates.io for dynamic dispatch
            * dyner 
            * `#[dyner] trait Foo { }` creates `DynFoo::new(...)` that implements `Foo`
            * supports:
                * traits with async fn
                * traits with `-> impl Trait` if `dyner` is used on Trait (maybe?)
                * traits with `(impl Trait)` if `dyner` is used on Trait (maybe?)
            * includes:
                * "Dyner"-ified versions of libstd traits like AsyncRead and friends
    * stage 2
        * libstd will add stable versions of 
            * AsyncRead, AsyncWrite, AsyncStream
            * (domain of the portability initiative)
    * stage 3 and beyond
        * based on experience with dyner we figure out an official dyn story
            * "Someone is coding with dyner... :musical_note::musical_note::musical_note:"
        * async closures
        * other fun stuff
* what can you do with this
    * Grace and Alan are hacking on their async rust service at SomeBigCo
        * Traits they use internally just use async fn
        * If they want dyn dispatch, they use `#[dyner]`
        * To talk about read/write traits, they use the dyn-ified versions from dyner
    * Barbara has a cool idea for an arena-ified alternative (or one that caches .. or something .. )
        * she forks dyner and writes her own punny named crate that embodies this pattern
        * she submits the link to the repo
        * it's collected and in the doc and when the async fundamentals team gets to stage 3 they use a variation of this brilliant idea in their final design 
    * Grace is working on her embedded project, she can use the stable async fn support to get static dispatch
        * She has a plan for dyn dispatch and experiments and publishes her own procedural macro crate which the async fundamentals group adds to their repo
        * Opens a PR with an experimental of version of embedded-dyner 
    * Hyper publishes a "hyper-dyner" crate that includes dyn-ified versions of its traits
        * or maybe Sean Monstar opts for a feature flag. Whatever dude. You do you.
* Niko's wild and crazy Rust 2024 fantasies
    * "feature previously known as dyn" => low-level primitive, maybe it is even replaced with existential types or something
    * observation: if dyn is a low-level primitive, "dyn-safe"  is silly, you want to expose as many capabilities as you can
        * "low-level"? not the thing most code reaches for first
        * sort of like `for<'a>`
    * you have `dyn trait Foo` that exposes some "pretty useful" version (probably with Box) that is ergonomic and good enough most of the time
        * ability to declare your own variations in other crates (with traits you didn't define and don't have to copy and paste) and use those
    * you have "existential types" (which replace today's `dyn`) as the "fancy version" to build those nicer, ergonomic versions with
        * and for scala refugees
* "inline async at impl site" ??
    * don't recurse!!!
        * add in a panic at runtime
        * 


## 2021-11-07

* [x] WIP updates
    * [x] RFC
    * [x] Stakeholders
    * [x] Implementation
* [x] Syntax for named fn types
* [ ] "dyn adaptation"
    * [ ] Can we make it implementable by macros outside the crate defining the trait?
    * [ ] What's the ergonomic path?
* [ ] `dynX` idea
    * [ ] What are the problems facing it?
* [ ] Idea for conditional bounds (Niko)
* [ ] How to help

### WIP updates

#### RFC

* Should we talk to cramertj?
    * Responded in [comments](https://github.com/rust-lang/rfcs/pull/3185#issuecomment-961499403)

#### Stakeholders

Looking at https://alternativeto.net/software/doodle/

#### Implementation

Can use `type $ = impl Foo;` to implement RPITIT, and then implement `async fn` desugaring in terms of that.

### Syntax for named fn types

* It would be nice to have explicit and anonymous generics be equivalent
    * but it doesn't seem to work very nicely
    * you need `decltype` and then `declval`
* We can make anonymous generics late-bound
* Hopefully explicit generics too, eventually
    * Still need to support `let f = foo::<i32>;`
    * Requires making some "wrapper" to hold the specified generics. i.e. type currying

## 2021-11-03

* [x] WIP updates
    * [x] RFC
    * [x] Implementation
* [ ] Niko's dyn idea
* [ ] Syntax for named fn types

### RFC conversation

[cramertj comment](https://github.com/rust-lang/rfcs/pull/3185#issuecomment-956430290)

Will we be able to do this in the future?

Can libs assume it will be possible in the future? Backcompat hazard...

```rust
trait Foo {
    async fn bar(&self);
}

// Right now RFC doesn't allow this...
impl Foo for u32 {
    fn bar(&self) -> impl Future<Output = ()> + '_ {}
    // only `async fn bar() {}` allowed
}

// But if I'm writing a lib..
```

### Implementation

```rust
async fn foo() {}

// Lowers to...
type Foo = impl Future<Output = ()>;

trait Foo {
    async fn bar(&self);
}

// Lowers to...
trait Foo {
    type __Foo<'a> = impl Future<Output = ()> + 'a;
    fn bar(&self) -> __Foo<'a>;
}

// But in the future we want...
// (almost exactly what standalone functions do)
trait Foo {
    fn bar(&self) -> impl Future<Output = ()> + '_;
}
// ..which then lowers to something like the above
```

Maybe faster to implement RPITIT first.

https://github.com/rust-lang/impl-trait-initiative
https://rust-lang.github.io/impl-trait-initiative/updates/2021-oct.html#type-alias-impl-trait-stabilization

```rust
trait Foo {
    fn foo() -> impl Send;
}
```


## 2021-11-01

* [x] New sprint goals review
* [x] Stakeholder agenda
* [ ] Niko's dyn idea
    * and another idea for conditional bounds
* [ ] Syntax for named fn types?

### Sprint goals review

* Get [MVP RFC](https://github.com/rust-lang/rfcs/pull/3185) to FCP
    * Niko [fcp merged](https://github.com/rust-lang/rfcs/pull/3185#issuecomment-956370267)
* Implementation:
    * Santiago has done a basic desugaring but tests are failing still

### Stakeholder meeting agenda

* 90 minutes
* Who will present? tmandry mostly
* Outline
    * Format
        * We'll talk
        * You ask questions whenever they come up, no need to wait
    * Async vision doc overview (keep it short)
        * The grand [roadmap]:
            * Scoped APIs for reliable concurrency
            * Common interop traits are just "async fn"
        * Our part today:
            * The very first step
        * Other active initiatives:
            * Generators async and otherwise
            * Tooling (tokio console, crashdumps)
            * Polish (the bug! backtraces!)
    * What does async fn in traits mean
        * Async fn: fn that returns impl Future
        * impl Trait in traits desugars to associated type
    * Send bounds and named return types
        * The syntax we expect
        * Where would this be needed
        * Feedback point:
            * What have your experiences been with Send bounds in generic code so far?
            * Do your codebases frequently use `spawn` or other parallel operations?
    * This is the MVP:
        * You can write async fn in traits
        * It works in static cases
        * Writing the Send bounds for futures is kinda painful but possible
    * Major capability missing: dynamic dispatch
        * Associated type prevents dynamic dispatch
        * Also, boxing
        * Not sure the most general fix here
        * Current approach:
            * procedural macro
        * Feedback point:
            * Where do you use dyn dispatch vs static in your codebases?
    * Shortcomings of MVP and future work
        * Dynamic dispatch in the lang
        * Shorthands or better ways to put send bounds
            * Multiplication bounds (!)
            * Globs
    * Implementation status
        * Core features are on path to stabilization
        * Async sugar is on its way to nightly
        * We'll let you know when it's time to port your code to try this out and give instructions for how to do it

[roadmap]: https://rust-lang.github.io/wg-async-foundations/vision/roadmap.html

### Niko's crazy dyn idea

* `dynx Trait`
    * "A pointer to `Trait` that implements `Trait`"
* whereas:
    * `dyn Trait` = `exists T. Implemented(T: Trait)`
* whereas:
    * `dynX Trait` = `exists T. sizeof(T) == sizeof(usize) && Implemented(T: Trait)`
* probably want to combine this with:
    * `impl<T, U> Trait for T where T: Deref<Target = U>, U: Trait` -- automatic for traits with only `&self` methods
    * `impl<T, U> Trait for T where T: DerefMut<Target = U>, U: Trait` -- automatic for traits with only `&mut self` and `&self` methods
    * `impl<T: Trait> Trait for Box<T>` -- always true
    * just imagine this is true for now
* what does this mean?
    * `Box<dyn Iterator>` == `dynx Iterator + 'static`
    * `Rc<dyn Debug>` == `dynx Debug + Clone + 'static`
    * `&'a dyn Debug` == `dynx Debug + Copy + 'a`
* for any dyn safe trait `Trait`

```rust
trait MyTrait {
    fn foo(x: impl OtherTrait) {
        // we know that `x` does not escape this function
        // without being tracked, because `x` could be a `&T`
    }
}
```

we want `MyTrait` to be dyn safe, but we can't put `foo` into the vtable because it requires monomorphization

because we know that `&T: OtherTrait` where `T: OtherTrait`, however, we could put this in the vtable:

```rust
fn vtable_foo(x: dynx Trait) {
    ...
}
```

and then in the `impl MyTrait for dynx MyTrait` impl use this function:

```rust
impl MYTrait for dynx MyTrait {
    fn foo(x: impl Trait) {
        vtable_foo(&x)
    }
}
```

Of course, this doesn't really require `dynx`. You could do same transformation with `dyn`, if you know that `&T: Trait` where `T: Trait`. You put this in the vtable:

```rust
fn vtable_foo(x: &dyn Trait) {
    ...
}
```

and this in the `impl MyTrait for dyn MyTrait`:

```rust

// shim user calls:
fn foo(x: impl Trait) {
    vtable_foo(&x)
}
```

### Step back and just talk about dyn and erased serde

```rust
trait MyTrait {
    fn foo(x: impl OtherTrait);
}

trait OtherTrait {
    fn bar(&self);
}

impl<T> OtherTrait for &T
where
    T: ?Sized + OtherTrait
{
    fn bar(&self) {
        T::bar(self)
    }
}
```

What could we do?

We could write:

```rust
trait DynMyTrait {
    fn dyn_foo(x: &dyn OtherTrait);
}

impl<T> DynMyTrait for T
where
    T: MyTrait,
{
    fn dyn_foo(&self, x: &dyn OtherTrait) {
        <T::foo as FnOnce(&dyn OtherTrait)>::call_once(self, x)
        //                ^^^^^^^^^^^^^^^
        //                type given to the impl trait
    }
}
```

The final "knot" is that one can implement

```rust
impl MyTrait for dyn DynMyTrait {
    fn foo(&self, x: impl OtherTrait) {
        let x = &x as &dyn OtherTrait;
        //            ^^^^^^^^^^^^^^^
        //            Possible because `OtherTrait` is dyn safe
        self.dyn_foo(x)
    }

}
```

Using all these pieces, if you have a `&T: MyTrait`, you can ...

* convert the `&T` to `&dyn DynMyTrait`
* convert the `&'a dyn DynMyTrait` to `impl MyTrait + 'a`
    * not that useful
* 

## 2021-10-27

* Syntax for named function types
    * https://hackmd.io/WQUfas2jSiaeIv6EBPgtew
* Plan around dynamic dispatch
* Stakeholder meeting, agenda plan?
* Next steps for dyn
* `with` clauses?

### Late-bound and arguments

```rust
trait Foo {
    async fn bar(&self, x: impl Debug);
}
```

```rust
fn my_helper<T: Foo>
where
    T::*::Output: Send
    <T as Foo>::fn::bar::Output: Send
    for<D: Debug + Send> { <<T as Foo>::fn::bar as FnOnce(&T, D)>::Output: Send }
    <<T as Foo>::fn::bar as FnOnce(&T, impl Debug + Send)>::Output: Send,
```

```rust
trait Foo {
    async fn bar(&self);
}
```

```rust
fn my_helper<T: Foo>
where
    T::fn::bar::Output: Send, // <-- what you write
    //        ^^ look ma, no args -- works for elided lifetime parameters
    for<'me> { <<T as Foo>::fn::bar as FnOnce(&'me T)>::Output: Send }, // <-- what it means
    //                                       ^^^^^^^^ defaulting the arguments
    //                                                from the signature of `fn bar`
    //                                                and substituting the `Self` or
    //                                                other trait parameters

where
    T::Item // <T as Iterator>::Item -- T is the Self type
```

### Stakeholder meeting

* Explain the plan
    * Concept of MVP
    * MVP
    * Dyn async fn in traits
        * using a proc macro to generate a wrapper struct
    * Naming of output types
* Feedback in meeting
    * How often do you think you will want dyn vs static dispatch?
* Feedback after trying it
    * Naming output types and 

### Dyn async fn

High-level idea

```rust
trait Foo {
    fn stuff(&self);
}

// Compiler generates:
impl Foo for dyn Foo {
    fn stuff(&self) {
        self.vtable[0](self);
    }
}

trait Bar {
    async fn stuff(&self);
}

impl Bar for dyn Bar {
    // Post-desugaring
    type __stuff_output<'a> = Pin<Box<dyn Future<Output = ()>>> + 'a;
    fn stuff<'a>(&self) -> Pin<Box<dyn Future<Output = ()>>> + 'a {}
}

impl dyn Bar {
    fn stuff(&self, arena: &Arena<'a>) -> Pin<ArenaBox<'a, dyn Future<Output = ()>>> {}
}
```

### 

## 2021-10-25

```rust
// Warning: For reasons we are in the midst of explaining,
// this version of the trait will not compile.
trait Iterable {
    type Item<'me>;

    type Iterator<'me>: Iterator<Item = Self::Item<'me>>;

    fn iter<'a>(&'a self) -> Self::Iterator<'a>;
}

impl Iterable for Vec<T> {
    type Item<'me> = &'me T; // <-- Error: don't know that T: 'me
    type Iterator<'me> = std::vec::Iter<'me, T>;
    fn iter(&self) -> Self::Iterator<'_> { self.iter() }
}
```

What we want:

```rust
trait Iterable {
    type Item<'me>
    where
        Self: 'me;

    type Iterator<'me>: Iterator<Item = Self::Item<'me>>
    where
        Self: 'me;

    fn iter<'a>(&'a self) -> Self::Iterator<'a>;
}

impl Iterable for Vec<T> {
    type Item<'me> = &'me T where Self: 'me;
        // Self = Vec<T>
        // Vec<T>: 'me => T: 'me
    type Iterator<'me> = std::vec::Iter<'me, T> where Self: 'me;
    fn iter(&self) -> Self::Iterator<'_> { self.iter() }
}
```


Current status of GATs, doing an analysis of the trait def'n to find missing where clauses:

* For every GAT `G` in a trait definition with generic parameters `X0...Xn` from the trait and `Xn..Xm` on the GAT... (e.g., `Item` or `Iterable`, in the case of `Iterable`, with generic parameters `[Self]` from the trait and `['me]` from the GAT)
    * If for every method in the trait... (e.g., `iter`, in the case of `Iterable`)
        * When the method signature (argument types, return type, where clauses) references `G` like `<P0 as Trait<P1..Pn>>::G<Pn..Pm>` (e.g., `<Self as Iterable>::Iterator<'a>`, in the `iter` method, where `P0 = Self` and `P1` = `'a`)...
            * we can show that `Pi: Pj` for two parameters on the reference to `G` (e.g., `Self: 'a`, in our example)
                * then the GAT must have `Xi: Xj` in its where clause list in the trait (e.g., `Self: 'me`).

How we desugar RPIT today:

```rust
fn foo<'a>(x: &'a u32) -> impl Debug + 'a {
}

fn foo<'a, T>(x: &'a u32) -> Foo<T, 'a> {
    type Foo<T, 'me> = impl Debug + 'me; // scope of this is the enclosing fn
}
```

```rust
trait Iterable {
    fn iter(&self) -> impl Iterator + '_;

    // "desugared"
    fn iter(&self) -> impl Iterator + '_
        type Iter<'me>; // inherits the where clauses
}
```

### Tests

Things to add

- Generic async fn
    - with where clauses req'd to type check
- Elided lifetimes in async fn

### Impl notes

* `async fn` -> return position `impl Trait` -> associated type
* Be careful about elided lifetimes
* May or may not be easier to start with a nameable associated type
    * `gensym`?
    * Ask petrochenkov how to do it
    * Check what argument position impl trait does

## 2021-10-20

* [RFC Draft](https://hackmd.io/ZKb-lh8iRN66RiuYjALZrA)
    * tmandry to upload to repo
    * and open a PR to rust-lang/rfcs
* Milestones
    * Santiago to make a list of tests for desired behavior
        * read the RFC
    * Tyler/Niko review list of tests and add anything that seems to be missing
    * Santiago to write tests for desired behavior
    * Naive desugaring for async fn in traits/impls
        * literally introduce an associated type with the same name as the method but with `Output` appended?
    * Niko to open RFC for `-> impl Trait` in traits
    * Implement `-> impl Trait` in traits properly
    * Implement the dyn procedural macro "stuff"
* Ergo-dyn milestones (dyno)
    * Open issues on the repository
    * Encourage people to do it
    * [find a new name](https://www.thefreedictionary.com/words-that-start-with-din)
        * dyner

### When would you want to use dyn anyway?

* Parser combinator library
    * every combinator returns `Box<dyn Parser>` or whatever
* In async, passing around a `dyn AsyncRead` or whatever
    * In sync, passing around a `dyn Read`
* Things you lose access to:
    * Associated constants
    * Static methods, constructors
* Kinds of traits:
    * Traits where all methods are `&self`; ideally `Trait` would be implemented for `&Trait`
    * Traits where all methods are `&mut self`
    * Traits where methods are `self`
    * In general, `Trait` should be implemented for `Box<Trait>`

* In general, `Trait` should be implemented for `Box<Trait>`
    * Properties of `Box` that we need?

Something Niko likes is that you can have an `&dyn Debug` and call it without forcing any allocation

```rust
fn bar() {
    debuglog(&22)
}

fn debuglog(x: &dyn Debug) {

}
```


```rust=
fn map<T>(x: impl Iterator<Item = T>) {}

fn main() {
    
}
```

Homework:

* Try to write up some example programs and the ergonomic nits that result


## 2021-10-18

* What does the MVP story look like?
    * You can write async fn in traits/impls but not dyn saf†e
    * You can't name the resulting future (until we get fn type syntax)
        * but you can make an explicit associated type if you so choose
    * There is a procedural macro available `#[ergo_dyn]` that a `DynTrait` struct that encapsulates a `Box<dyn Trait>` and supports async dispatch, impl trait in traits, and other nifty features

* If you could declare "cannot be overridden" defaults...

```rust
trait AsyncIter {
    final type NextFuture<'me> = <Self as AsyncIter>::next_future::Output;
    
    async fn next_future(&mut self) -> ...;
}
```

if you had that option, one could write a decorator to make it convenient

```rust
trait AsyncIter {
    #[return_type(NextFuture)]
    async fn next_future(&mut self) -> ...;
}
```

* What do we want feedback on from the stakeholders?
    * Do you need dyn? If so, what are the details of how you plan to use it?
    * Present two crates that let you easily swap back and forth
        * Can people land the one version?
        * What problems do they encounter?
    * After you try it:
        * Do you need Send bounds?
        * Can you measure performance impact?

* MVP timeline and requirements:
    * Nightly version
        * Test suite
        * Implement the sugar
        * Procedural macros
    * Stabilize TAIT -- EOY was my goal, but I'm not sure we're going to make it
    * Stabilize GAT

[Named function types](https://rust-lang.github.io/impl-trait-initiative/RFCs/named-function-types.html)
[impl trait in traits](https://rust-lang.github.io/impl-trait-initiative/RFCs/rpit-in-traits.html)

### Late-bound lifetimes

```rust
fn foo<T>(x: impl Iterator<Item = T>) {
    
}

fn bar<T>(x: impl Iterator<Item = u32>) {}

fn main() {
    let x: Foo<?, ?> = foo; // ERROR today
    foo(...);
    
}

struct MyStruct {
    f: foo<u32, x: vec::IntoIter<u32>> // conceptually
}
```

```rust
trait Foo {
    async fn bar<U>(&mut self);
}

// <T as Foo>::bar<u32>::Output
//
// desugared to...something like this...
//
// for<'a> <<T as Foo>::bar<'a, u32> as FnOnce>::Output
```

### Argument types

`Foo<..>` // means the fn type

let's call this U

`<U as FnOnce<(A1, A2)>>::Output`

```rust=
let x: FnDef[Foo]<?X, ?Y> = foo;

impl<'a, A2> FnOnce<(&'a mut Self, A2)> for FnDef[Foo]<&'a mut Self, A2> {
    type Output = SomeFutureType<'a>;
}
```

### Can we ... think of `impl Trait` as late-bound?

// given the fn foo from line 62 

```rust
struct MyStruct {
    field: foo<u32> // incomplete type
    
    // conceptually:
    //
    // for<T> { foo<u32, T> }
    //
    // Foo<u32> // FnDef just doesn't have a value here
}
```

Rule: You need to name all the named type parameters, the rest are all late bound.

- Already the case that elided lifetime parameters are always late bound.
- For `impl Trait`, when it's called we're just doing `FnOnce` trait selection with the concrete type of that argument. No need to have a different function type for each instantiation.

## 2021-10-13

### with

* `with(x: T)` is a where clause
* dyn trait
* bounded clauses
    * `in('a) { T: Trait }`
    * in the future, would be the default `in('_) { ... }`
    * "needs to be true independently of the scope I'm in "
        * `in('static) { T: Trait }`
    * `Implemented(T: Trait for 'a)`
    * other use cases:
        * [safer transmute](https://github.com/jswrenn/rfcs/blob/af9f3012de8a642a9fcaa2f2f334e68f682742ad/text/0000-safer-transmute.md)
        * crate-local impls (sort of)
            * maybe not a real use case
* implication types
    * `P => T`
    * `with(tokio: &mut TokioRuntime) => Box<dyn xxx>`
    * other use cases:
        * `for<'a, 'b> fn(&'a &'b u32, &'a u32, &'b u32)`
        * unsound because of https://github.com/rust-lang/rust/issues/25860
            * could upcast `for<'a, 'b> fn(&'static &'static u32, &'a u32, &'b u32)`
        * `for<'a, 'b> ('b: 'a => fn(&'a &'b u32, &'a u32, &'b u32))`
        * `for<'a, 'b where 'b: 'a> fn...`
* borrow checker integration
    * I think what happens is that when you prove a predicate you get back a set of in-scope variables that are required
        * much like today you get back lifetime bounds


```rust
struct Foo {

}

impl Foo {
    fn foo(&mut self)
    where
        with(f: &mut Foo)
    {
        // self != f
    }
}

fn main() {
    let mut f = Foo { };
    with(f: &mut f) {
         f.foo(); // Error!
    }


    let mut f = Foo { };
    let mut g = Foo { };
    with(f: &mut f) {
        let f1 = &mut f;
        g.foo(); // Error!
        drop(f1);
    }
}
```

* async live over yield question
    * are `with` live over await? interesting question

can express both patterns

```rust
// acts like a fn param
fn foo<'a>(...) -> impl Future + 'a
where in('a) { with(x: &mut Context) }
{
}

fn foo<'a>(...) -> impl with(x: &mut Context) => Future
{
}
```

* specialization

* specializing impls can't add with clauses

```rust
trait MyTrait { fn method(&self) { } }
impl<T> MyTrait for T { }

fn foo<A>(a: A) {
    MyTrait::method(&a)
}

impl<T> MyTrait for T
where
    with(cx: &mut Foo)
    {
    
    }

// in another crate

fn bar() {
    foo(); // do I consider `cx` borrowed or not?
}
```

* optional / defaulted with clauses
* providing something that is `Copy` (e.g. shared ref) means can be used multiple times

`Box<dyn Foo + 'a>`

`Box<dyn with(cx: &mut Context) => Foo>`

`trait WithContext = with(cx: &mutContext>`
`trait WithContext<predicate P> = with(cx: &mutContext> P`


* complicaiton:
    * how do you think about bounds on a struct type?
        * `struct Foo<T: Debug>`
        * what is the bound here?

### talking about dyn

```rust=
trait Foo { // would be nice if this were dyn safe
   fn foo(x: impl Iterator<Item = u32>) { 
   }
}

fn foo(x: &move dyn Iterator<Item = u32>) { }
```

## 2021-10-06

- What about threading local arena through?
    - This design shouldn't add more complications to that

```rust
impl<A: Allocator> Foo for dyn Foo
with(a: A) {
    ...
}


with(alloc: impl Allocator);
```

https://github.com/rust-lang/rfcs/pull/2492

```rust
impl<'a> Foo<'a> for String { .. }

impl Foo for String {
    fn method<'a>()
}
```

```rust
impl Context {
    fn stuff(&self) -> &Output;
}
```

```rust
// crate A:
trait SomeTrait { 
    fn method(&self);
}

// crate B:
struct Context { }

struct X;
impl SomeTrait for X
with<'a>(cx: &'a mut Context)
{
    fn method(&self)
    // can't write it here:
    // with(cx: &mut Context)
    {
    
    }

}
```

```rust
with(value: Type) {
    ... can use value ...
    foo();
}
```

```rust
with(cx: &mut Context)
with(cx2: &mut Context2)
```

```rust
with(cx: .., cx2: ...) {
    
}
```

## 2021-10-04

### Niko muses about dyn

```rust
trait Foo {
    fn method(&self) -> impl Iterator<Item = ...>;
}

impl Foo for Blah {
    fn method(&self) -> impl Iterator<Item = ...> {
        ... /* call the type of this X */
    }
}
```

* given an instance `x: X` (`let x = <Blah as Foo>::method`)
    * `x as fn(&Blah) -> XXX`
* trait `InstantiateFn<F> { ... }`
    * `x: InstantiateFn<fn(&Blah) -> XXX>`
        * Resolves to pointer to impl method
    * `x: InstantiateFn<fn(&Blah) -> Box<dyn Iterator<Item = ...>>`
        * Resolves to pointer to wrapper fn around impl method
* given this, you can write generic code that generates a vtable
    * has to run at compilation time: need const fn
* you can also write a `impl Foo for dyn Foo` that consumes the vtable

### Impl question

Parent of a HIR node?

https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html#method.find_parent_node

### Pieces

* MVP
* Ability to get type of a fn item
    * fallback syntax to name items
    * what about constants?
        * for now we should make them an error to leave space for future expansion
* Ability to construct dyn vtables and implement dyn manually
* (Maybe) trait aliases

```
MyTraitSend!(X) ==> X: Send + X::foo: Send
trait MyTraitSend =
    MyTrait + Send + 
    <Self as MyTrait>::foo: Send + 
    Bar: Send
    
X: MyTraitSend


trait Foo<T> where T: Ord =
    Bar where T: PartialOrd
    
impl SomeTrait for X {
    // Today:
    // What Niko always types
    type Foo<T>
    where
        T: Ord +
        T: Send +
        T: Blah
    = Bar;

    // What Niko always types
    type Foo<T> = Bar
    where
        T: Ord +
        T: Send +
        T: Blah;
}

trait Foo<T> = where T: PartialEq<Self>

trait Foo<T> = T: PartialEq<Self>

X: Foo<T> => T: PartialEq<X>

(): Foo<T> "write an arbitrary predicate with no self"
```

Next: Arenas

### Sprint items

* Stakeholders
    * Niko found 2 in AWS
    * 
* MVP RFC
    * needs work
    * create a hackmd and write it together
* Evaluation for the output type naming (niko will call it impl trait)
    * needs work
        * sort of belongs in the impl trait initiative
    * create a hackmd and write it together

```rust
trait Foo {
    async fn bar();
    async fn baz();
}
type AllFooFutures<T: Foo> =
    (<T as Foo>::bar::Output, <T as Foo>::baz::Output);

T: Foo + Send 
where AllFooFutures<T>: Send

where T: FooSend // trait alias for the above
```

## 2021-09-30

* Async stakeholders plan: [link](https://hackmd.io/y31gA3ElSu2DUdY6vUGs8A)
* Possible stakeholders
    * Web services: Niko has contacts in AWS
    * Embedded Rust: Dario
    * Web framework author: 
    * Web framework consumer: 
    * High-performance computing: glommio author
* Sourcing
    * Dario
    * Alice Rhyl
    * Glauber Costa (glommio)
    * farnz / Simon Farnsworth 
    * Android (BT?)
    * Fuchsia (BT?) - Marie
    * AWS people x 2 -- agreed
    * Yosh

---

* dyn for any trait
    * do not have to specify the associated types (ever)
    * maybe you can emit elide the other trait parameters
* but:
    * you can only directly use members that meet the safety criteria for your dyn type
        * they can't name associated types whose values you don't know
        * they can't reference the generics whose values you don't know (including Self), at least not in contravariant positions
* and then:
    * dyn trait Foo
        * implements the Foo for dyn Foo impl in a particular way
        * can give an error if that can't be done
        * and you can give hints on methods (maybe?) to configure it a bit
* another part:
    * what do we need to allow people to implement the dyn impl (unsafely) and what do we need (safely)
* goodies that extend what is dyn safe a little bit
    * mapping `impl Trait` return types (or associated types) for dyn safe traits to `Box<dyn>` and allocating
    * impl trait in argument position ===> pass dyn by value? maybe Boxed?

[impl trait in traits brainstorming doc](https://hackmd.io/IISsYc0fTGSSm2MiMqby4A)
 
```rust=
trait Foo {
    fn method(&self);
}

fn fun<T: Foo>(x: T) where T::method<'_>::Output: Clone {}
```
 
* for anonymous lifetimes, or if lifetimes are elided, always hrtb
    * the same rule for gats
    * probably `'_` should mean hrtb too

```rust
fn fun<T: Foo>(t: T)
where
    T: SomeTrait<'_>, // would be nice if this meant for<'x> T: SomeTrait<'x>

// Meaning 1
fn fun<T: Foo>(t: T)
where
    for<'a> T: SomeTrait<'a>, // would be nice if this meant for<'x> T: SomeTrait<'x>

// Meaning 2
fn fun<'a, T: Foo>(t: T)
where
    T: SomeTrait<'a>, 

// Meaning 3
fn fun<T: Foo>(t: T)
where
    T: SomeTrait<impl Trait>, // Today: error

fn fun<T: Foo>(t: T)
where
    for<U: Trait> T: SomeTrait<U>, // Today: error
```

Niko's argment:

* '_ and impl Trait both should "introduce name into binder" at the same depth in all "input" positions
    * in output positions, they "refer back" to a name from somewhere
        * `'_` refers to self lifetime
        * `-> impl Trait` returns to return type of body
* in where clauses:
    * you don't want to introduce a fresh name at the *item* level because it would be unconstrained
        * (this is less true for lifetimes for "reasons" but definitely true for types)
    * so you probably want a forall at the where clause level
        * exception: value of associated types


https://github.com/rust-lang/async-fundamentals-initiative/pull/3/files


```rust=
// Later we could experiement with, e.g.:
fn fun<T: Foo>(x: T) where T::*::Output: Send {}

fn main() {
    (1..3).collect::<Vec<i32>().map(<Foo as Bar>::method)
}
```

https://lang-team.rust-lang.org/design_notes/fn_type_trait_impls.html

## 2021-09-28

* https://rust-lang.github.io/async-fundamentals-initiative/evaluation.html
* MVP (niko to open a PR describing MVP on the repo):
    * Straightforward desugaring
        * async fn in trait desugars to an anonymous associated type that implements Future
        * async fn in impl
    * No dyn
    * Can only use async fn in impl if you had one in the trait
* Next steps:
    * [Something with dyn](https://rust-lang.github.io/async-fundamentals-initiative/evaluation/challenges/dyn_traits.html)
    * [Bounding futures](https://rust-lang.github.io/async-fundamentals-initiative/evaluation/challenges/bounding_futures.html)
    * Naming futures
        * associated type inference
        * typeof for fn types
        * "some other crazy stuff"

Regarding the last bullet in "MvP":

```rust
impl Iterator for Bar {
    fn next(&self) -> Option<u32> {
    //                       ^^^ "infers" that `type Item = u32`
        None
    }
}

trait AsyncThing {
    type Bar<'me>: Future<Output = ()> + 'me;
    fn do_it(&self) -> Self::Bar<'_>;
}

impl AsyncThing for Bar {
    fn do_it(&self) -> impl Future<Output = ()> {
    //                  ^^^^^^^^^^^^^^^^^^^^^^^ Self::Bar
    
    }
}

impl AsyncThing for Bar {
    async fn do_it(&self) {
    // infer that BAr = impl Future
    }
}
```

## 2021-09-23

Niko would like it if traits had to be declared dyn

```rust
dyn trait Foo {

}
```

Why?

* Implementation soundness reasons
* Transparency / semver
    * Don't accidentally make something not dyn safe
    * It's clearer to users that something is happening

Plausible route:

* You have to supply the dyn impl 
* `#[derive(dyn)]` to get the "default"
    * this would be an edition change, obviously

```rust
// 
trait Foo {
    async fn bar(&self);
}

impl Foo for dyn Foo {
    type Bar = Box<dyn Future<Output = ()>>;
    
    fn bar(&self) -> Box<dyn Future<Output = ()>> {
        vtable(self)[0](self)
    }
}

// "the vtable"
impl dyn Foo for T {
    fn bar(&self) {
        Box::new(T::bar(self))
        //       ^^^^^^ the actual impl you wrote
    }
}

impl Foo for T {
    fn bar(&self) {
        ...
    }
}
```

```rust
dyn trait Foo {
    // Might want the Box thing here
    fn bar(&self) -> impl Iterator<Item = u32>;
}

dyn trait Foo { // dyn Foo<Bar = ...>
    type Bar: Debug;
    fn bar(&self) -> Self::Bar;
}

dyn trait Foo {
    // Might want the Box thing here
    fn bar(&self, input: impl Iterator<Item = u32>) -> impl Iterator<Item = u32>;
}
```

Underlying mechanisms:

* Trait methods that return `impl Trait`:
    * Only works for traits that `impl Trait for Box<dyn Trait>`
    * Vtable shim that boxes and creates `Box<dyn Trait>`
* Controlling the kind of box (we have no idea how to do this yet, apart from `dyn(Box)`)


Why not return unsized values?

* Because futures have to have statically known size

Why not determine it from vtable?

```rust
let (tx, rx) = channel();
let f: impl Future<Output = u32> = async move {
    let fut: dyn Future<Output = u32> = rx.receive().await;
    fut.await
};

// How big is `f`?
```

```rust
let (tx, rx) = channel();
let f: impl Future<Output = u32> = async move {
    let fut: dyn Future<Output = u32> = rx.receive().await.box;
    //                                                     ^^^ something that lets this work
    fut.await
};

// How big is `f`?
```

### Defining the underlying mechanisms

```rust
struct Obj<trait T> {
    exists type E: T;
    data: Box<E>,
    vtable: vtable<E: T>,
}

impl<trait T> Obj<T> {
    fn new<E: T>(e: E) -> Obj<T> {
        let vtable = magic_get_vtable::<E>(&e);
        let data = Box::new(e);
        Obj { data, vtable }
    }
    
    fn *(*) from T {
        ... some code that extracts from vtable... somehow ...
    }
}

impl as<Obj<trait T>> for T { ... allocates a box ... }
```

```rust
let x = Obj::new(some_value);
```


### What Niko wants

* dyn is always 1 word
    * so dyn Trait is Sized
* `x as dyn Trait` requires that `x` is a pointer (in practice)
* `box struct Foo` means that `Foo` is actually `Box<Foo>` (covenience)
* `dyn trait Foo` declare that a trait is "dyn-able"
* `dyn Trait: Trait` works kind of universally
* `fn foo(x: dyn Trait)` -- you could pass in a `&Foo` where `Foo: Trait` (which has size one word)
    * `fn foo(x: &dyn Trait)` is a pointer to pointer, not much we can do about that


## 2021-09-22

MVP

```rust
trait Foo {
    async fn method(&self);
}

impl Foo for u32 {
    async fn method(&self);
}

// desugars to

trait Foo {
    type _Foo /* unnameable */: Future<Output = ()>;
    fn method(&self) -> Self::_Foo;
}

impl Foo for u32 {
    type _Foo /* unnameable */ = impl Future<Output = ()>;
    fn method(&self) -> Self::_Foo {
        async move { ... }
    }
}
```

* dyn??

### What works


```rust
async fn my_function<T: Foo>(x: T) {
    x.method().await;
}

#[async]
fn main() {
    tokio::spawn(move async {
        my_function(22);
    });
}

impl Foo for i32 {
    async fn method(&self) {
        tokio::println!("Hello, world {}", self).await
    }
}
```


### What doesn't

```rust
fn my_function<T: Foo>(x: T) {
    tokio::spawn(move async {
        // cannot write this because `T::_Foo` is not known to be Send
        x.foo();
    });
}
```


```rust
fn foo(x: &dyn Foo) {
//         ^^^^^^^ did not provide a value for `_Foo`

}
```

### Implementation work required

* Extend the parser
* Lower the thing in HIR lowering
* Improve error messages in some cases
* Make these traits not dyn-safe for now

### Prepare a test suite

* Prepare a test suite

https://rust-lang.github.io/async-fundamentals-initiative/

https://github.com/rust-lang/async-fundamentals-initiative

https://rust-lang.github.io/async-fundamentals-initiative/evaluation/challenges/dyn_traits.html

## Dyn traits

Normal "default impl" for dyn generated by the compiler

```rust
trait Foo {
    type Bar;

    fn method(&self);
}

impl<B> Foo for dyn Foo<Bar = B> {
    type Bar = B;

    fn method(&self) {
        let f: fn(&Self) = get_method_from_vtable(self)
        //  ^ literally the same function 
        f(self)
    }
}


impl Foo for u32 {
    fn method(self: &u32) { XXX }
}

// compiles to:
//
// Vtable_Foo = [ ..., `<u32 as Foo>::method` ]
// fn `<u32 as Foo>::method`(self: &u32) { XXX  }
```

For async fn:

```rust
trait Foo {
    async fn method(&self);
}

impl<B> Foo for dyn Foo {
    type Bar = Box<dyn Future<Output = ()>>;

    fn method(&self) -> Box<dyn Future<Output = ()>> {
            
    }
}

// compiles to:
//
// Vtable_Foo = [ ..., `<u32 as Foo>::methodX`]
// fn `<u32 as Foo>::method`(self: &u32) { XXX  }
// fn `<u32 as Foo>::methodX`(self: &u32) -> Box<dyn> { Box::new(TheFuture)  }
```

### Auto traits and resulting futures

Basically we just need multiple impls:

```rust
trait Foo {
    async fn method(&self);
}

impl<B> Foo for dyn Foo {
    type Bar = Box<dyn Future<Output = ()>>;

    fn method(&self) -> Box<dyn Future<Output = ()>> {
            
    }
}

impl<B> Foo for dyn Foo * Send {
    type Bar = Box<dyn Future<Output = ()> + Send>;

    fn method(&self) -> Box<dyn Future<Output = ()>> {
            
    }
}

// compiles to:
//
// Vtable_Foo = [ ..., `<u32 as Foo>::methodX`]
// fn `<u32 as Foo>::method`(self: &u32) { XXX  }
// fn `<u32 as Foo>::methodX`(self: &u32) -> Box<dyn> { Box::new(TheFuture)  }
```

### Avoiding hard-coding box


"if you give me a box, I give you a box"

but is this what we really want? Then dyn foo doesn't quite work the same

```rust
trait Foo {
    async fn method(&self);
}

impl<B> Foo for Box<dyn Foo> {
    type Bar = Box<dyn Future<Output = ()>>;

    fn method(&self) -> Box<dyn Future<Output = ()>> {
            
    }
}

impl<B> Foo for dyn Foo * Send {
    type Bar = Box<dyn Future<Output = ()> + Send>;

    fn method(&self) -> Box<dyn Future<Output = ()>> {
            
    }
}

// compiles to:
//
// Vtable_Foo = [ ..., `<u32 as Foo>::methodX`]
// fn `<u32 as Foo>::method`(self: &u32) { XXX  }
// fn `<u32 as Foo>::methodX`(self: &u32) -> Box<dyn> { Box::new(TheFuture)  }
```

```rust
fn foo<T>(x: Box<T>) where T: ?Sized + Foo { ... }
```

"I tell you what I want, what I really really want"

```rust
#[async_dyn_type(SmallBox<4, _>)]
trait Foo {

}
```


```rust
trait Foo {
    async fn method(&self);
}

impl<B> Foo for dyn(Box) Foo {
    type Bar = Box<dyn Future<Output = ()>>;

    fn method(&self) -> Box<dyn Future<Output = ()>> {
            
    }
}
```

### Embedded workloads

* not depending on box
* inline
* smallbox 
* maybe you have some allocator object?

### Opening up dyn for Foo for anyone

rust```