Repository navigation
Conversation
A type-erased receiver answers a declared query `R(Q, Args...)` by calling `Q()(get_env(rcvr), args...)` on the wrapped receiver's environment, but type erasure checks something narrower: whether the environment has a `query` member for `Q`. The two differ for a query with a default answer. For example, `get_domain(env)` answers `default_domain` for an environment with no `get_domain` member, so an `exec::any_sender` or `exec::function` declaring `default_domain(get_domain_t) noexcept` can answer the query in such an environment, but can't be connected there. This diff checks the call instead: the environment satisfies a declared query when calling the query object on it is well-formed, converts to the declared result type and, if the declaration is `noexcept`, isn't potentially throwing. For the standard queries, the two checks agree wherever the environment has its own `query` member, so every environment accepted before is still accepted; what's new is that a query's default answer now counts. Only `get_domain` and `get_stop_token` have one, and `any_sender`'s existing special cases for `get_stop_token` still decide those declarations. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`exec::function` shares its receiver type erasure with `exec::any_sender`, including `any_sender`'s stop-token bridging. When the erased receiver's queries include `inplace_stop_token(get_stop_token_t) noexcept`, the concrete receiver is stored in a state that owns an `inplace_stop_source` and forwards the receiver's stop requests to it from a callback. That doesn't work for `function`: - the bridging state isn't movable, so it isn't a receiver, and the type-erased receiver can't be constructed from it; no `function` that declares the query can be connected at all, and - `function`'s operation state never registers the forwarding callback, so even with the first problem fixed, stop requests never reach the implementation. The type-erasure checks also accept, for that query, a receiver whose stop token is a `never_stop_token`, answering with a token that is never stopped, and accept `never_stop_token(get_stop_token_t) noexcept` whatever the receiver's stop token. This diff stops `function` using the bridge. A declared stop-token query is now a requirement on the receiver's environment like any other declared query: the environment must answer it with a token that converts to the declared type, and the type-erased receiver answers it by converting the receiver's own token, so stop requests reach the implementation directly. A receiver whose stop token doesn't convert is rejected. Since `get_stop_token` answers `never_stop_token` for an environment without a stop token, such an environment satisfies a declared `never_stop_token` and not a declared `inplace_stop_token`. `any_sender` keeps its bridging and its more permissive checks unchanged: the shared check is split into the requirement that `function` uses and `any_sender`'s relaxation of it for the stop-token queries. Changing `any_sender` to match would break code that relies on the bridge. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Author
|
@SamGaaWaa, once this merges, you should be able to use |
This branch has not been deployed
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.
Depends on #2364.
exec::functionshares its receiver type erasure withexec::any_sender, includingany_sender's stop-token bridging. When the erased receiver's queries includeinplace_stop_token(get_stop_token_t) noexcept, the concrete receiver is stored in a state that owns aninplace_stop_sourceand forwards the receiver's stop requests to it from a callback. That doesn't work forfunction:functionthat declares the query can be connected at all, andfunction's operation state never registers the forwarding callback, so even with the first problem fixed, stop requests never reach the implementation.The type-erasure checks also accept, for that query, a receiver whose stop token is a
never_stop_token, answering with a token that is never stopped, and acceptnever_stop_token(get_stop_token_t) noexceptwhatever the receiver's stop token.This diff stops
functionusing the bridge. A declared stop-token query is now a requirement on the receiver's environment like any other declared query: the environment must answer it with a token that converts to the declared type, and the type-erased receiver answers it by converting the receiver's own token, so stop requests reach the implementation directly. A receiver whose stop token doesn't convert is rejected. Sinceget_stop_tokenanswersnever_stop_tokenfor an environment without a stop token, such an environment satisfies a declarednever_stop_tokenand not a declaredinplace_stop_token.any_senderkeeps its bridging and its more permissive checks unchanged: the shared check is split into the requirement thatfunctionuses andany_sender's relaxation of it for the stop-token queries. Changingany_senderto match would break code that relies on the bridge.