From da40fc2706beb08b79139e564c884bcd6e6fc8ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Neboj=C5=A1a=20Cvetkovi=C4=87?= Date: Mon, 1 Jun 2026 16:28:40 +0100 Subject: [PATCH] exec(at_coroutine_exit): inherit start scheduler only when available The cleanup task's await_suspend unconditionally read get_start_scheduler from the parent promise's env, which made at_coroutine_exit impossible to use with tasks whose context doesn't model affinity (e.g. basic_task>): the call failed to compile. Gate the read on a requires-expression. When the parent's env doesn't expose get_start_scheduler, the cleanup task's __scheduler_ keeps its default value (inline_scheduler{}), which is what callers of an inline task would expect anyway. Affinity-bearing tasks (default_task_context) continue to inherit the parent's scheduler as before. --- include/exec/at_coroutine_exit.hpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/exec/at_coroutine_exit.hpp b/include/exec/at_coroutine_exit.hpp index 9a872f67f..e8b80b07a 100644 --- a/include/exec/at_coroutine_exit.hpp +++ b/include/exec/at_coroutine_exit.hpp @@ -157,8 +157,11 @@ namespace experimental::execution template <__has_continuation _Promise> auto await_suspend(__std::coroutine_handle<_Promise> __parent) -> bool { - // Set the cleanup task's scheduler to the parent coroutine's scheduler. - __coro_.promise().__scheduler_ = get_start_scheduler(get_env(__parent.promise())); + // Set the cleanup task's scheduler to the parent coroutine's scheduler, if present + if constexpr (requires { get_start_scheduler(get_env(__parent.promise())); }) + { + __coro_.promise().__scheduler_ = get_start_scheduler(get_env(__parent.promise())); + } // This causes the parent to be resumed after the cleanup action is performed. __coro_.promise().set_continuation(__parent.promise().continuation()); // This causes the parent to invoke the cleanup action when it performs the final