<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/55664>55664</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
`is_invocable_r` does not work with non-movable return types
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
davidstone
</td>
</tr>
</table>
<pre>
The following valid translation unit
```
#include <functional>
#include <type_traits>
struct non_movable {
non_movable() = default;
non_movable(non_movable &&) = delete;
};
auto function() {
return non_movable();
};
static_assert(std::is_invocable_r_v<non_movable, decltype(function)>);
```
is rejected by clang with libc++ with the message
```
<source>:13:1: error: static_assert failed due to requirement 'std::is_invocable_r_v<non_movable, non_movable ()>'
static_assert(std::is_invocable_r_v<non_movable, decltype(function)>);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
Compiler returned: 1
```
See it live: https://godbolt.org/z/GrPE4vKz9
Presumably, the implementation of `is_invocable_r` is using `std::is_convertible`. However, `is_convertible` uses `std::declval`, which for types other than void produces a reference, and rvalue references do not have guaranteed copy elision. The standard specifies the behavior of `is_invocable_r` in terms of a call to `INVOKE<R>`, where `R` is the return type (https://eel.is/c++draft/meta.rel#lib:is_invocable_r). However, https://eel.is/c++draft/func.require#lib:INVOKE defines `INVOKE<R>` as just doing an implicit conversion from the result of the function to the type `R`.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzNVU2P2zYQ_TXyZRBBlix_HHTYeDdtEaAN0qBXgyZHNlOKdPkhw_n1nZGsrL1JFu2lqEHLIjkczrz3Zrx36tJ8OiK0zhh31vYAvTBaQfTCBiOidhaS1TErHrPi4fpcFtcxTstKW2mSQsiqbZus5FPCZNXT9wzi5YQ7cq9jeLYYniH6JCNYZ3ed68XekP3q7WSxuVnPynVWbsjbIyhsRTIxq35keOeuXA5jOmow4vPJ1eONF36KFB1MCU133kTkMSZv4ZvAXnEZImEqdyIE9JGsQ1RZ9UBDh522vZPsZed3PSF153dL4UrD4NGp55g2jOHtjS-4GZ46gMfPKCMq2F9AGkE8n3U8gtF7mZVvaYzzSFLoMARxwNcYr7bBJS-RL68e5hU_6AvovfP8cpcmtEIbulolBALU419Je-zQRiJk9S8QuKdyPWW_-o-grZ_g9pOtnv7vY4h7PtICB7ToBWkgH9e3rjsRLx5GGSOjBfNXZPQ7IuhImumRTY8xngIjXL6jcXBq70zMnT_Q7At9f_Ifnhb9-y-bWx8fPIbUEe4Xxp3lpruTGcQwNhvXAl17TxktAGk4Be5PNLllVjrbE9-amVwWOfzszkgL7H30c29ATjDc-WDuqedxrnTmfNTySN3QA-shgKMQ6f0oLPSO-uLJO5UkbQiCrUWPVg4KElaBJzck8a_rAZQjzUY4ih7hkAT11IhUCNKdLoBGB0o4B26_pF2rhFcQTih1q-ksY7NHOqopmB-iYiGi7wIbCJDCGK4w2vnl1z9-e0_Fuf3IKp5yo7h48-MVUL7i2sM4W66pe1IRTa4DvVybhPKipdJ612EUuUdDnZ06yDclRlVzR8Q_c8qVl1-bw1fHYx7c5bUdiXuZGYgAn1OIBDbLg4hiRWlJSh2pZ5Sh9a675hvo74Lx4tlU7Ywaz0cYRoTymWoqtak2YhZ1NNh8lwHlKCwm-ez8n2MTpebyZmpTN_CGWfKmeVE1ZJ_2uXQdTYzpp583pDNu2DTVISRkuOp6uVzMjo1QZb1eLhZ1sVi1AutNsVpXcrlZz-Vc1UU1M2KPJjRZTeiWFs8wuKD3rH6c6aYsyrKoy6os63lV5oVcrNflQiyVUlVVy2xRYEcNO-c4uJxnvhlC2qdDoE2SbQzPm9Ru9cEiDteRf_rPPDrfKNKtCtFZnA23N0P0fwOZRplQ">