<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">