<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/76649>76649</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[Clang] operator== rewrite return type restriction is overly strict
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
ednolan
</td>
</tr>
</table>
<pre>
[over.match.oper](https://eel.is/c++draft/over.match.oper#10) states: "If a rewritten operator== candidate is selected by overload resolution for an operator @, its return type shall be cv bool."
Presumably based on that language, Clang rejects the following code:
```
struct foo {};
template <typename T>
auto operator==(foo, T) { return true; }
void bar() {
0 == foo{};
}
```
With this error:
```
<source>:7:7: error: return type 'auto' of selected 'operator==' function for rewritten '==' comparison is not 'bool'
7 | 0 == foo{};
| ~ ^ ~~~~~
<source>:4:6: note: declared here
4 | auto operator==(foo, T) { return true; }
| ^
```
However, GCC, MSVC and EDG all accept it, as shown in Compiler Explorer here: https://godbolt.org/z/46aaPvn46
I think Clang is being overly restrictive here. The fact that the `operator==` returns `auto` doesn't violate that "its return type shall be cv `bool`," since `auto` is a placeholder for a return type, not a return type itself. The standard seems to make this distinction in [dcl.spec.auto](https://eel.is/c++draft/dcl.spec.auto#general-3):
> A placeholder type can appear with a function declarator in the decl-specifier-seq, type-specifier-seq, conversion-function-id, or trailing-return-type, in any context where such a declarator is valid. If the function declarator includes a trailing-return-type ([dcl.fct]), that trailing-return-type specifies the declared return type of the function. Otherwise, the function declarator shall declare a function. If the declared return type of the function contains a placeholder type, the return type of the function is deduced from non-discarded return statements, if any, in the body of the function ([stmt.if]).
Notice the distinction between "declared return type" (which is `auto` or `decltype(auto)`) and "return type" (which is "deduced from non-discarded return statements [...] in the body of the function").
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJykVk2P2zYQ_TX0ZWBBS9rS-uDD2l6nObQN0KA9U-TIYkORLknZ2R7y24uhvP7KYpuiQdaGRfJx3uN7I8oYzc4hLtl8xeabiRxS58MStfNWuknj9QsN-QOGopdJdYXfY2DzDeOPXUr7yMQT41vGt4i2MJHxrWJ8xfhKB9kmxrf3S7l4KBlfQEwyIS0HxvnHFiQEPAaTEjqgiTL5wMSGiQ0o6bTRMiGYCBEtqoQamhcgbOulhoDR2yEZ76D1AeQFAtisZHwNJkUImIbgIL3sEWInrYUGQR2g8d4WjHNWblj5NH5-ChiHXjb2BRoZUYN3kDqZwEq3G-QOCXRNPyDgn6hShNQhtN5afzRuB8prJHGuMFlVnv7nnzGFQSVovQdWr1i9YWJ1PT1hv7fEmok11exkj_CZiedxWA7J3ynF-GPrPVX2mSRm9erMOQzIxApol6stDt5oaGRg_PG0YHwOAFDCSX6CvKvvjHLLaPz8w6QOUmciYAhU2nsiMLGOfggKiZd4qk9_56U3h8Z4TawZr8G3FycwXt_rUEM7OHU2xMVajNeXOcr3exlM9I6c5XyiYXIDzToLUQOr1_AvkuTx88RvwObP8I3-vUlzxsRTReycT-QS0KisDKihw4AXxFlG_H8nfVsZFfbO2f3kj3iglK7hw3pNXz__9vsapNPwvPkAlBmpFO4TmESjMkLs_NGBcbD2_d5YDPD8dW99wDCSEU9w2yl2XjfepsKHHePbvxnfziopPx3crLou5SN5yH05hcxEaJBylTP_QolPwahkDpi3KeAzxU-qNMaUwsiq8k61qjzJFGkwe6kqQXuMjvE6wcH4nLgMwTh_r2uwqsxWqai_MM4hGqfwGtdEkLC3UmHnrcYw9qZrQJKQbHfzkHoV2nZkFJN0WgYNEbGPkDz08guO8dImJnNyuXHA5iutbBH3qIpcwn_o0rcLudihwyDtVDC-uA-weIanG1q5aCUdyP0eZYAjNQB5SeBo7tyNjcsnQ0-mtJ9pDYZpxL9ICcL5_qny7oAhGu-mr4hTo2nEB0hBGmvcbjrqN30V1TiQ7oXWJvya4EgWgTgoquu6nAgHaY0u4GM79u83a1Z20EiH-dZ2QM1zlL5VKYu-yGyyDd9a8EoxnrXI0b-2gL8tp4BfU4fhaCKO0G9XOtrzBHh1Amd6P7JXFk0ad2_eV2lp7nvLyZioB4Ua2uB7cN5NtYlKBn3ZOL_9e3Qp5tNq6bRO50ZgdO_4DnjUOaY-FaYddS6ujfmLT0bhyPMqGQ2mI-bOz9-iT8ll_PHYGdVR7Vf5pdtDVdKiceLjGI5FjvwiN0XG-XtYtOWPS0EJLoqCzTfv6UAXlTPziV4KvRALOcHlQ12KxaIu52LSLXkj5mUlxMOcz1rBGynbdqE1imYxQy0WE7PkJRcPdB2biXIuCoF60VZqphpZY_Wg2azEXhpbWHvoqVlPTIwDLuuqmi0mVjZoY742cq6oRVNd880kLGn-tBl2kc1Ka2KKF4Rkks13zdzUiejdVW98Ud8a7NzqR3OdXgDjs8kQ7PLu9WJSNzSF8j3jW9r59DXdB08XNca3mQh1wczlnwAAAP__KbKGMg">