Problem with GATs in an async trait after updating nightly Rust

Yeah, the only Wrapper created is 'b, :face_with_raised_eyebrow: so I also don't see why it needs to be Send for every lifetime. When I don't use a HRTB, but just demand <S as Source>::Wrapper<'b>, I get:

   Compiling playground v0.0.1 (/playground)
error: implementation of `Send` is not general enough
  --> src/main.rs:48:5
   |
48 | /     {
49 | |         let result = source.retrieve().await;
50 | |         some_async_task().await;
51 | |         result
52 | |     }
   | |_____^ implementation of `Send` is not general enough
   |
   = note: `<S as Source>::Wrapper<'0>` must implement `Send`, for any lifetime `'0`...
   = note: ...but `Send` is actually implemented for the type `<S as Source>::Wrapper<'b>`

error: could not compile `playground` due to previous error

If you remember where, let me know…

I will try to boil it down further. Not sure if it will happen without the macro-expansion, but maybe it does. I think I somehow need to replace async-trait's demand for Send by creating an async block with explicit type annotation or something like that (have done that for other examples I presented here).

Where exactly should I give that feedback best? The original issue is closed. I'm not very familiar with the exact proceedings, so if you can give me a hint where it's best to post it, I'd be thankful.

As for PR #89970, the direct impact wasn't too bad. PR #89970 did not really break anything. The problem with getting rid of the Send bound in the associated type (Source::Wrapper<'_> in my example) by adding a bound to the method (User::process in my example) that uses that associated type wasn't possible before the update either, but error messages were different, I think. If I remember right, I got pages of errors with long lists of… I don't remember what it was, but it was worse :sweat_smile:.

However, PR #89970 resulted in the bloaty syntax of my code to de-sugar async trait methods to get bloated a bit more :grinning_face_with_smiling_eyes::

pub trait Binary: Sized {
    type Dump<'a, 'b, W>: Future<Output = io::Result<()>> + Send
    where
        Self: 'a,
        W: 'b;
    fn dump<'a, 'b, W>(&'a self, writer: &'b mut W) -> Self::Dump<'a, 'b, W>
    where
        W: AsyncWrite + Unpin + Send;

    type Restore<'a, R>: Future<Output = io::Result<Self>> + Send
    where
        R: 'a;
    fn restore<'a, R>(reader: &'a mut R) -> Self::Restore<'a, R>
    where
        R: AsyncRead + Unpin + Send;
}

Luckily I can use a shorter notation without where at least for implementation of that Binary trait:

impl Binary for SomeStruct {
    type Dump<'a, 'b, W: 'b> = impl Future<Output = io::Result<()>> + Send;
    fn dump<'a, 'b, W>(&'a self, writer: &'b mut W) -> Self::Dump<'a, 'b, W>
    where
        W: AsyncWrite + Unpin + Send,
    {
        async move {
            /* … */
        }
    }
    type Restore<'a, R: 'a> = impl Future<Output = io::Result<Self>> + Send;
    fn restore<'a, R>(reader: &'a mut R) -> Self::Restore<'a, R>
    where
        R: AsyncRead + Unpin + Send,
    {
        async move {
            /* … */
        }
    }
}

It was ugly beforehand and still is ugly, so not a big issue. What bugs me most is the extra indentation due to the async move, which is unrelated to PR #89970 and was necessary before.

Side note: If I get it right, such (ugly) desugaring might be necessary for a while when async trait methods shall guarantee to return a Sendable future. See also limitations/workarounds in the MVP of the async fn fundamentals initiative. But I'm happy that there is progress in getting support for async trait methods!