Repository navigation
Open
Description
I spawn a child into a counting_scope. The child reads the stop token out of the
environment and passes it to a coroutine that takes stdexec::inplace_stop_token. The
scope supplies a real inplace_stop_token, and the program runs as expected when it
compiles.
Wrapping that child in starts_on makes clang reject the program. gcc accepts the same
code.
#include <utility>
#include <stdexec/execution.hpp>
namespace ex = stdexec;
// In real code this is a member function defined in a .cpp, so its parameter
// type is fixed.
auto work(ex::inplace_stop_token token) -> ex::task<void> {
(void)token;
co_return;
}
int main() {
ex::run_loop loop;
ex::counting_scope scope;
auto child = ex::let_value(ex::read_env(ex::get_stop_token),
[](auto token) -> ex::task<void> {
co_await work(token);
});
ex::spawn(ex::starts_on(loop.get_scheduler(), std::move(child)) |
ex::upon_error([](auto&&) noexcept {}),
scope.get_token());
ex::sync_wait(scope.join());
}clang++ -std=c++26 -Iinclude -fsyntax-only repro.cpp
fails with:
repro.cpp:20:41: error: no matching function for call to 'work'
20 | co_await work(token);
| ^~~~
include/stdexec/__detail/../__detail/../functional.hpp:168:16: note: in instantiation of function template specialization 'main()::(anonymous
class)::operator()<stdexec::never_stop_token>' requested here
168 | return static_cast<_Fun &&>(__fun)(static_cast<_Args &&>(__args)...);
| ^
...
repro.cpp:9:6: note: candidate function not viable: no known conversion from 'stdexec::never_stop_token' to 'ex::inplace_stop_token' for 1st argument
9 | auto work(ex::inplace_stop_token token) -> ex::task<void> {
| ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
The same command with g++ -std=c++26 compiles.
Variants, each changing one thing in the program above:
| variant | g++ 15.2.0 | clang 21.1.8 |
|---|---|---|
| as written | compiles | fails |
work takes the token as auto instead of inplace_stop_token |
compiles | compiles |
| the child does not read the environment | compiles | compiles |
the scheduler is given through write_env(prop{get_start_scheduler, sched}) instead of starts_on |
compiles | compiles |
sync_wait with the token in the environment, instead of spawning into a scope |
compiles | compiles |
connect to a receiver whose environment carries the token, instead of spawning into a scope |
compiles | compiles |
Is the child expected to be instantiated with an environment that has no stop token here,
or am I holding starts_on wrong?
Versions:
- stdexec
main@f91f6363(2026-08-22) - g++ 15.2.0, clang 21.1.8, both
-std=c++26 - clang 22.1.2 rejects the program the same way
Metadata
Metadata
Assignees
Labels
No labels
Activity
yulin26c commentedon Aug 28, 2026
Hi, I believe PR #2234 should address this issue based on my code‑level analysis. I haven’t been able to test it in practice, though. Could anyone check it out and give it a try?
kyusic commentedon Aug 28, 2026
Confirmed: PR #2234 fixes this for me.
With that branch checked out, the repro above and every variant in the table compile with
g++ 15.2.0 and clang 21.1.8. The real code this was reduced from also compiles again
without the workaround I had applied.
One note: clang 22.1.2 still rejects the program, but with a different diagnostic
(
no member named 'await_ready') that also shows up on shapes withoutstarts_on, and itis unchanged by this PR, so it looks unrelated.
yulin26c commentedon Aug 28, 2026
Thanks for testing and confirming!
daniel-petrovic commentedon Sep 25, 2026
can this issue be closed if already tested and fixed ?
alwaysprince05 commentedon Sep 28, 2026
Tested against current main and this is fixed there. PR #2234 (merged as 6720837) fixed the environment propagation through
__stop_when, which is the pathspawntakes for astarts_onchild, and the reporter already confirmed it resolves the issue in this thread.For anyone rechecking later: I reproduced the original
never_stop_tokenerror on f91f636 (the revision the report was made against) and the same repro compiles on current main with Apple clang 21 and gcc 16.2.0, both with -std=c++26.Looks safe to close.
alwaysprince05 commentedon Oct 22, 2026
Following up on the verification from Sep 28 — is anything still needed to move this, such as a re-test on a specific compiler set? Happy to test a patch if that helps.