Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions test/stdexec/queries/test_get_completion_behavior.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,41 @@ static_assert(cb::__may_be_asynchronous(cb::__asynchronous_affine));
static_assert(cb::__may_be_asynchronous(cb::__asynchronous | cb::__inline_completion));
static_assert(cb::__may_be_asynchronous(cb::__asynchronous_affine | cb::__asynchronous));
static_assert(cb::__may_be_asynchronous(cb::__asynchronous_affine | cb::__inline_completion));

// read_env completes in its start(), so get_scheduler() may claim inline completion
// for set_value_t -- but only for the tags it can actually send. Advertising
// inline completion for a tag it never sends made a task that co_awaits
// get_scheduler() | let_value(schedule) look like it completed inline, and the
// awaiter then kept the composed operation state in its own stack frame while a
// nested schedule() operation was still queued (see #2098).
using __get_scheduler_sndr_t = decltype(ex::get_scheduler());
using __get_scheduler_attrs_t = ex::env_of_t<__get_scheduler_sndr_t>;

static_assert(ex::__completes_inline<ex::set_value_t, __get_scheduler_attrs_t>);
static_assert(!ex::__completes_inline<ex::set_error_t, __get_scheduler_attrs_t>);
static_assert(!ex::__completes_inline<ex::set_stopped_t, __get_scheduler_attrs_t>);

// The same expression from #2098, composed: the successor sender schedule(sch) may
// complete asynchronously, so the composition must not be treated as completing
// inline.
inline constexpr auto __reschedule = [](auto __sch)
{
return ex::schedule(__sch);
};
inline constexpr auto __reschedule_on_current = ex::get_scheduler() | ex::let_value(__reschedule);

// For co_await, a sender is treated as completing inline only if _all_ of its
// completion tags complete inline (see __as_awaitable::__completes_inline). The
// nested schedule(sch) does not complete inline for set_stopped_t, so the
// composition must not be classified as completing inline. We check the stopped
// tag directly; the value tag of the composition _does_ complete inline
// (let_value forwards read_env's inline value completion), so that is pinned
// here as well. This check uses only names exported by the stdexec module: the
// __as_awaitable namespace is not part of the module's public surface, and
// naming it fails the modular and nvc++ configurations.
static_assert(ex::__completes_inline<ex::set_value_t,
ex::env_of_t<decltype(__reschedule_on_current)>,
ex::env<>>);
static_assert(!ex::__completes_inline<ex::set_stopped_t,
ex::env_of_t<decltype(__reschedule_on_current)>,
ex::env<>>);
Loading