NVIDIA/stdexec

let_value does not propagate nothrow-connect-ness

Opened this issue · 2 comments

Consider this code:

#include <stdexec/execution.hpp>
void test() {
    auto s1 = stdexec::let_value(
        stdexec::just(),
        []() noexcept {
            return stdexec::just();
        }
    );
    static_assert(stdexec::__detail::__connectable<decltype(s1), stdexec::__sync_wait::__receiver_t<decltype(s1)>>);    
    static_assert(stdexec::__nothrow_connectable<decltype(s1), stdexec::__sync_wait::__receiver_t<decltype(s1)>>);  // <                    
}

(Godbolt link: https://godbolt.org/z/hn5MG7dqe)

Compilation fails on the line marked with <, which suggests than s1 is a valid sender, but its connect CPO is declared as throwing.
This is surprising: as fas as I can see, there is no room for an exception in this code, since just() returns nothrow-connectable sender, and lambda itself is declared as non-throwing. let_value internal implementation is hard to follow (in particular, while reading [exec] I wasn't able to find what domain really is), so I can't pinpoint source of confusion any further.

Is this behavior intended?

Looks like there is perhaps a missing noexcept declaration on let_value's get_state impls function.
e.g. see here

[]<class _Sender, class _Receiver>(_Sender&& __sndr, _Receiver&) {

Note that there is also another issue that can potentially cause sync_wait of let_value to be potentially-throwing, which is a currentl limitation of the env-based completion-signature computation.

At the time that let_value is computing the completion-signatures, it only has access to the environment type, which means it cannot generally compute the exact receiver type that will be passed to connect() on the second sender returned by the lambda, and so it cannot reliably determine if connect() will be noexcept or not. In some cases this can mean it conservatively needs to assume it might throw and thus will add set_error_t(std::exception_ptr) to the completion-signatures.

See cplusplus/sender-receiver#247