Skip to content

Commit 364da35

Browse files
committed
let_value, let_error, & let_stopped: Dependent set_error_t(std::exception_ptr)
let_value, let_error, and let_stopped have three different kinds of completion signatures: - Those obtained from the sender type returned by the invocable, - Those passed through from the child sender, and - Possibly set_error_t(std::exception_ptr) The latter must be added when: - Decay-copying the apropos result datums of the child sender can throw, - Invoking the invocable with any set of decay-copied result datums can throw, or - Connecting any of the sender types which can be returned by the invocable can throw Note that if the child of let_value, let_error, or let_stopped is not dependent the apropos result datums can be determined without the context of an environment. This means, in turn, that in such a situation it can be determined, without the context of an environment, whether invocation of the invocable can throw (since the type of the decay- copied result datums with which it will be invoked can be known). The last of the bullets above, however, presents a problem in an environment-free context. Computing whether or not a sender can be connected without throwing requires the context of an environment (see P3388). Previously let_value, let_error, and let_stopped unconditionally added set_error_t(std::exception_ptr) in the case where no environment was provided. This created the illusion that the sender was not dependent, and led to compilation failures in situations such as the test added by this commit. The above might seem to imply that let_value, let_error, and let_stopped are always dependent, but this isn't true. In the case where set_error_t(std::exception_ptr) is already a possible completion signature it doesn't matter whether or not connecting the sender returned by the invocable can throw. Reified the above: let_value, let_error, and let_stopped indicate they are dependent when the question of whether or not connecting the sender returned by the invocable throws determines the presence of set_error_t(std::exception_ptr), otherwise they can advertise non- dependent completion signatures.
1 parent e92245d commit 364da35

2 files changed

Lines changed: 28 additions & 0 deletions

File tree

include/stdexec/__detail/__let.hpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,24 @@ namespace STDEXEC
565565
using __what_t = __bad_result_sender_t<__sndr2_t, _LetTag, __env2_t<_Child, _Env>...>;
566566
return STDEXEC::__throw_compile_time_error(__what_t());
567567
}
568+
else if constexpr (__nothrow_decay_copyable<_Args...>
569+
&& __nothrow_invocable<_Fun, __decay_t<_Args>&...>
570+
&& sizeof...(_Env) == 0)
571+
{
572+
auto __completions =
573+
STDEXEC::get_completion_signatures<__sndr2_t, __env2_t<_Child, _Env>...>();
574+
STDEXEC_IF_OK(__completions)
575+
{
576+
if constexpr (__completions.template __contains<__eptr_sig_t>())
577+
{
578+
return __completions;
579+
}
580+
else
581+
{
582+
return STDEXEC::__throw_dependent_sender_error<__sndr2_t>();
583+
}
584+
}
585+
}
568586
else if constexpr (__nothrow_decay_copyable<_Args...>
569587
&& __nothrow_invocable<_Fun, __decay_t<_Args>&...>
570588
&& (__nothrow_connectable<__sndr2_t, __rcvr2_t<_Child, _Env>>

test/stdexec/algos/adaptors/test_let_error.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,16 @@ namespace
100100
STDEXEC::sync_wait(std::move(snd));
101101
}
102102

103+
TEST_CASE("let_error can be followed by upon_error", "[adaptors][let_error]")
104+
{
105+
auto snd = ex::just_error(2)
106+
| ex::let_error([](int n) noexcept { return ex::just_error(n * 10); })
107+
| ex::upon_error([](int n) noexcept { return n + 3; });
108+
auto opt = ex::sync_wait(std::move(snd));
109+
REQUIRE(opt.has_value());
110+
CHECK(std::get<0>(*opt) == 23);
111+
}
112+
103113
#if !STDEXEC_NO_STDCPP_EXCEPTIONS()
104114
TEST_CASE("let_error can be used to produce values (error to value)", "[adaptors][let_error]")
105115
{

0 commit comments

Comments
 (0)