Title
`std::execution::spawn_future` is mishandling dependent senders
Status
new
Section
[exec.spawn.future]
Submitter
Eric Niebler

Created on 2026-04-11.00:00:00 last changed 1 week ago

Messages

Date: 2026-04-11.10:43:19

Proposed resolution:

This wording is relative to N5032.

  1. Modify [exec.spawn.future] as indicated:

    -7- Let spawn-future-state be the exposition-only class template:

    namespace std::execution {
      template<class Alloc, scope_token Token, sender Sender, class Env>
      struct spawn-future-state                   // exposition only
        : spawn-future-state-base<completion_signatures_of_t<future-spawned-sender<Sender, Env>, env<>>> {
        using sigs-t =                            // exposition only
          completion_signatures_of_t<future-spawned-sender<Sender, Env>, env<>>;
        using receiver-t =                        // exposition only
          spawn-future-receiver<sigs-t>;
        using op-t =                              // exposition only
          connect_result_t<future-spawned-sender<Sender, Env>, receiver-t>;
      […]
      };
    […]
    }
    
Date: 2026-04-11.00:00:00

In [exec.spawn.future] p7, we see this:

-7- Let spawn-future-state be the exposition-only class template:

namespace std::execution {
  template<class Alloc, scope_token Token, sender Sender, class Env>
  struct spawn-future-state                   // exposition only
    : spawn-future-state-base<completion_signatures_of_t<future-spawned-sender<Sender, Env>>> {
    using sigs-t =                            // exposition only
      completion_signatures_of_t<future-spawned-sender<Sender, Env>>;
    using receiver-t =                        // exposition only
      spawn-future-receiver<sigs-t>;
    using op-t =                              // exposition only
      connect_result_t<future-spawned-sender<Sender, Env>, receiver-t>;
  […]
  };
[…]
}

where spawn-future-sender<Sender, Env> is the type of write_env(stop-when(declval<Sender>(), declval<stoken-t>()), declval<Env>()).

The problem happens in the definition of sigs-t. There is a difference between asking for a sender's completion signatures with an empty environment, and asking with no environment.

In sigs-t, we are asking for the completion signatures with no environment. That is asking the sender for its non-dependent completions. But if `Sender` is a dependent sender, then so is future-spawned-sender<Sender, Env>, and so this line will not compile. A dependent sender cannot provide non-dependent completion signatures.

The `spawn_future` algorithm connects the future-spawned-sender with a receiver that has an empty environment. Therefore, we should be using the empty environment when computing the future-spawned-sender's completion signatures.

History
Date User Action Args
2026-04-11 10:43:19adminsetmessages: + msg16263
2026-04-11 00:00:00admincreate