Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

let_value does not propagate nothrow-connect-ness #1442

Open
MikailBag opened this issue Nov 28, 2024 · 2 comments
Open

let_value does not propagate nothrow-connect-ness #1442

MikailBag opened this issue Nov 28, 2024 · 2 comments

Comments

@MikailBag
Copy link

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?

@lewissbaker
Copy link
Contributor

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&) {

@lewissbaker
Copy link
Contributor

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants