<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml" lang="en-CA" xml:lang="en-CA"><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>On the non-uniform semantics of return-type-requirements</title>

<style type="text/css">
body { color: #000000; background-color: #FFFFFF; max-width: 40em; }
del, .del { text-decoration: line-through; color: #8B0040; }
ins, .ins { text-decoration: underline; color: #005100; }

p.example { margin-left: 2em; }
pre.example { margin-left: 2em; }
div.example { margin-left: 2em; }

code.extract { background-color: #F5F6A2; }
pre.extract { margin-left: 2em; background-color: #F5F6A2;
  border: 1px solid #E1E28E; }

p.function { }
.attribute { margin-left: 2em; }
.attribute dt { float: left; font-style: italic;
  padding-right: 1ex; }
.attribute dd { margin-left: 0em; }

blockquote.std, ul.std { color: #000000; background-color: #F1F1F1;
  border: 1px solid #D1D1D1;
  padding-left: 0.5em; padding-right: 0.5em; }
blockquote.std del, blockquote.std .del, ul.std del, ul.std .del { text-decoration: line-through;
  color: #000000; background-color: #FFEBFF;
  border: 1px solid #ECD7EC; }
blockquote.std ins, blockquote.std .ins, ul.std ins, ul.std .ins { text-decoration: underline;
  color: #000000; background-color: #C8FFC8; }
blockquote.stddel { text-decoration: line-through;
  color: #000000; background-color: #FFEBFF;
  border: 1px solid #ECD7EC;
  padding-left: 0.5em; padding-right: 0.5em; }
blockquote.stdins { text-decoration: none;
  color: #000000; background-color: #C8FFC8;
  border: 1px solid #B3EBB3;
  padding-left: 0.5em; padding-right: 0.5em; }

table { border: 1px solid black; border-spacing: 0px;
  margin-left: auto; margin-right: auto; }
th { text-align: left; vertical-align: top;
  padding-left: 0.8em; border: none; }
td { text-align: left; vertical-align: top;
  padding-left: 0.8em; border: none; }

table.table { border-spacing: 2px; border-collapse: separate; }
.table * th, .table * td { border: 1px solid black; }

table.frontmatter { border: 0; border-spacing: 0px; border-collapse: collapse; margin: 0; width: 619px; }
.frontmatter * td, .frontmatter * th { padding: 0px; }
.frontmatter * th { font-weight: inherit; text-align: left; vertical-align: top; }

ul.dash { list-style-type: none; }
ul.dash li:before { content: '\2014'; margin-left: -1em }

span.highlight { background-color: #7FDFFF }

.nowrap { white-space: nowrap; }
.pre { white-space: pre; }

pre { font-family: inherit; }

.subtitle { font-size: 80%; }

#xins1:checked ~ * ins { display: none; visibility: hidden }
#xdel1:checked ~ * del { display: none; visibility: hidden }
#xins2:checked ~ * ins { display: none; visibility: hidden }
#xdel2:checked ~ * del { display: none; visibility: hidden }

code.prettyprint { background-color: #F1F1F1; border-width: 1px; border-style: none dotted; border-color: #787878; padding: 0 0.25em 0 0.25em; white-space: nowrap; }
span.prettyprint { background-color: #F1F1F1; border-width: 1px; border-style: none dotted; border-color: #787878; padding: 0 0.25em 0 0.25em; white-space: nowrap; }
</style>

<script type="text/javascript" src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>
</head>

<body>
<h1>On the non-uniform semantics of <i>return-type-requirement</i>s</h1>
<table class="frontmatter"><tbody>
    <tr>
        <th>Document number:</th>
        <td>P1452R0</td>
    </tr>
    <tr>
        <th>Date:</th>
        <td>2019-01-21</td>
    </tr>
    <tr>
        <th>Project:</th>
        <td>ISO/IEC JTC 1/SC 22/WG 21/C++</td>
    </tr>
    <tr>
        <th>Audience subgroup:</th>
        <td>Evolution</td>
    </tr>
    <tr>
        <th>Revises:</th>
        <td><i>None</i></td>
    </tr>
    <tr>
        <th>Reply-to:</th>
        <td><span class="nowrap">Hubert S.K. Tong</span> &lt;<a href="mailto:hubert.reinterpretcast@gmail.com">hubert.reinterpretcast@gmail.com</a>&gt;</td>
    </tr>
</tbody></table>

<h2>Introduction</h2>
<p>What we have as a <i>return-type-requirement</i> today is a misnomer in both the syntactic and semantic sense.
The Concepts TS introduced two kinds of semantic constraints that syntactically took the form of a <i>trailing-return-type</i>:
the deduction constraint and the implicit conversion constraint.
In the time since, deduction constraints were first changed by the lack of constrained placeholders until the adoption of P1141R1 at the 2018 San Diego meeting
(becoming syntactically different from a <i>trailing-return-type</i>),
and then&#x2014;with P1084R2&#x2014;they ceased to deduce in the manner associated with return type deduction.
The syntactic space occupied by deduction constraints in the Concepts TS is now occupied by something else altogether;
however, the implicit conversion constraint lives on.
Yet the two are both <i>return-type-requirement</i>s, using the <span class="prettyprint"><code>-&gt;</code></span> token.</p>

<p>The inconsistency between the uses of the <span class="prettyprint"><code>-&gt;</code></span> token in the same context seems unfortunate; and
the <i>trailing-return-type</i> form of <i>return-type-requirement</i>, with its current semantics, appears to be easily replaceable.
Its presence in the language seems to be an unnecessary complication that may frustrate future extensions.</p>

<h2><span class="prettyprint"><code>-&gt; </code><i>Type</i></span> versus <span class="prettyprint"><code>-&gt; </code><i>Concept</i></span></h2>
<p>The <span class="prettyprint"><code>-&gt; </code><i>Type</i></span> form of <i>return-type-requirement</i> behaves consistently with the behaviour of
<code class="nowrap">return E;</code> for a function that is declared to return <i>Type</i> except that placeholder types are allowed for
<i>trailing-return-type</i>s in function declarations and not for <i>return-type-requirement</i>s.
That is, the semantics of the various <i>compound-requirement</i>s in</p>
<blockquote><pre class="prettyprint language-cpp"><code
>requires {
  { E } -&gt; </code><i>Type</i><code>;
  { [](</code><i>Type</i><code>) {}(E) };
  { E } -&gt; ConvertibleTo&lt;</code><i>Type</i><code>&gt;;
};</code></pre></blockquote>
<p>are roughly the same. The last form is less aware of the context in terms of access checking, null pointer conversion, and
other cases where perfect forwarding is less-than-perfect. This last form is also the form used by the library in N4791,
the post-San Diego working draft. Note, however, that <code>Same</code> is more often used than <code>ConvertibleTo</code> in N4791.</p>

<p>In contrast, the <span class="prettyprint"><code>-&gt; </code><i>Concept</i></span> form of <i>return-type-requirement</i> most notably does not use a type after
the <span class="prettyprint"><code>-&gt;</code></span> token. It also deduces in a manner different from either of <span class="prettyprint"><i>Concept</i><code> auto</code></span> or
<span class="prettyprint"><i>Concept</i><code> decltype(auto)</code></span> would for a function whose declared return type contains such a placeholder type,
and it does not involve a check for convertibility.</p>

<p>Extending the current <span class="prettyprint"><code>-&gt; </code><i>Type</i></span> case to allow placeholder types would leave us with a problem where the extension
of the current semantics would lead to a difference in the meaning of the first two <i>compound-requirement</i>s in</p>
<blockquote><pre class="prettyprint language-cpp"><code
>requires {
  { E } -&gt; </code><i>Concept</i><code>;
  { E } -&gt; </code><i>Concept</i><code> auto;
  { [](</code><i>Concept</i><code> auto) {}(E) };
};</code></pre></blockquote>
<p>However, we note that the third <i>compound-requirement</i> already expresses a deduction constraint (except that the TS wording causes
access checking, etc. to be ignored).
It would seem that extending from the current semantics of <code>-&gt; </code><i>Type</i> is not very profitable.</p>

<h2>Possibility for a more powerful <span class="prettyprint"><code>-&gt; </code><i>Type</i></span></h2>
<p>Today&#x2019;s placeholder types are limited in context; however, the Concepts TS allowed deduction constraints like</p>
<blockquote><pre class="prettyprint language-cpp"><code
>-&gt; std::vector&lt;Boolean&gt;</code></pre></blockquote>
<p>We note that this sort of &#x201c;type pattern&#x201d; is expressed in the language as a type.
Thus, if we retain <span class="prettyprint"><code>-&gt; </code><i>Type</i></span> with its current semantics, we will not gain the benefit of applying P1084 to such cases if we were to adopt them into the language.</p>
<p>We also note that, if we performed the template argument deduction upon <code>decltype((E))</code> (while requiring that the deduced <code>A</code> is identical to <code>A</code>)
in the style of partial specialization matching instead of applying template argument deduction upon the expression in the style of a call to a function template, then
<span class="prettyprint"><code>-&gt; </code><i>Type</i></span> would have semantics matching that of <span class="prettyprint"><code>-&gt; Same&lt;</code><i>Type</i><code>&gt;</code></span>.
Additional benefits are that <code>-&gt; </code><i>Concept</i><code> auto</code> would work like <code>-&gt; </code><i>Concept</i> does in N4791, and that replacing a concrete type in a
<i>return-type-requirement</i> with a concept that the type models would not cause the <i>compound-requirement</i> to reject previously accepted cases.</p>

<h2>Proposal for C++20: remove <span class="prettyprint"><code>-&gt; </code><i>Type</i></span></h2>
<p>The <span class="prettyprint"><code>-&gt; </code><i>Type</i></span> form of <i>return-type-requirement</i>
is underpowered and does not bring additional expressiveness to the language.
It is on the wrong side of the split between <code>ConvertibleTo</code> and <code>Same</code> as used with <i>compound-requirement</i>s in N4791, and
it introduces complications for future extensions; therefore, it is proposed that the <i>trailing-return-type</i> form of <i>return-type-requirement</i>
be removed. At the same time, it is proposed that <i>trailing-type-requirement</i> is a more appropriate name.</p>
</body></html>
