Allow just to Throw on Connect#1578
Merged
ericniebler merged 2 commits intoNVIDIA:mainfrom Jul 20, 2025
Merged
Conversation
Sending completion signals to receivers must not throw, including
set_value. This is enforced as can be seen in this error which was
observed before the application of this commit:
/stdexec/__detail/__receivers.hpp:47:11: error: static assertion failed: set_value member functions must be noexcept
47 | noexcept(static_cast<_Receiver&&>(__rcvr).set_value(static_cast<_As&&>(__as)...)),
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
An obvious consequence of the above is that the set_value member
function(s) of a receiver must be marked noexcept. However the
evaluation of a function itself is not the only thing that can throw
when invoking a function: The population of the parameters thereto may
emit an exception. For example a function may accept parameters by value
thereby requiring the caller to copy or move the arguments thereto.
Since, as alluded to above, the parameters are populated in the context
of the caller the only thing a function can do to prevent such
exceptions is to accept its parameters by reference (thereby obviating
the need to move construct arguments thereto). Previously the test
helper fun_receiver did not do this leading to the error provided above.
Updated fun_receiver::set_value to accept parameters by forwarding
reference thereby allowing it to accept parameters whose move
constructors are not noexcept.
A just sender that isn't nullary contains one or more objects. These objects are transmitted thereinto by the sender factory therefor. Since copying and moving objects can throw the just sender factory can also throw (this is demonstrated by the unit test added by this commit). In order to be useful a sender must be connected with a receiver to form an operation state. Since the just operation does not yield the objects passed to the sender factory therefor until the operation has been started it is clear those objects must in turn be transmitted from the sender to the operation state at connect time. If initially providing those objects can throw then so too can propagating them from the sender to the operation state. That is to say that not only can the just sender factory throw but so too can connecting a just sender with a receiver. Before this commit if a just sender was connected, and one of the move operations involved therein threw an exception, the program would terminate due to the fact the exception would attempt to pass through a constructor marked noexcept. The code involved (changed by this commit) attempted to accurately reflect the noexcept-ness of the operations involved by checking: __noexcept_of<__sexpr_impl<__tag_t>::get_state, _Sexpr, _Receiver&> However this merely checks if the evaluation of some function throws an exception. In the case wherein a just sender is being connected the evaluation does not throw and therefore the above expression correctly yields true. The function is not merely invoked however, the value returned thereby is used to populate a data member in the constructor initializer list. In the instance of just the invocation yields an rvalue reference and therefore a move operation must occur, one which may throw an exception. To account for this the noexcept check must be: noexcept(__state_t(__sexpr_impl<__tag_t>::get_state(static_cast<_Sexpr&&>(__sndr), __rcvr_))) Which is what it is changed to by this commit.
ericniebler
reviewed
Jul 20, 2025
Collaborator
|
/ok to test daf9a01 |
Collaborator
|
Thanks Robert! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Previously if connecting a just sender with a receiver threw due to a throwing move operation terminate was called due to an exception passing through noexcept.