From b8bf6895c1cc549c8d4c44b74a5c291a1efa8508 Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Sun, 15 Feb 2026 11:52:34 -0800 Subject: [PATCH 1/2] `affine_on` does not need to compute its own completion signatures --- include/stdexec/__detail/__affine_on.hpp | 52 --------------------- include/stdexec/__detail/__basic_sender.hpp | 2 +- include/stdexec/__detail/__when_all.hpp | 27 ++++++----- 3 files changed, 14 insertions(+), 67 deletions(-) diff --git a/include/stdexec/__detail/__affine_on.hpp b/include/stdexec/__detail/__affine_on.hpp index 8dea4b2cc..91d0d8023 100644 --- a/include/stdexec/__detail/__affine_on.hpp +++ b/include/stdexec/__detail/__affine_on.hpp @@ -118,53 +118,6 @@ namespace STDEXEC { return completion_behavior::asynchronous_affine; } }; - - template - consteval auto __get_completion_signatures() { - STDEXEC_COMPLSIGS_LET( - __child_completions, get_completion_signatures<__child_of<_Self>, __fwd_env_t<_Env>>()) { - using __child_completions_t = decltype(__child_completions); - using __sched_t = __call_result_or_t, const _Env&>; - using __eptr_completion_t = - __eptr_completion_unless_t<__nothrow_decay_copyable_results_t<__child_completions_t>>; - - constexpr auto __completions = __transform_completion_signatures( - __child_completions, - __decay_arguments(), - __decay_arguments(), - {}, - __eptr_completion_t{}); - - if constexpr (!__decay_copyable_results_t<__child_completions_t>::value) { - // If the child sender's completion signatures aren't decay-copyable, then we can't - // adapt it to be affine. - return __throw_compile_time_error< - _WHAT_(_CANNOT_MAKE_SENDER_AFFINE_TO_THE_CURRENT_SCHEDULER_), - _WHY_(_SENDER_RESULTS_ARE_NOT_DECAY_COPYABLE_), - _WITH_PRETTY_SENDER_<__child_of<_Self>>, - _WITH_ENVIRONMENT_(_Env), - _WHERE_(_IN_ALGORITHM_, affine_on_t) - >(); - } else if constexpr (__is_affine<__child_of<_Self>, _Env>) { // NOLINT(bugprone-branch-clone) - return __completions; - } else if constexpr (__same_as<__sched_t, __not_a_scheduler<>>) { - return __throw_compile_time_error< - _WHAT_(_CANNOT_MAKE_SENDER_AFFINE_TO_THE_CURRENT_SCHEDULER_), - _WHY_(_THE_CURRENT_EXECUTION_ENVIRONMENT_DOESNT_HAVE_A_SCHEDULER_), - _WHERE_(_IN_ALGORITHM_, affine_on_t) - >(); - } else if constexpr (!__infallible_scheduler<__sched_t, _Env>) { - return __throw_compile_time_error< - _WHAT_(_CANNOT_MAKE_SENDER_AFFINE_TO_THE_CURRENT_SCHEDULER_), - _WHY_(_THE_SCHEDULER_IN_THE_CURRENT_EXECUTION_ENVIRONMENT_IS_NOT_INFALLIBLE_), - _WHERE_(_IN_ALGORITHM_, affine_on_t), - _WITH_SCHEDULER_(__sched_t) - >(); - } else { - return __completions; - } - } - } } // namespace __affine_on template <> @@ -173,10 +126,5 @@ namespace STDEXEC { [](__ignore, __ignore, __ignore) noexcept { return __affine_on::__attrs{}; }; - - template - static consteval auto __get_completion_signatures() { - return __affine_on::__get_completion_signatures<_Self, _Env>(); - } }; } // namespace STDEXEC diff --git a/include/stdexec/__detail/__basic_sender.hpp b/include/stdexec/__detail/__basic_sender.hpp index 64ac94778..2693842b8 100644 --- a/include/stdexec/__detail/__basic_sender.hpp +++ b/include/stdexec/__detail/__basic_sender.hpp @@ -184,7 +184,7 @@ namespace STDEXEC { _Set()(static_cast<_State&&>(__state).__rcvr_, static_cast<_As&&>(__as)...); }; - template + template static consteval auto __get_completion_signatures() { static_assert( __mnever>, diff --git a/include/stdexec/__detail/__when_all.hpp b/include/stdexec/__detail/__when_all.hpp index 18d8e30a7..7c00fb419 100644 --- a/include/stdexec/__detail/__when_all.hpp +++ b/include/stdexec/__detail/__when_all.hpp @@ -129,8 +129,7 @@ namespace STDEXEC { } template - using __env_t = - decltype(__when_all::__mk_env(__declval<_Env>(), __declval())); + using __env_t = __result_of<__when_all::__mk_env<_Env>, _Env, const inplace_stop_source&>; template concept __max1_sender = @@ -432,8 +431,8 @@ namespace STDEXEC { }; static constexpr auto __start = []( - _State& __state, - _Operations&... __child_ops) noexcept -> void { + _State& __state, + _Operations&... __child_ops) noexcept -> void { // register stop callback: __state.__on_stop_.emplace( get_stop_token(STDEXEC::get_env(__state.__rcvr_)), @@ -473,10 +472,10 @@ namespace STDEXEC { } static constexpr auto __complete = []( - _Index, - _State& __state, - _Set, - _Args&&... __args) noexcept -> void { + _Index, + _State& __state, + _Set, + _Args&&... __args) noexcept -> void { using _ValuesTuple = decltype(_State::__values_); if constexpr (__same_as<_Set, set_error_t>) { __set_error(__state, static_cast<_Args&&>(__args)...); @@ -534,9 +533,9 @@ namespace STDEXEC { struct __transfer_when_all_impl : __sexpr_defaults { static constexpr auto __get_attrs = []( - __ignore, - const _Scheduler& __sched, - const _Child&...) noexcept { + __ignore, + const _Scheduler& __sched, + const _Child&...) noexcept { // TODO(ericniebler): check this use of __sched_attrs return __sched_attrs{std::cref(__sched)}; }; @@ -551,9 +550,9 @@ namespace STDEXEC { struct __transfer_when_all_with_variant_impl : __sexpr_defaults { static constexpr auto __get_attrs = []( - __ignore, - const _Scheduler& __sched, - const _Child&...) noexcept { + __ignore, + const _Scheduler& __sched, + const _Child&...) noexcept { return __sched_attrs{std::cref(__sched)}; }; From 4f1d6b387f8edfa274b8aaaf8a30bc65ab88c624 Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Sun, 15 Feb 2026 15:39:32 -0800 Subject: [PATCH 2/2] work around nvc++ bug --- include/stdexec/__detail/__when_all.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/stdexec/__detail/__when_all.hpp b/include/stdexec/__detail/__when_all.hpp index 7c00fb419..d5fa1de5a 100644 --- a/include/stdexec/__detail/__when_all.hpp +++ b/include/stdexec/__detail/__when_all.hpp @@ -129,7 +129,8 @@ namespace STDEXEC { } template - using __env_t = __result_of<__when_all::__mk_env<_Env>, _Env, const inplace_stop_source&>; + using __env_t = + decltype(__when_all::__mk_env(__declval<_Env>(), __declval())); template concept __max1_sender =