starts_on: a child reading get_stop_token from the environment fails to compile with clang (gcc accepts it)

Aperta
#2,240 3 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
48/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
cpp

Direzione di ricerca

Riproduci l’esempio con clang++ e g++ usando i comandi C++26 indicati, quindi esamina i percorsi starts_on, read_env, spawn e counting_scope, iniziando dall’istanza di functional.hpp mostrata nella diagnostica. Confronta i tipi di environment e stop-token osservati dal child nelle varianti elencate. Il lavoro è completato quando il programma originale viene compilato con clang senza compromettere le varianti che compilano già.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

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
Lingua principale
C++
Stelle
2.4k
Fork
270
Merge medio
2g 17h
PR unite (30g)
37

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di NVIDIA/stdexec

Tutte le issue di NVIDIA/stdexec

Issue simili

Altre issue su C++

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.