For me coming from Rust, this just seems way overly complicated to me. Rust's async doesn't even need a heap to work: https://lights0123.com/blog/2020/07/25/async-await-for-avr-w...
C++ coroutines do support allocators [1], so it is not a huge issue, but it does complicate the design further.
[1] the compiler is also allowed to elide the allocation, but a) it is not clear how this is different from the normal allocation elision allowance that compilers already had, and b) it is a fragile optimization.
There are already proposals to improve on the design, but we will have to see if they work out.