Skip to content

Commit f88db0e

Browse files
committed
Add more sender-receiver issues to 4203
1 parent 714a854 commit f88db0e

File tree

1 file changed

+226
-7
lines changed

1 file changed

+226
-7
lines changed

xml/issue4203.xml

Lines changed: 226 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,26 @@
22
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
33

44
<issue num="4203" status="New">
5-
<title>constraints on `schedule_from`'s <i>`get-state`</i> function are incorrect</title>
5+
<title>Constraints on <i>`get-state`</i> functions are incorrect</title>
66
<section><sref ref="[exec.schedule.from]"/></section>
77
<submitter>Eric Niebler</submitter>
88
<date>03 Feb 2025</date>
99
<priority>99</priority>
1010

1111
<discussion>
1212
<p>
13-
Imported from <a href="https://github.com/cplusplus/sender-receiver/issues/313">cplusplus/sender-receiver #313</a>.
13+
Imported from:
14+
<a href="https://github.com/cplusplus/sender-receiver/issues/313">cplusplus/sender-receiver #313</a>
15+
and
16+
<a href="https://github.com/cplusplus/sender-receiver/issues/314">cplusplus/sender-receiver #314</a>.
1417
</p>
1518
<p>
1619
<sref ref="[exec.schedule.from]"/> p6 reads:
1720

