Skip to content

fix(exec): allow any_sender completion signatures through reference types - #2244

Open
alwaysprince05 wants to merge 1 commit into
NVIDIA:mainfrom
alwaysprince05:fix-any-sender-sequence-completion-signatures
Open

fix(exec): allow any_sender completion signatures through reference types#2244
alwaysprince05 wants to merge 1 commit into
NVIDIA:mainfrom
alwaysprince05:fix-any-sender-sequence-completion-signatures

Conversation

@alwaysprince05

Copy link
Copy Markdown

Summary

Fixes #2101 (supersedes #2223 with a simpler, correct approach).

When exec::sequence has 3+ senders, the recursive completion-signature
computation in __seq::__sndr produces reference-qualified sender types
(e.g. const any_sender&). The constraint derived_from<Self, _interface_>
on _isender::_interface_::get_completion_signatures() rejects these because
std::derived_from is never satisfied by a reference type.

Fix

Decay Self before the derived_from check. This is a 2-line change in
any_sender_of.hpp:

-        template <__std::derived_from<_interface_> Self, class... Env>
+        template <class Self, class... Env>
+          requires __std::derived_from<__decay_t<Self>, _interface_>
         static consteval auto get_completion_signatures()

get_completion_signatures is a static consteval function that returns
type information only — it never connects the sender, so the cvref-qualifiers
on Self are irrelevant. The connect member function remains &&-qualified
and still rejects const lvalue references.

Why this approach

The earlier PR #2223 changed __attrs to decay children types and
__sequence.hpp to decay the first sender for signature queries. Eric noted
that "the cvref-ness of the first sender matters" for connect (line 328).
Our fix avoids touching __sequence.hpp entirely — the constraint was simply
too restrictive for a function that only computes types.

Verified

  • 2 any_senders ✅
  • 3 any_senders ✅ (previously failed to compile)
  • 4 any_senders ✅
  • Concrete senders only ✅ (regression check)
  • Mixed concrete + any_senders ✅

🤖 Generated with Codebuff
Co-Authored-By: Codebuff noreply@codebuff.com

…ypes

Fixes NVIDIA#2101. When exec::sequence has 3+ senders, the recursive
completion-signature computation in __seq::__sndr produces reference-
qualified sender types (e.g. const any_sender&). The previous
constraint `derived_from<Self, _interface_>` on
isender::interface::get_completion_signatures() rejected reference
types because std::derived_from is never satisfied by a reference.

Decay Self before the derived_from check. get_completion_signatures is
a static consteval function that returns type information only — it
never connects the sender, so the cvref-qualifiers on Self are
irrelevant here. This restores the ability to use type-erased
any_senders inside sequences of 3+ senders.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
@copy-pr-bot

copy-pr-bot Bot commented Aug 31, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.


template <__std::derived_from<_interface_> Self, class... Env>
template <class Self, class... Env>
requires __std::derived_from<__decay_t<Self>, _interface_>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm afraid this fix is wrong too. if sender_in<S, E> is true, then a sender of type S should be connect-able with a receiver whose environment has type E. after this change, that is no longer true for any_sender. only rvalue any_senders can be connected, so any_sender::get_completion_signatures is right to reject lvalue any_senders.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

exec::any_sender fails get_completion_signatures inside a sequence of 3+ senders (works with 2)

2 participants