This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

4355. connect-awaitable() should mandate rcvr can receive all completion-signals rather than using constraints

Section: 33.9.10 [exec.connect] Status: New Submitter: Lewis Baker Opened: 2025-08-27 Last modified: 2025-09-14

Priority: Not Prioritized

View other active issues in [exec.connect].

View all other issues in [exec.connect].

View all issues with New status.

Discussion:

In 33.9.10 [exec.connect] p6, the wording for the connect() customization-point defines a case that is expression-equivalent to connect-awaitable(new_sndr, rcvr).

The connect-awaitable function is specified in p5 as having the signature:

operation-state-task connect-awaitable(DS sndr, DR rcvr) requires receiver_of<DR, Sigs>;

The requires-clause constrains this overload to ensure that the receiver, rcvr, can accept all of the completion signatures listed in Sigs. This means that connect() will SFINAE out if the receiver cannot accept all of the completion signatures, rather than this being ill-formed.

However, this seems inconsistent with the handling of the case that dispatches to new-sndr.connect(rcvr) which does not constrain on this. It is also redundant with the Mandates element in p6 which mandates that the following is satisfied:

receiver_of<Rcvr, completion_signatures_of_t<Sndr, env_of_t<Rcvr>>>

The constraint on connect-awaitable should either be removed or replaced with a Mandates element. As connect-awaitable is only used within the definition of connect() and as connect() already mandates that receiver_of is satisfied, it seems sufficient to just remove this constraint from connect-awaitable.

Proposed resolution:

This wording is relative to N5014.

  1. Modify 33.9.10 [exec.connect] as indicated:

    -5- Let V name the type await-result-type<DS, connect-awaitable-promise>, let Sigs name the type

    completion_signatures<
      SET-VALUE-SIG(V), // see 33.9.3 [exec.snd.concepts]
      set_error_t(exception_ptr),
      set_stopped_t()>
    

    and let connect-awaitable be an exposition-only coroutine defined as follows:

    namespace std::execution {
      […]
      operation-state-task connect-awaitable(DS sndr, DR rcvr) requires receiver_of<DR, Sigs> {
        exception_ptr ep;
        try {
          if constexpr (same_as<V, void>) {
            co_await std::move(sndr);
            co_await suspend-complete(set_value, std::move(rcvr));
          } else {
            co_await suspend-complete(set_value, std::move(rcvr), co_await std::move(sndr));
          }
        } catch(...) {
          ep = current_exception();
        }
        co_await suspend-complete(set_error, std::move(rcvr), std::move(ep));
      }
    }