================ @@ -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(); + } + +An awaiter type may provide both annotated and non-annotated overloads of +``await_suspend()``, as long as each invocation of an annotated overload has a +corresponding ``await_suspend_destroy(Promise&)`` overload. + +Instead of calling the annotated ``await_suspend()``, the coroutine calls +``await_suspend_destroy(Promise&)`` and immediately destroys the coroutine +``await_suspend_destroy()`` must return ``void`` (Note: if desired, it +would be straightforward to also support the "symmetric transfer" +``std::coroutine_handle`` return type.) + +This optimization improves code speed and size for "short-circuiting" +coroutines — those that use coroutine syntax **exclusively** for early returns +and control flow rather than true asynchronous operations. + +Specifically, a short-circuiting awaiter is one that either proceeds +immediately (``await_ready()`` returns ``true``, skipping to +``await_resume()``) or terminates the coroutine execution. + +Then, a short-circuiting coroutine is one where **all** the awaiters (including +``co_await``, ``co_yield``, initial, and final suspend) are short-circuiting. + +The short-circuiting coroutine concept introduced above has close analogs in +other languages: + +- Rust has ``Result<T>`` and a ``?`` operator to unpack it, while + ``folly::result<T>`` is a C++ short-circuiting coroutine, within which + ``co_await or_unwind(someResult())`` acts just like ``someResult()?``. + +- Haskell has ``Maybe`` & ``Error`` monads. A short-circuiting ``co_await`` + loosely corresponds to the monadic ``>>=``, whereas a short-circuiting + ``std::optional`` coro would be an exact analog of ``Maybe``. ---------------- ChuanqiXu9 wrote:
I feel the doc for attributes is not a good place for these ideas. But I don't have a strong idea now. We can always update it later. 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