================ @@ -9363,6 +9363,119 @@ Example: }]; } +def CoroAwaitSuspendDestroyDoc : Documentation { + let Category = DocCatFunction; + let Content = [{ + +The ``[[clang::coro_await_suspend_destroy]]`` attribute applies to an +``await_suspend(std::coroutine_handle<Promise>)`` member function of a +coroutine awaiter. When applied, suspensions into the awaiter use an optimized +call path that bypasses standard suspend intrinsics, and immediately destroys +the suspending coro. + +Each annotated ``await_suspend`` member must contain a compatibility stub: + +.. code-block:: c++ + + [[clang::coro_await_suspend_destroy]] + void await_suspend(std::coroutine_handle<Promise> handle) { + await_suspend_destroy(handle.promise()); + handle.destroy(); + } ---------------- snarkmaster wrote:
Here is what is **the same** in both the old and the new version: - The compiler does not constrain the implementation of `await_suspend()`. - Normal users SHOULD implement a portability `await_suspend()` with those two lines -- it should be very uncommon not to do this. - Given the attribute, the emitted code only uses `await_suspend_destroy()` -- the stub does not run. The only thing that **differs** is that in the new version, we test-call `await_suspend()` to check for the attribute, so as a result: - `await_suspend()` must be at least declared, and have the same return type as `await_suspend_destroy()` IMO, having to declare both functions is a good tradeoff in exchange for the outcome is that an awaiter can use overloads to select whether or not it is short-circuiting in a particular promise. If you need me to elaborate **why** it's useful to have the overload selection, I can write more. --- As far as the comment, I will make the requirements more explicit in the doc, and replace "must" by "should". https://github.com/llvm/llvm-project/pull/152623 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits