================
@@ -9270,6 +9270,93 @@ Example:
 }];
 }
 
+def CoroAwaitSuspendDestroyDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+
+The ``[[clang::coro_await_suspend_destroy]]`` attribute may be applied to a C++
+coroutine awaiter type.  When this attribute is present, the awaiter must
+implement ``void await_suspend_destroy(Promise&)``.  If ``await_ready()``
+returns ``false`` at a suspension point, ``await_suspend_destroy`` will be
+called directly, bypassing the ``await_suspend(std::coroutine_handle<...>)``
+method.  The coroutine being suspended will then be immediately destroyed.
+
+Logically, the new behavior is equivalent to this standard code:
+
+.. code-block:: c++
+
+  void await_suspend_destroy(YourPromise&) { ... }
+  void await_suspend(auto handle) {
+    await_suspend_destroy(handle.promise());
+    handle.destroy();
+  }
+
+This enables `await_suspend_destroy()` usage in portable awaiters — just add a
+stub ``await_suspend()`` as above.  Without ``coro_await_suspend_destroy``
+support, the awaiter will behave nearly identically, with the only difference
+being heap allocation instead of stack allocation for the coroutine frame.
+
+This attribute exists to optimize short-circuiting coroutines—coroutines whose
+suspend points are either (i) trivial (like ``std::suspend_never``), or (ii)
+short-circuiting (like a ``co_await`` that can be expressed in regular control
----------------
snarkmaster wrote:

Next update, I will start with something like the below. WDYT? I'm happy to 
linkify the various concepts if that's not frowned upon.

A short-circuiting coroutine is one where every `co_await` or `co_yield` either 
immediately produces a value, or exits the coroutine. In other words, they use 
coroutine syntax to concisely branch out of a synchronous function. Here are 
analogies to other languages:

- Rust has `Result<T>` and a `?` operator to unpack it, while 
`folly::result<T>` is a C++ short-circuiting coroutine, where `co_await` acts 
just like `?`.

- Haskell has `Maybe` & `Error` monads. A short-circuiting `co_await` loosely 
corresponds to the monadic `>>=`, whereas a short-circuiting `std::optional` 
would be an exact analog of `Maybe`.

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

Reply via email to