From 6295f6665a85c39a46c494cf89c96325ddcff0f9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dietmar=20K=C3=BChl?=
@@ -387,7 +304,7 @@ template
@@ -695,7 +730,7 @@ to the operation state that results from connecting `out_sndr` with
`out_rcvr`. Calling `start(op)` shall
-
-
-[19]{.pnum} _Effects_: Initializes an allocator `palloc` of type
-`PAlloc` with `alloc`. Uses `palloc` to allocate storage for the
-smallest array of `U` sufficient to provide storage for a coroutine
-state of size `size`, and unspecified additional state necessary to
-ensure that `operator delete` can later deallocate this memory block
-with an allocator equal to `palloc`.
-
-[20]{.pnum} _Returns_: A pointer to the allocated storage.
-
-## Wording Change C: Fix type names, allow flexible position, don't use for env
-
-::: ednote
-
-Change [task.promise] paragraph 17 and 18 to use the correct type and don't convert to `allocator_type`:
-
-:::
-
-```
-template
-
-
-[19]{.pnum} _Effects_: Initializes an allocator `palloc` of type
-`PAlloc` with `alloc`. Uses `palloc` to allocate storage for the
-smallest array of `U` sufficient to provide storage for a coroutine
-state of size `size`, and unspecified additional state necessary to
-ensure that `operator delete` can later deallocate this memory block
-with an allocator equal to `palloc`.
-
-[20]{.pnum} _Returns_: A pointer to the allocated storage.
-
# Use Allocator From Environment
MANDATE-NOTHROW(AS-CONST(env).query(get_start_scheduler))
-if this expression is well-formed. Otherwise, `get_start_scheduler(env)`
-is expression-equivalent to `get_scheduler(env)`.
+if this expression is well-formed.
Mandates: If the expression above is well-formed, its type satisfies `scheduler`.
[3]{.pnum} `forwarding_query(execution::get_start_scheduler)` is a core
constant expression and has value true.
-[?]{.pnum} Given subexpressions `sndr` and `rcvr` such that
+[4]{.pnum} Given subexpressions `sndr` and `rcvr` such that
`sender_toSCHED-ENV
-use `get_start_scheduler` instead of `get_scheduler`:
+Add two paragraphs at the start of [exec.snd.expos] giving
+implementations permission to add members `affine_on` and `as_awaitable`
+to standard library sender types:
+
+:::
+
+::: add
+
+[?]{.pnum} Given an expression `sndr`, whose type is any sender
+type defined in the standard library, it is unspecified whether the
+expression `sndr.affine_on()` is well-formed. If that expression
+is well-formed, then the evaluation thereof shall satisfy the
+semantic requirements of the `affine_on` [exec.affine.on] algorithm.
+
+[?]{.pnum} Given an expression `sndr`, whose type type is any sender type
+defined in the standard library, and an expression `p`, whose type is a
+promise type, it is unspecified whether the expression
+`sndr.as_awaitable(p)` is well-formed. If that expression is
+well-formed, then the evaluation thereof shall satisfy the semantic
+requirements of the `as_awaitable` [exec.as.awaitable] algorithm.
+
+:::
+
+::: ednote
+
+Change [[exec.snd.expos](https://wg21.link/exec.snd.expos)] paragraph
+8 to have SCHED-ENV use `get_start_scheduler`
+instead of `get_scheduler`:
:::
@@ -641,15 +675,16 @@ satisfies queryable such that `o2.query(@[get_scheduler]{.rm
is a prvalue with the same type and value as `sch`, and such that
`o2.query(get_domain)` is expression-equivalent to `sch.query(get_domain)`.
-
::: ednote
-The specification of `on` [[exec.on](https://wg21.link/exec.on)] shouldn't use `write_env` as it does,
-i.e., this change removes these (not removing them was an oversight
-in
+The specification of `on` [[exec.on](https://wg21.link/exec.on)]
+shouldn't use `write_env` as it does, i.e., this change removes
+these (not removing them was an oversight in
[P3826](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3826r3.html)).
+
In addition, if `get_start_scheduler` is introduced change how `on`
-gets its scheduler in [[exec.on](https://wg21.link/exec.on)], i.e., change the use from
-`get_scheduler` to use `get_start_scheduler`:
+gets its scheduler in [[exec.on](https://wg21.link/exec.on)], i.e.,
+change the use from `get_scheduler` to use `get_start_scheduler`:
+
:::
@@ -747,30 +782,33 @@ If any scheduling operation fails, an error completion on `out_rcvr` shall be ex
MANDATE-NOTHROW(AS-CONST(env).query(get_scheduler)).
+:::
-Mandates: If the expression above is well-formed, its type satisfies `scheduler`.
+Let `@_sync-wait-env_@` be the following exposition-only class type:
-[3]{.pnum} `forwarding_query(execution::get_scheduler)` is a core
-constant expression and has value true.
+```
+namespace std::this_thread {
+ struct sync-wait-env {
+ execution::run_loop* loop; // @_exposition only_@
-:::add
+ auto query(execution::get_scheduler_t) const noexcept {
+ return loop->get_scheduler();
+ }
-[?]{.pnum} Given subexpressions `sndr` and `rcvr` such that
-`sender_tostart(_op_) completes. [If scheduling onto `sch`
fails, an error completion on _out_rcvr_ shall be
executed on an unspecified execution agent.]{.rm}
-::: ednote
-Change [exec.affine.on] to use only one parameter, require an
-infallible scheduler from the receiver, and add a default implementation
-which allows customization of `affine_on` for child senders. If
-`get_start_scheduler` is not introduced the algorithms should use
-`get_scheduler` to get the start scheduler:
-:::
-
-[1]{.pnum}
-`affine_on` adapts a sender into one that completes on a [specified
-scheduler]{.rm}[receiver's scheduler]{.add}. If the algorithm
-determines that the adapted sender already completes on the correct
-scheduler it can avoid any scheduling operation.
-
-[2]{.pnum}
-The name `affine_on` denotes a pipeable sender adaptor object. For
-[a ]{.add} subexpression[s sch and]{.rm} `sndr`, if [`decltype((sch))`
-does not satisfy scheduler, or]{.rm} `decltype((sndr))` does not
-satisfy sender, affine_on(sndr[, sch]{.rm}) is ill-formed.
-
-[3]{.pnum}
-Otherwise, the expression affine_on(sndr[, sch]{.rm})
-is expression-equivalent to
-`@_make-sender_@(affine_on, @[sch]{.rm}@@[env<>()]{.add}@, sndr)`.
-
-:::{.add}
-[?]{.pnum}
-Let `sndr` and `ev` be subexpressions such that `Sndr` is
-`decltype((sndr))`. If sender-for<Sndr,
-affine_on_t> is `false`, then the expression
-`affine_on.transform_sender(sndr, ev)` is ill-formed; otherwise,
-it is equal to:
-
-```
-auto&[_, _, child] = sndr;
-using child_tag_t = tag_of_t
-
-
-[?]{.pnum}
-_Recommended Practice_: Implementations should provide `affine_on`
-member functions for senders which are known to resume on the
-scheduler where they were started. Example senders for which that
-is the case are `just`, `just_error`, `just_stopped`, `read_env`,
-and `write_env`.
-
-:::
-
-[5]{.pnum}
-Let _out_sndr_ be a subexpression denoting a sender
-returned from affine_on(sndr[, sch]{.rm}) or one equal
-to such, and let _OutSndr_ be the type
-decltype((_out_sndr_)). Let _out_rcvr_
-be a subexpression denoting a receiver that has an environment of
-type `Env` such that sender_in<_OutSndr_, Env>
-is `true`. [Let _sch_ be the result of the expression
-get_scheduler(get_env(_out_rcvr_)). If the completion
-signatures of schedule(_sch_) contain a different
-completion signature than `set_value_t()` when using an environment
-where `get_stop_token()` returns an `unstoppable_token`, the
-expression connect(out_sndr, out_rcvr) is
-ill-formed.]{.add} Let `op` be an lvalue referring to the operation
-state that results from connecting _out_sndr_ to
-_out_rcvr_. Calling start(_op_) will
-start `sndr` on the current execution agent and execute completion
-operations on _out_rcvr_ on an execution agent of the
-execution resource associated with [`sch`]{.rm}[_sch_]{.add}.
-If the current execution resource is the same as the execution
-resource associated with [`sch`]{.rm}[_sch_]{.add},
-the completion operation on _out_rcvr_ may be called
-before start(_op_) completes. [If scheduling onto `sch`
-fails, an error completion on _out_rcvr_ shall be
-executed on an unspecified execution agent.]{.rm}
-
::: ednote
Remove `change_coroutine_scheduler` from [execution.syn]:
:::
@@ -1050,6 +999,153 @@ namespace std::execution {
}
```
+::: ednot
+
+In [[task.class](https://wg21.link/task.class)] change `scheduler_type` to
+`start_scheduler_type`:
+
+:::
+
+```
+namespace std::execution {
+ template
+
+
+[3]{.pnum}
+
+A program is ill-formed if `error_types` is not a specialization
+of `execution::completion_signatures` or if the template arguments
+of that specialization contain an element which is not of the form
+`set_error_t(E)` for some type `E`.
+
+[4]{.pnum}
+The type alias `completion_signatures` is a specialization of
+`execution::completion_signatures` with the template arguments (in
+unspecified order):
+
+
+
+[5]{.pnum} `allocator_type` shall meet the _Cpp17Allocator_ requirements.
+
+::: ednote
+Change the scheduler propagation to `start` to use `get_start_scheduler` in [[task.state](https://wg21.link/task.state#4)] p4:
+:::
+
+```
+void start() & noexcept;
+```
+
+[4]{.pnum} _Effects_: Let `@_prom_@` be the object `@_handle_@.promise()`. Associates `@_STATE_@(@_prom_@)`, `@_RCVR_@(@_prom_@)`, and `@_SCHED_@(@_prom_@)` with `*this` as follows:
+
+
+
+
+Let `@_st_@` be `get_stop_token(get_env(@_rcvr_@))`. Initializes `@_prom_@.@_token_@`
+and `@_prom.source_@` such that
+
+
+
+
+After that invokes `@_handle_@.resume()`.
+
+::: ednote
+Use `get_start_scheduler` instead of `get_scheduler` when providing
+an environment to the `co_await`ed sender in
+[[task.state](https://wg21.link/task.state#16)] p16:
+:::
+
+```
+@_unspecified_@ get_env() const noexcept;
+```
+[16]{.pnum}
+
+_Returns_: An object `env` such that queries are forwarded as follows:
+
+
+
::: ednote
Adjust the use of `affine_on` and remove `change_coroutine_scheduler` from [task.promise]:
:::
@@ -1085,7 +1181,7 @@ templateMANDATE-NOTHROW(AS-CONST(env).query(get_start_scheduler))
-if this expression is well-formed.
+MANDATE-NOTHROW(AS-CONST(env).query(get_start_scheduler)).
Mandates: If the expression above is well-formed, its type satisfies `scheduler`.
@@ -650,14 +703,14 @@ to standard library sender types:
[?]{.pnum} Given an expression `sndr`, whose type is any sender
type defined in the standard library, it is unspecified whether the
expression `sndr.affine_on()` is well-formed. If that expression
-is well-formed, then the evaluation thereof shall satisfy the
+is well-formed, then the evaluation thereof meets the
semantic requirements of the `affine_on` [exec.affine.on] algorithm.
-[?]{.pnum} Given an expression `sndr`, whose type type is any sender type
+[?]{.pnum} Given an expression `sndr`, whose type is any sender type
defined in the standard library, and an expression `p`, whose type is a
promise type, it is unspecified whether the expression
`sndr.as_awaitable(p)` is well-formed. If that expression is
-well-formed, then the evaluation thereof shall satisfy the semantic
+well-formed, then the evaluation thereof meets the semantic
requirements of the `as_awaitable` [exec.as.awaitable] algorithm.
:::
@@ -710,12 +763,10 @@ if constexpr (scheduler
If any scheduling operation fails, an error completion on `out_rcvr` shall be executed on an unspecified execution agent.
-[10]{.pnum}
-Let out_sndr be a subexpression denoting a sender returned from
-`on(sndr, sch, closure)` or one equal to such, and let `OutSndr` be
-the type `decltype((out_sndr))`. Let `out_rcvr` be a subexpression
-denoting a receiver that has an environment of type `Env` such that
-`sender_in
-If any scheduling operation fails, an error completion on `out_rcvr` shall be executed on an unspecified execution agent. -
::: ednote @@ -839,9 +850,12 @@ the type of the expression above. [7.?]{.pnum} -[`@_adapt-for-await-completion_@(transform_sender(expr, get_env(p))).as_awaitable(p)` -if this expression is well-formed, `sender_insender-for<Sndr,
@@ -910,26 +943,15 @@ it is equal to:
```
auto&[_, _, child] = sndr;
-if constexpr (requires{ child.affine_on(); })
- return child.affine_on();
+if constexpr (requires{ std::forward_like(child).affine_on(); })
+ return std::forward_like(child).affine_on();
else
- return continues_on(child, @_UNSTOPPABLE-SCHEDULER_@(get_start_scheduler(ev)));
+ return continues_on(std::forward_like(child), @_UNSTOPPABLE-SCHEDULER_@(get_start_scheduler(ev)));
```
-[?]{.pnum} For a subexpression `sch` whose type satisfies `scheduler`,
-let `@_UNSTOPPABLE-SCHEDULER_@(sch)` be an expression `e` whose type
-satisfies `scheduler` such that:
-
-- [?.1]{.pnum} `schedule(e)` is expression-equivalent to `unstoppable(schedule(sch))`.
-- [?.2]{.pnum} For any query object `q` and pack of subexpressions `args...`, `e.query(q, args...)`
-is expression-equivalent to `sch.query(q, args...)`.
-- [?.3]{.pnum} Let `f` be the subexpression `@_UNSTOPPABLE-SCHEDULER_@(other)`. `e == f`
-is expression-equivalent to `sch == other`.
-
-
[?]{.pnum}
_Recommended Practice_: Implementations should provide `affine_on`
-member functions for senders which are known to resume on the
+member functions for senders that are known to resume on the
scheduler where they were started. Example senders for which that
is the case are `just`, `just_error`, `just_stopped`, `read_env`,
and `write_env`.
@@ -940,16 +962,14 @@ and `write_env`.
Let _out_sndr_ be a subexpression denoting a sender
returned from affine_on(sndr[, sch]{.rm}) or one equal
to such, and let _OutSndr_ be the type
-decltype((_out_sndr_)). Let _out_rcvr_
+decltype((_out_sndr_)). Let out_rcvr
be a subexpression denoting a receiver that has an environment of
-type `Env` such that sender_in<_OutSndr_, Env>
-is `true`. [Let _sch_ be the result of the expression
-get_start_scheduler(get_env(_out_rcvr_)). If the completion
-signatures of schedule(_sch_) contain a different
-completion signature than `set_value_t()` when using an environment
-where `get_stop_token()` returns an `unstoppable_token`, the
-expression connect(out_sndr, out_rcvr) is
-ill-formed.]{.add} Let `op` be an lvalue referring to the operation
+type `Env` [such that sender_in<_OutSndr_, Env>
+is `true`]{.rm}. [If get_start_scheduler(get_env(out_rcvr)) is ill-formed
+or does not satisfy `@_infallible-scheduler_@` then evaluation of the
+expression `get_completion_signatures<@_OutSndr_@, Env>()` exits with
+an exception.
+]{.add} Let `op` be an lvalue referring to the operation
state that results from connecting _out_sndr_ to
_out_rcvr_. Calling start(_op_) will
start `sndr` on the current execution agent and execute completion
@@ -1096,7 +1116,7 @@ void start() & noexcept;
[4]{.pnum} _Effects_: Let `@_prom_@` be the object `@_handle_@.promise()`. Associates `@_STATE_@(@_prom_@)`, `@_RCVR_@(@_prom_@)`, and `@_SCHED_@(@_prom_@)` with `*this` as follows:
-- [4.1]{.pnum} STATE(prom) is *this.
+- [4.1]{.pnum} `@_STATE_@(prom)` is `*this`.
- [4.2]{.pnum} `@_RCVR_@(@_prom_@)` is `@_rcvr_@`.
- [4.3]{.pnum} `@_SCHED_@(@_prom_@)` is the object initialized with
`@[scheduler_type]{.rm}@@[start_scheduler_type]{.add}@(@[get_scheduler]{.rm}@@[get_start_scheduler]{.add}@(get_env(@_rcvr_@)))` if that expression is
@@ -1216,11 +1236,8 @@ explicit task_scheduler(Sch&& sch, Allocator alloc = {});
::: add
[?]{.pnum}
-_Mandates_: Let `E` be the type of a queryable.
-If `unstoppable_token
>` is `true`, then
-the type `completion_signatures_of_t, E>`
-only includes `set_value_t()`, otherwise it may additionally include
-`set_stopped_t()`.
+_Mandates_: `Sch` satisfies `@_infallible-scheduler_@>`.
+
:::
[2]{.pnum}
From 88ea2d760008ca08ac399a295dac0286b70663c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dietmar=20K=C3=BChl?=
Date: Sat, 28 Mar 2026 08:37:51 +0000
Subject: [PATCH 5/6] added infallible scheduler and some fixes
---
docs/P3941-affinity.md | 8 ++---
.../task/detail/infallible_scheduler.hpp | 33 +++++++++++++++++++
.../beman/task/detail/inline_scheduler.hpp | 2 ++
include/beman/task/detail/task_scheduler.hpp | 4 ++-
tests/beman/task/task_scheduler.test.cpp | 5 +++
5 files changed, 47 insertions(+), 5 deletions(-)
create mode 100644 include/beman/task/detail/infallible_scheduler.hpp
diff --git a/docs/P3941-affinity.md b/docs/P3941-affinity.md
index 220fc29..0316da9 100644
--- a/docs/P3941-affinity.md
+++ b/docs/P3941-affinity.md
@@ -1,7 +1,7 @@
---
title: Scheduler Affinity
-document: D3941R4
-date: 2026-03-25
+document: P3941R4
+date: 2026-03-26
audience:
- Concurrency Working Group (SG1)
- Library Evolution Working Group (LEWG)
@@ -604,7 +604,7 @@ Add an exposition only concept `@_infallible-scheduler_@` to
::: add
[8]{.pnum} The exposition-only `@_infallible-scheduler_@` concept defines
the requirements of a scheduler type whose `schedule` asynchronous operation
-can only complete with `set_value` unless stop is requested:
+can only complete with `set_value` unless stop can be requested:
```
template
@@ -781,7 +781,7 @@ to the operation state that results from connecting `out_sndr` with
`out_rcvr`. Calling `start(op)` shall
- [9.1]{.pnum} remember the current
-scheduler@[,]{.rm}@@[ which is obtained by]{.add}@ `@[get_scheduler]{.rm}@@[get_start_scheduler]{.add}@(get_env(rcvr))`;
+scheduler[,]{.rm}[ which is obtained by]{.add} `@[get_scheduler]{.rm}@@[get_start_scheduler]{.add}@(get_env(rcvr))`;
- [9.2]{.pnum} start `sndr` on an execution agent belonging to `sch`'s associated
execution resource;
- [9.3]{.pnum}
diff --git a/include/beman/task/detail/infallible_scheduler.hpp b/include/beman/task/detail/infallible_scheduler.hpp
new file mode 100644
index 0000000..40c1716
--- /dev/null
+++ b/include/beman/task/detail/infallible_scheduler.hpp
@@ -0,0 +1,33 @@
+// include/beman/task/detail/infallible_scheduler.hpp -*-C++-*-
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#ifndef INCLUDED_INCLUDE_BEMAN_TASK_DETAIL_INFALLIBLE_SCHEDULER
+#define INCLUDED_INCLUDE_BEMAN_TASK_DETAIL_INFALLIBLE_SCHEDULER
+
+#include
+#include
+#include
+
+// ----------------------------------------------------------------------------
+
+namespace beman::task::detail {
+template
+concept completes_with =
+ ::std::same_as<::beman::execution::completion_signatures,
+ ::beman::execution::
+ completion_signatures_of_t())), Env>>;
+
+template
+concept infallible_scheduler =
+ (::beman::execution::scheduler) &&
+ (::beman::task::detail::completes_with ||
+ (!::beman::execution::unstoppable_token<::beman::execution::stop_token_of_t> &&
+ (::beman::task::detail::
+ completes_with ||
+ ::beman::task::detail::
+ completes_with)));
+} // namespace beman::task::detail
+
+// ----------------------------------------------------------------------------
+
+#endif
diff --git a/include/beman/task/detail/inline_scheduler.hpp b/include/beman/task/detail/inline_scheduler.hpp
index 916db68..c6f4b11 100644
--- a/include/beman/task/detail/inline_scheduler.hpp
+++ b/include/beman/task/detail/inline_scheduler.hpp
@@ -5,6 +5,7 @@
#define INCLUDED_BEMAN_TASK_DETAIL_INLINE_SCHEDULER
#include
+#include
#include
#include
@@ -60,6 +61,7 @@ struct inline_scheduler {
bool operator==(const inline_scheduler&) const = default;
};
static_assert(::beman::execution::scheduler);
+static_assert(::beman::execution::scheduler<::beman::task::detail::inline_scheduler>);
} // namespace beman::task::detail
// ----------------------------------------------------------------------------
diff --git a/include/beman/task/detail/task_scheduler.hpp b/include/beman/task/detail/task_scheduler.hpp
index 6bb83be..b5a5882 100644
--- a/include/beman/task/detail/task_scheduler.hpp
+++ b/include/beman/task/detail/task_scheduler.hpp
@@ -5,6 +5,7 @@
#define INCLUDED_BEMAN_TASK_DETAIL_task_scheduler
#include
+#include
#include
#include
#include
@@ -174,7 +175,8 @@ class task_scheduler {
template >
requires(not std::same_as>) &&
- ::beman::execution::scheduler<::std::remove_cvref_t>
+ ::beman::execution::scheduler<::std::remove_cvref_t> &&
+ ::beman::task::detail::infallible_scheduler<::std::remove_cvref_t, ::beman::execution::env<>>
explicit task_scheduler(S&& s, Allocator = {})
: scheduler(static_cast>*>(nullptr), std::forward(s)) {}
task_scheduler(task_scheduler&&) = default;
diff --git a/tests/beman/task/task_scheduler.test.cpp b/tests/beman/task/task_scheduler.test.cpp
index 31e4a86..d5008a3 100644
--- a/tests/beman/task/task_scheduler.test.cpp
+++ b/tests/beman/task/task_scheduler.test.cpp
@@ -123,6 +123,10 @@ struct thread_context {
struct sender {
using sender_concept = ex::sender_t;
using completion_signatures = ex::completion_signatures;
+ template
+ static consteval auto get_completion_signatures() -> completion_signatures {
+ return {};
+ }
thread_context* ctxt;
thread_context::complete cmpl;
@@ -149,6 +153,7 @@ struct thread_context {
this->condition.notify_one();
}
};
+static_assert(::beman::task::detail::infallible_scheduler>);
enum class stop_result : char { none, success, failure, stopped };
template
From 4e2566d22e904bbeb48f5318c67427f5bc06cebe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dietmar=20K=C3=BChl?=
Date: Sat, 28 Mar 2026 08:41:47 +0000
Subject: [PATCH 6/6] fix CI issues
---
docs/P3941-affinity.md | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/docs/P3941-affinity.md b/docs/P3941-affinity.md
index 0316da9..7e9d72f 100644
--- a/docs/P3941-affinity.md
+++ b/docs/P3941-affinity.md
@@ -568,7 +568,7 @@ algorithm a better name.
During the LEWG discussion on 2026-03-24 it was brought up that
`get_start_scheduler` shouldn't fallback to `get_scheduler`. To
-make proper use of `get_start_scheduler` without that fallback,
+make proper use of `get_start_scheduler` without that fallback,
algorithms current using `get_scheduler` also need to use
`get_start_scheduler` and advertise it appropriately:
@@ -579,7 +579,7 @@ algorithms current using `get_scheduler` also need to use
`get_scheduler`. Since it names the type, the type is also
renamed `start_scheduler_type`.
- `sync_wait` advertises its scheduler using both `get_scheduler`
- and `get_start_scheduler`.
+ and `get_start_scheduler`.
# Wording Changes
@@ -612,11 +612,11 @@ concept @_infallible-scheduler_@ =
scheduler &&
(same_as,
completion_signatures_of_t())), Env>
- > ||
+ > ||
(!unstoppable_token> && (
same_as,
completion_signatures_of_t())), Env>
- > ||
+ > ||
same_as,
completion_signatures_of_t())), Env>
>)