Async generator dual return type?

I just read about async generators and I'm confused. Why the heck would they yield one type many times, then do a final return with a different type? Shouldn't a generator just yield values of one type, or nothing at all?

What did you read? Some things that were called generators in rust were recently renamed to coroutines, so that might explain some things. Also not sure exactly what you mean by async generator.

I saw mention of it here: A universal lowering strategy for control effects in Rust - Abubalay

Then I googled and found this:

Yeah, that crate was made before the rename. If it was made today, they might rename AsyncGenerator to Coroutine or AsyncCoroutine.

This is just an issue of naming. There's no technical reason why a coroutine can't yield and return different types, so the crate allows it, even though it's probably not used much. Note that AsyncGen only implements Stream when it returns nothing.

You could imagine a generator that yields items of type Vec<u8> and when it completes, it returns the type Result<(), Error>. This would represent a steam of byte chunks they can terminate normally or with an error.

Currently we simulate this by using the item type Result<Vec<u8>>, with the stream always terminating after it yields an error. But this way, we encode in the type system that errors terminate the stream, and don't have to deal with cases where more data comes after the error.

Forgot to mention: Rust having a type for nothing (the zero-tuple) means you can always replace a generic with nothing, and it's the same as hardcoding an empty return.