fix: require schedule() to return a stdexec sender in the scheduler concept - #2259
Conversation
…oncept Evaluating stdexec::scheduler<S> for a foreign scheduler type whose schedule() member returns a non-stdexec sender was a false positive: __callable<schedule_t, S> succeeded, and the sender check only fired as a hard error inside the schedule CPO body at the point of use. Add a SFINAE-safe __returns_stdexec_sender clause to the concept so such types evaluate to false gracefully, while foreign frameworks whose schedule() returns a genuine stdexec sender model the concept behaviorally, with no scheduler_concept alias required. See NVIDIA#1406. 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
|
Hi @ericniebler — this grew out of the scheduler_concept work in #2256/#2257, so it felt like a natural next step to take on #1406. I played with a small repro and it turns out the concept now fails in the opposite direction from what was originally reported: a scheduler whose It's a small change — one extra clause in the concept plus three test cases. |
|
/ok to test 4f2a398 |
Fixes #1406.
The problem, as it stands today
The original report (2024) was that
stdexec::scheduler<S>hard-errored for foreign scheduler types. On currentmainthat specific failure mode is gone, but investigating it with a repro exposed the remaining defect — the inverse one:stdexec::scheduler<foreign_scheduler>currently evaluates totruefor a type whoseschedule()returns something that is not a stdexec sender (nosender_conceptalias, not enabled viaenable_sender).__callable<schedule_t, S>succeeds, and the sender check only fires as a hardstatic_assertinside thescheduleCPO body — at the point of actual use, not at the concept. So the concept answers the wrong question at the wrong time: a false positive up front, and a hard error later.The fix
Add a SFINAE-safe clause to the concept in
include/stdexec/__detail/__schedulers.hpp:schedule()returns a non-stdexec sender now evaluate the concept tofalsegracefully — no hard error, no false positive.static_assertin the CPO body stays, so explicitschedule(foreign_sched)misuse still fails with a clear message at the call site.scheduler_conceptalias is required: a foreign framework opts in behaviorally by returning a genuine stdexec sender fromschedule(). This matches the direction discussed in No way to check whether a scheduler is a stdexec scheduler #1406 (No way to check whether a scheduler is a stdexec scheduler #1406 (comment)).What's here
include/stdexec/__detail/__schedulers.hpp: the new__returns_stdexec_senderconcept, wired intoscheduler, plus doc-comment updates.test/stdexec/concepts/test_concept_scheduler.cpp(3 new cases, existing file/style):scheduler(value, lvalue-ref, and const-lvalue-ref forms)schedule()returningvoiddoes not modelschedulerscheduler_conceptalias whoseschedule()returns a real stdexec sender does modelscheduler(behavioral opt-in)Verification
test.stdexec: 3534 assertions / 622 cases pass (Release, Apple Clang 21)test.exec: 3417 assertions / 362 cases passHappy to restructure if there's a preferred shape for this — e.g. folding the check into
__callable<schedule_t, ...>instead of a separate concept.