1821
<blockquote>
1922
The member <code><i>impls-for</i>&lt;schedule_from_t&gt;::get-state</code>
2023
is initialized with a callable object equivalent to the following lambda:
21-
<pre><code>
22-
[]&lt;class Sndr, class Rcvr&gt;(Sndr&amp;&amp; sndr, Rcvr&amp; rcvr) noexcept(<i>see below</i>)
24+
<pre><code> []&lt;class Sndr, class Rcvr&gt;(Sndr&amp;&amp; sndr, Rcvr&amp; rcvr) noexcept(<i>see below</i>)
2325
requires sender_in&lt;<i>child-type</i>&lt;Sndr&gt;, env_of_t&lt;Rcvr&gt;&gt; {
2426
</code></pre>
2527
</blockquote>
@@ -28,7 +30,74 @@ The constraint should account for the fact that the child sender will
2830
be connected with <code><i>FWD-ENV</i>(get_env(rcvr))</code>.
2931
</p>
3032

31-
<note>The resolution touches the same text as LWG <iref ref="4198"/>.</note>
33+
<note>
34+
The resolution touches some of the same text as LWG <iref ref="4198"/>,
35+
but without conflicting.
36+
</note>
37+
38+
<p>
39+
Imported from:
40+
<a href="https://github.com/cplusplus/sender-receiver/issues/315">cplusplus/sender-receiver #315</a>.
41+
</p>
42+
<p>
43+
<sref ref="[exec.when.all]"/> p6 reads:
44+
45+
<blockquote>
46+
The member <code>impls-for&lt;when_all_t&gt;::<i>get-env</i></code>
47+
is initialized with a callable object equivalent to the following lambda
48+
expression:
49+
<pre><code> []&lt;class State, class Rcvr&gt;(auto&amp;&amp;, State&amp; state, const Receiver&amp; rcvr) noexcept {
50+
return <i>see below</i>;
51+
}
52+
</code></pre>
53+
Returns an object `e` such that
54+
<ol style="list-style-type:none">
55+
<li>(6.1) &mdash; `decltype(e)` models <i>`queryable`</i>, and</li>
56+
<li>(6.2) &mdash; `e.query(get_stop_token)` is expression-equivalent to
57+
<code>state.<i>stop-src</i>.get_token()</code>, and</li>
58+
<li>(6.3) &mdash;
59+
given a query object `q` with type other than <i>cv</i> `stop_token_t`,
60+
`e.query(q)` is expression-equivalent to `get_env(rcvr).query(q)`.
61+
</li>
62+
</ol>
63+
</blockquote>
64+
65+
The problem is in (6.3). It should be forwarding on <i>`forwarding-query`</i>'s
66+
to `get_env(rcvr)` but is is instead forwarding all queries.
67+
</p>
68+
69+
<p>
70+
Imported from:
71+
<a href="https://github.com/cplusplus/sender-receiver/issues/316">cplusplus/sender-receiver #316</a>.
72+
</p>
73+
<p>
74+
The child senders should only see the parent's queries if they are forwarding queries.
75+
</p>
76+
77+
<p>
78+
Imported from:
79+
<a href="https://github.com/cplusplus/sender-receiver/issues/311">cplusplus/sender-receiver #311</a>.
80+
</p>
81+
82+
<p>
83+
<sref ref="[exec.stopped.opt]"/>/para 3 reads:
84+
85+
<blockquote>
86+
Let `sndr` and `env` be subexpressions such that `Sndr` is `decltype((sndr))`
87+
and `Env` is `decltype((env))`.
88+
If <code><i>sender-for</i>&lt;Sndr, stopped_as_optional_t&gt;</code> is `false`,
89+
or if the type <code><i>single-sender-value-type</i>&lt;Sndr, Env&gt;</code>
90+
is ill-formed or `void`,
91+
then the expression `stopped_as_optional.transform_sender(sndr, env)`
92+
is ill-formed; otherwise, it is equivalent to:
93+
</blockquote>
94+
the test for <code>single-sender-value-type&lt;Sndr, Env&gt;</code> is incorrect.
95+
It should be testing its child for single-sender-ness.
96+
</p>
97+
<p>
98+
In addition, it should be applying <i>`FWD-ENV-T`</i> to `Env`
99+
so that only forwarding queries are forwarded.
100+
</p>
32101

33102
</discussion>
34103

@@ -65,8 +134,7 @@ Change <sref ref="[exec.schedule.from]"/> as indicated:
65134
The member
66135
<code><i>impls-for</i>&lt;schedule_from_t&gt;::<i>get-state</i></code>
67136
is initialized with a callable object equivalent to the following lambda:
68-
<pre><code>
69-
[]&lt;class Sndr, class Rcvr&gt;(Sndr&amp;&amp; sndr, Rcvr&amp; rcvr) noexcept(<i>see below</i>)
137+
<pre><code> []&lt;class Sndr, class Rcvr&gt;(Sndr&amp;&amp; sndr, Rcvr&amp; rcvr) noexcept(<i>see below</i>)
70138
requires sender_in&lt;child-type&lt;Sndr&gt;, <ins><i>FWD-ENV-T</i>(</ins>env_of_t&lt;Rcvr&gt;<ins>)</ins>&gt; {
71139
</code></pre>
72140
<p>&hellip;</p>
@@ -86,6 +154,157 @@ except with duplicate types removed.
86154
</p>
87155
</blockquote>
88156
</li>
157+
158+
<li>
159+
Change <sref ref="[exec.let]"/> as indicated:
160+
161+
<blockquote>
162+
<p>
163+
-6-
164+
Let <i>`receiver2`</i> denote the following exposition-only class template:
165+
<pre><code> namespace std::execution {
166+
&hello;
167+
}
168+
</code></pre>
169+
Invocation of the function <code><i>receiver2</i>::get_env</code>
170+
returns an object `e` such that
171+
<ol style="list-style-type:none">
172+
<li>(6.1) &mdash;
173+
`decltype(e)` models <i>`queryable`</i> and
174+
</li>
175+
<li>(6.2) &mdash;
176+
given a query object `q`, the expression `e.query(q)` is expression-equivalent
177+
to
178+
<code><i>env</i>.query(q)</code>
179+
if that expression is valid<del>,</del><ins>;</ins>
180+
otherwise,
181+
<ins>if the type of `q` satisfies <i>`forwarding-query`</i>,</ins>
182+
`e.query(q)` is expression-equivalent to
183+
<code>get_env(<i>rcvr</i>).query(q)</code>
184+
<ins>; otherwise, `e.query(q)` is ill-formed</ins>.
185+
</li>
186+
</ol>
187+
</p>
188+
<p>
189+
-7-
190+
<code><i>impls-for</i>&lt;<i>decayed-typeof</i>&lt;<i>let-cpo</i>&gt;&gt;::<i>get-state</i></code>
191+
is initialized with a callable object [&hellip;]
192+
</p>
193+
<p>
194+
-8-
195+
Let `Sigs` be a pack of the arguments to the `completion_signatures`
196+
specialization named by
197+
<code>completion_signatures_of_t&lt;<i>child-type</i>&lt;Sndr&gt;,
198+
<ins><i>FWD-ENV-T</i>(</ins>env_of_t&lt;Rcvr&gt;<ins>)</ins>&gt;</code>.
199+
Let `LetSigs` be a pack of those types in `Sigs` with a return type of
200+
<code><i>decayed-typeof</i>&lt;<i>set-cpo</i>&gt;</code>.
201+
Let `as-tuple` be an alias template such that
202+
<code><i>as-tuple</i>&lt;Tag(Args...)&gt;</code>
203+
denotes the type <code><i>decayed-tuple</i>&lt;Args...&gt;</code>.
204+
Then `args_variant_t` denotes the type
205+
<code>variant&lt;monostate, <i>as-tuple</i>&lt;LetSigs&gt;...&gt;</code>
206+
except with duplicate types removed.
207+
</p>
208+
</blockquote>
209+
</li>
210+
211+
<li>
212+
Change <sref ref="[exec.when.all]"/> as indicated:
213+
214+
<blockquote>
215+
<p>
216+
-6-
217+
The member <code>impls-for&lt;when_all_t&gt;::<i>get-env</i></code>
218+
is initialized with a callable object equivalent to the following lambda
219+
expression:
220+
<pre><code> []&lt;class State, class Rcvr&gt;(auto&amp;&amp;, State&amp; state, const Receiver&amp; rcvr) noexcept {
221+
return <i>see below</i>;
222+
}
223+
</code></pre>
224+
Returns an object `e` such that
225+
<ol style="list-style-type:none">
226+
<li>(6.1) &mdash; `decltype(e)` models <i>`queryable`</i>, and</li>
227+
<li>(6.2) &mdash; `e.query(get_stop_token)` is expression-equivalent to
228+
<code>state.<i>stop-src</i>.get_token()</code>, and</li>
229+
<li>(6.3) &mdash;
230+
given a query object `q` with type other than <i>cv</i> `stop_token_t`
231+
<ins>and whose type satisfies <i>`forwarding-query`</i></ins>,
232+
`e.query(q)` is expression-equivalent to `get_env(rcvr).query(q)`.
233+
</li>
234+
</ol>
235+
</p>
236+
<p>
237+
-7-
238+
The member <code><i>impls-for</i>&lt;when_all_t&gt;::<i>get-state</i></code>
239+
is initialized with a callable object equivalent to the following
240+
lambda expression:
241+
<pre><code> []&lt;class Sndr, class Rcvr&gt;(Sndr&amp;&amp; sndr, Rcvr&amp; rcvr) noexcept(e) -&gt; decltype(e) {
242+
return <i>e</i>;
243+
}
244+
</code></pre>
245+
where <i>e</i> is the expression
246+
<pre><code> std::forward&lt;Sndr&gt;(sndr).apply(<i>make-state</i>&lt;Rcvr&gt;())
247+
</code></pre>
248+
and <i>`make-state`</i> is the following exposition-only class template:
249+
<pre><code> template&lt;class Sndr, class Env&gt;
250+
concept max-1-sender-in = sender_in&lt;Sndr, Env&gt; &amp;&amp; <i>// exposition only</i>
251+
(tuple_size_v&lt;value_types_of_t&lt;Sndr, Env, tuple, tuple&gt;&gt; &lt;= 1);
252+
253+
enum class <i>disposition</i> { <i>started</i>, <i>error</i>, <i>stopped</i> }; <i>// exposition only</i>
254+
255+
template&lt;class Rcvr&gt;
256+
struct make-state {
257+
template&lt;max-1-sender-in&lt;<ins><i>FWD-ENV-T</i>(</ins>env_of_t&lt;Rcvr&gt;<ins>)</ins>&gt;... Sndrs&gt;
258+
</code></pre>
259+
&hellip;
260+
</p>
261+
<p>
262+
-8- Let <i>`copy_fail`</i> be `exception_ptr` if [&hellip;]
263+
</p>
264+
<p>
265+
-9-
266+
The alias `values_tuple` denotes the type
267+
<pre><code> tuple&lt;value_types_of_t&lt;Sndrs, <ins><i>FWD-ENV-T</i>(</ins>env_of_t&lt;Rcvr&gt;<ins>)</ins>, <i>decayed-tuple</i>, optional&gt;...&gt;
268+
</code></pre>
269+
if that type is well-formed; otherwise, <code>tuple&lt;&gt;</code>.
270+
</p>
271+
</blockquote>
272+
</li>
273+
274+
<li>
275+
Change <sref ref="[exec.into.variant]"/> as indicated:
276+
277+
<blockquote>
278+
-5-
279+
The member <code>impls-for&lt;into_variant_t&gt;::<i>get-state</i></code>
280+
is initialized with a callable object equivalent to the following lambda:
281+
<pre><code> []&lt;class Sndr, class Rcvr&gt;(Sndr&amp;&amp; sndr, Rcvr&amp; rcvr) noexcept
282+
-&gt; type_identity&lt;value_types_of_t&lt;<i>child-type</i>&lt;Sndr&gt;, <ins><i>FWD-ENV-T</i>(</ins>env_of_t&lt;Rcvr&gt;<ins>)</ins>&gt;&gt; {
283+
return {};
284+
}
285+
</code></pre>
286+
</blockquote>
287+
</li>
288+
289+
<li>
290+
Change <sref ref="[exec.stopped.opt]"/> as indicated:
291+
292+
<blockquote>
293+
-3-
294+
Let `sndr` and `env` be subexpressions such that `Sndr` is `decltype((sndr))`
295+
and `Env` is `decltype((env))`.
296+
If <code><i>sender-for</i>&lt;Sndr, stopped_as_optional_t&gt;</code> is `false`,
297+
or if the type <code><i>single-sender-value-type</i>&lt;<ins><i>child-type</i>&lt;</ins>Sndr<ins>&gt;</ins>, <ins><i>FWD-ENV-T</i>(</ins>Env<ins>)</ins>&gt;</code>
298+
is ill-formed or `void`,
299+
then the expression `stopped_as_optional.transform_sender(sndr, env)`
300+
is ill-formed; otherwise, it is equivalent to:
301+
<pre><code> auto&amp;&amp; [_, _, child] = sndr;
302+
using V = <i>single-sender-value-type</i>&lt;<ins><i>child-type</i>&lt;</ins>Sndr<ins>&gt;</ins>, <ins><i>FWD-ENV-T</i>(</ins>Env<ins>)</ins>&gt;;
303+
</code></pre>
304+
&hellip;
305+
</blockquote>
306+
</li>
307+
89308
</ol>
90309

91310
</resolution>

0 commit comments

Comments
 (0)