title: Why does std::is_invocable_r reject functions returning non-moveable types?
body: <p>I'm curious about the definition of <code>std::is_invocable_r</code> and how it interacts with non-moveable types. Its libc++ implementation under clang in C++20 mode seems to be wrong based on my understanding of the language rules it's supposed to emulate, so I'm wondering what's incorrect about my understanding.</p>
  <p>Say we have a type that can't be move- or copy-constructed, and a function that returns it:</p>
  <pre class="lang-cpp prettyprint-override"><code>struct CantMove {
    CantMove() = default;
    CantMove(CantMove&amp;&amp;) = delete;
  };
  
  static_assert(!std::is_move_constructible_v&lt;CantMove&gt;);
  static_assert(!std::is_copy_constructible_v&lt;CantMove&gt;);
  
  CantMove MakeCantMove() { return CantMove(); }
  </code></pre>
  <p>Then it's possible to call that function to initialize a <code>CantMove</code> object (I believe due to the copy elision rules):</p>
  <pre class="lang-cpp prettyprint-override"><code>CantMove cant_move = MakeCantMove();
  </code></pre>
  <p>And the type traits agree that the function is invocable and returns <code>CantMove</code>:</p>
  <pre class="lang-cpp prettyprint-override"><code>using F = decltype(MakeCantMove);
  static_assert(std::is_invocable_v&lt;F&gt;);
  static_assert(std::is_same_v&lt;CantMove, std::invoke_result_t&lt;F&gt;&gt;);
  </code></pre>
  <p>But <code>std::is_invocable_r</code> says it's <em>not</em> possible to invoke it to yield something convertible to <code>CantMove</code>, at least in C++20 under clang:</p>
  <pre><code>static_assert(!std::is_invocable_r_v&lt;CantMove, F&gt;);
  </code></pre>
  <hr />
  <p>The <a href="https://timsong-cpp.github.io/cppwp/n4868/meta.rel#lib:is_invocable_r" rel="noreferrer">definition</a> of <code>std::is_invocable_r</code> is</p>
  <blockquote>
  <p>The expression <code>INVOKE&lt;R&gt;(declval&lt;Fn&gt;(), declval&lt;ArgTypes&gt;()...)</code> is well-formed when treated as an unevaluated operand</p>
  </blockquote>
  <p>with <code>INVOKE&lt;R&gt;</code> being <a href="https://timsong-cpp.github.io/cppwp/n4868/function.objects#func.require-2" rel="noreferrer">defined</a> as</p>
  <blockquote>
  <p>Define <code>INVOKE&lt;R&gt;(f, t1, t2, …, tN)</code> as [...] <code>INVOKE(f, t1, t2, …, tN)</code> implicitly converted to <code>R</code>.</p>
  </blockquote>
  <p>and <code>INVOKE</code> <a href="https://timsong-cpp.github.io/cppwp/n4868/function.objects#func.require-1.7" rel="noreferrer">defined</a> (in this case) as simply <code>MakeCantMove()</code>. But the <a href="https://timsong-cpp.github.io/cppwp/n4868/conv.general#3" rel="noreferrer">definition</a> of whether an implicit conversion is possible says:</p>
  <blockquote>
  <p>An expression <code>E</code> can be implicitly converted to a type <code>T</code> if and only if the declaration <code>T t=E;</code> is well-formed, for some invented temporary variable <code>t</code> ([dcl.init]).</p>
  </blockquote>
  <p>But we saw above that <code>CantMove cant_move = MakeCantMove();</code> is accepted by the compiler. <strong>So is clang wrong about accepting this initialization, or is the implementation of <code>std::is_invocable_r_v</code> wrong?</strong> Or is my reading of the standard wrong?</p>
  <p>For the record, the reason I care about this question is that types like <code>std::move_only_function</code> (I'm using an advanced port to C++20 of this) have their members' overload sets <a href="http://eel.is/c++draft/func.wrap.move.ctor#1" rel="noreferrer">restricted</a> by <code>std::is_invocable_r_v</code>, and I'm finding that it's not possible to usefully work with functions that return a no-move type like this. Is that by design, and if so why?</p>