<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/150376>150376</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Name lookup in operator's requires-clause causes constraint recursion
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          ckwastra
      </td>
    </tr>
</table>

<pre>
    This issue was previously discussed [here](https://github.com/llvm/llvm-project/issues/62096#issuecomment-2162063813), but I couldn't find a dedicated issue to track it, so I decided to open this one. Feel free to close this if it turns out to be a duplicate. Test [code](https://godbolt.org/z/fsafqeqMj):

```cpp
namespace N {
struct S {};
} // namespace N
using namespace N;

template <class T>
void operator+(T t1, T t2)
  // Trailing requires-clause
  requires(!requires { t1 + t2; });
void test_operator_trailing() {
  // - GCC, MSVC: OK
  // - Clang: error: satisfaction of constraint
  //   '!requires { t1 + t2; }' depends on itself
  S{} + S{};
}

template <class T>
  // Leading requires-clause
  requires(!requires(T t1, T t2) { t1 - t2; })
void operator-(T, T);
void test_operator_leading() {
  // - GCC, MSVC: OK
  // - Clang: error: satisfaction of constraint
  //   '!requires (T t1, T t2) { t1 - t2; }' depends on itself
  S{} - S{};
}

template <class T>
void f(T t1, T t2)
  // Trailing requires-clause
  requires(!requires { f(t1, t2); });
void test_function_trailing() {
  // GCC, MSVC, Clang: OK
 f(S{}, S{});
}

template <class T>
  // Leading requires-clause
 requires(!requires(T t1, T t2) { g(t1, t2); })
void g(T, T) {}
void test_function_leading() {
  // GCC, MSVC, Clang: OK
  g(S{}, S{});
}
```

I'm not sure whether the position of the *requires-clause* (leading vs. trailing) is supposed to significantly affect behavior, though in the examples above, all three major compilers seem to treat them the same way.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzEVk1v4zYT_jX0ZWBDomLLPuhgO69fLNrdHmL0uqCokcUNJSqcodP01xeUrHx1N2mKFgUESeRwvp5nyKEiMqcOsRDLnVhez1TgxvlC394rYq9mpaseimNjCAxRQLhXBL3Hs3GB7ANUhnQgwgrEctegR7G8FnLdMPcksq2QByEPJ8NNKBfatUIerD1Pn3nv3TfULORhME5CHlYy2ayEzIYJ7doWO57LdCWTVbZOMyE3Qu6hDAyfQLtgq07InKE2XQUKKqyMVozVJVp2wF7pWzAc1cjBJ6hQmwqrKHM9dsAxOdfhAg6IFmqPg562jnAUmhoMAwffEbjAUVpi9BZ6O7hbwBGJIwTaVd-HwFWls7xw_iTk4XchDzWp-g7vPn-LKWVbkQzPKhkf3fci2XaqReqVRvgCIt-JZEvsg2a4GYb5tcjipMivYXQDzzREsg1kutOLuXF9smVse6sYQWR7bRURHEX2P5Fsz85UERev2Hkhd0Kuj8BpRO8ILGOwyRYmd0evjI0-PN4F45Hm2qpAOKyZ5oRcC5lOoxg5cApC7qK9bAcxj4jBbnLPSPx1iuErX3wMZjYXHB4jmMP_9_sY3eebX_ci28IvP70U763qTlGA3jsff0ixoVppNq4DV4N2XSx10_FzzfiTvx93DhX22FWxhMAwoa0HKzcjQcPym1dkvUPBYwg_o6o-Bu6f2ZrCnr8E-xXR86g4aL3FhB3j-c-J-GtJvsfM_KO8DIjU_86GiGZHo6PJH26LOnQDXu9si-dcyP0T9iMp0duUvNw_4jB5-2dK9EMVevph_pfkT88rdDr9vgvMm1X6Ni6Dl_eBmQ7pEaRPQuYtdI6Bgke4b5Ab9MANQu_ITMUdx0JuXwMlt7GeLzHDmRbwROwGDAGFvnc09qvYqk1ttOrYPoCqa9QMJTbqbOJhvQduXDg1YLrBHf6m2t4igSrdGaNcWQvcxA7Xqm_Og3Ztbyx6AkJsx3aJiqN2O5gg1cae_7CYVUVWbbKNmmGR5sssy9Z5up41RVKVpU429QoTTJdVuonfdXIl67LeVGU9M4VM5DLJ5VWyytLlelGXqlblJiuXWZ4iXomrBFtl7CLeCWKHnA3Nu0iXSZavZlaVaGm4n0jZ4f3Y2oWU8brii-EiUYYTiavEGmJ6MsOGLRZfYgrWudvQR2CeeltOr8sWdHzTs4MIPOrgybhuFrwt_v695pLMuZB_BAAA__-BvNpA">