Skip to content

Commit fe1d729

Browse files
committed
New issue from Lewis Baker: "get_env() specified in terms of as_const() but this doesn't work with rvalue senders"
1 parent 9a3da04 commit fe1d729

File tree

1 file changed

+163
-0
lines changed

1 file changed

+163
-0
lines changed

xml/issue4175.xml

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
<?xml version='1.0' encoding='utf-8' standalone='no'?>
2+
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
3+
4+
<issue num="4175" status="New">
5+
<title>`get_env()` specified in terms of `as_const()` but this doesn't work with rvalue senders</title>
6+
<section><sref ref="[exec.get.allocator]"/><sref ref="[exec.get.stop.token]"/><sref ref="[exec.get.env]"/>
7+
<sref ref="[exec.get.domain]"/><sref ref="[exec.get.scheduler]"/>
8+
<sref ref="[exec.get.delegation.scheduler]"/><sref ref="[exec.get.fwd.progress]"/>
9+
<sref ref="[exec.get.compl.sched]"/></section>
10+
<submitter>Lewis Baker</submitter>
11+
<date>10 Nov 2024</date>
12+
<priority>99</priority>
13+
14+
<discussion>
15+
<p>
16+
The current specification of `std::execution::get_env()` defines `get_env(o)` as `as_const(o).get_env()`.
17+
However, the `as_const()` function has a deleted rvalue-taking overload, meaning that you cannot pass temporaries to it.
18+
<p/>
19+
This means that several uses of `get_env()` which pass expressions which are either potentially rvalues
20+
(e.g. in definition of `connect(sndr, rcvr)` it uses the expression `get_env(rcvr)`, but `rcvr` could be,
21+
and usually is, a prvalue) or always rvalues (e.g. `scheduler` concept has the expression
22+
<tt>get_env(schedule(std::forward&lt;Sch&gt;(sch)))</tt>).
23+
<p/>
24+
The intent here was that `get_env()` is a function that takes as an argument a <tt>const T&amp;</tt> and thus
25+
allows prvalues to bind to it. We basically just want to require that `get_env()` finds a const-qualified
26+
member-function. The use of `as_const()` does not seem to mirror the semantics of a function with a
27+
<tt>const T&amp;</tt> parameter, so I suggest we change it to something else that expresses the intent.
28+
</p>
29+
</discussion>
30+
31+
<resolution>
32+
<p>
33+
This wording is relative to <paper num="N4993"/>.
34+
</p>
35+
36+
<ol>
37+
<li><p>Add to the end of <sref ref="[exec.general]"/> as indicated:</p>
38+
39+
<blockquote>
40+
<p>
41+
<ins>-?- For a subexpression `expr`, let <tt><i>AS-CONST</i>(expr)</tt> be expression-equivalent to</ins>
42+
</p>
43+
<blockquote><pre>
44+
<ins>[](const auto&amp; x) noexcept -&gt; const auto&amp; { return x; }(expr)</ins>
45+
</pre></blockquote>
46+
</blockquote>
47+
48+
</li>
49+
50+
<li><p>Modify <sref ref="[exec.get.allocator]"/> as indicated:</p>
51+
52+
<blockquote>
53+
<p>
54+
-1- `get_allocator` asks a queryable object for its associated allocator.
55+
<p/>
56+
-2- The name `get_allocator` denotes a query object. For a subexpression `env`, `get_allocator(env)` is
57+
expression-equivalent to <tt><i>MANDATE-NOTHROW</i>(<del>as_const</del><ins><i>AS-CONST</i></ins>(env).query(get_allocator))</tt>.
58+
</p>
59+
</blockquote>
60+
61+
</li>
62+
63+
<li><p>Modify <sref ref="[exec.get.stop.token]"/> as indicated:</p>
64+
65+
<blockquote>
66+
<p>
67+
-2- The name `get_stop_token` denotes a query object. For a subexpression `env`, `get_stop_token(env)` is
68+
expression-equivalent to:
69+
</p>
70+
<ol style="list-style-type: none">
71+
<li><p>(2.1) &mdash; <tt><i>MANDATE-NOTHROW</i>(<del>as_const</del><ins><i>AS-CONST</i></ins>(env).query(get_stop_token))</tt>
72+
if that expression is well-formed.</p></li>
73+
</ol>
74+
</blockquote>
75+
76+
</li>
77+
78+
<li><p>Modify <sref ref="[exec.get.env]"/> as indicated:</p>
79+
80+
<blockquote>
81+
<p>
82+
-1- `execution::get_env` is a customization point object. For a subexpression `o`, `execution::get_env(o)` is
83+
expression-equivalent to:
84+
</p>
85+
<ol style="list-style-type: none">
86+
<li><p>(1.1) &mdash; <tt><i>MANDATE-NOTHROW</i>(<del>as_const</del><ins><i>AS-CONST</i></ins>(o).get_env())</tt>
87+
if that expression is well-formed.</p></li>
88+
</ol>
89+
</blockquote>
90+
91+
</li>
92+
93+
<li><p>Modify <sref ref="[exec.get.domain]"/> as indicated:</p>
94+
95+
<blockquote>
96+
<p>
97+
-2- The name `get_domain` denotes a query object. For a subexpression `env`, `get_domain(env)` is expression-equivalent
98+
to <tt><i>MANDATE-NOTHROW</i>(<del>as_const</del><ins><i>AS-CONST</i></ins>(env).query(get_domain))</tt>.
99+
</p>
100+
101+
</blockquote>
102+
103+
</li>
104+
105+
<li><p>Modify <sref ref="[exec.get.scheduler]"/> as indicated:</p>
106+
107+
<blockquote>
108+
<p>
109+
-2- The name `get_scheduler` denotes a query object. For a subexpression `env`, `get_scheduler(env)` is
110+
expression-equivalent to <tt><i>MANDATE-NOTHROW</i>(<del>as_const</del><ins><i>AS-CONST</i></ins>(env).query(get_scheduler))</tt>.
111+
</p>
112+
</blockquote>
113+
114+
</li>
115+
116+
<li><p>Modify <sref ref="[exec.get.delegation.scheduler]"/> as indicated:</p>
117+
118+
<blockquote>
119+
<p>
120+
-2- The name `get_delegation_scheduler` denotes a query object. For a subexpression `env`,
121+
`get_delegation_scheduler(env)` is expression-equivalent to
122+
<tt><i>MANDATE-NOTHROW</i>(<del>as_const</del><ins><i>AS-CONST</i></ins>(env).query(get_delegation_scheduler))</tt>.
123+
</p>
124+
</blockquote>
125+
126+
</li>
127+
128+
<li><p>Modify <sref ref="[exec.get.fwd.progress]"/> as indicated:</p>
129+
130+
<blockquote>
131+
<p>
132+
-2- The name `get_forward_progress_guarantee` denotes a query object. For a subexpression `sch`, let
133+
`Sch` be `decltype((sch))`. If `Sch` does not satisfy `scheduler`, `get_forward_progress_guarantee` is ill-formed.
134+
Otherwise, `get_forward_progress_guarantee(sch)` is expression-equivalent to:
135+
</p>
136+
<ol style="list-style-type: none">
137+
<li><p>(2.1) &mdash; <tt><i>MANDATE-NOTHROW</i>(<del>as_const</del><ins><i>AS-CONST</i></ins>(sch).query(get_forward_progress_guarantee))</tt>
138+
if that expression is well-formed.</p></li>
139+
</ol>
140+
</blockquote>
141+
142+
</li>
143+
144+
<li><p>Modify <sref ref="[exec.get.compl.sched]"/> as indicated:</p>
145+
146+
<blockquote>
147+
<p>
148+
-2- The name `get_completion_scheduler` denotes a query object template. For a subexpression `q`, the expression
149+
<tt>get_completion_scheduler&lt;<i>completion-tag</i>&gt;(q)</tt> is ill-formed if <tt><i>completion-tag</i></tt>
150+
is not one of `set_value_t`, `set_error_t`, or `set_stopped_t`. Otherwise,
151+
<tt>get_completion_scheduler&lt;<i>completion-tag</i>&gt;(q)</tt> is expression-equivalent to
152+
</p>
153+
<blockquote><pre>
154+
<i>MANDATE-NOTHROW</i>(<del>as_const</del><ins><i>AS-CONST</i></ins>(q).query(get_completion_scheduler&lt;<i>completion-tag</i>&gt;
155+
</pre></blockquote>
156+
</blockquote>
157+
158+
</li>
159+
160+
</ol>
161+
</resolution>
162+
163+
</issue>

0 commit comments

Comments
 (0)