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

    <tr>
        <th>Summary</th>
        <td>
            Clang doesn't recognize friend operator!= to resolve ambiguity in operator==
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang,
            c++20
      </td>
    </tr>

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

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

<pre>
    https://godbolt.org/z/abdvexjo7
```cpp
struct S {
    operator int();
    friend bool operator==(const S &, int);
 friend bool operator!=(const S &, int);
};

struct A : S {};
struct B : S {};

bool x = A{} == B{}; // ambiguous!!
```

Adding a decl for `operator!=` to the **namespace scope** makes it work fine: https://godbolt.org/z/ndrEeY68G
```cpp
struct S {
    operator int();
    friend bool operator==(const S &, int);
    friend bool operator!=(const S &, int);
};

bool operator!=(const S &, int);

struct A : S {};
struct B : S {};

bool x = A{} == B{};
```

According to [P2468R2 - The Equality Operator You Are Looking For](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2468r2.html)

A non-template function or function template F named operator== is a rewrite target with first operand o unless a search for the name operator!= in the scope S from the instantiation context of the operator expression finds a function or function template that would correspond ([basic.scope.scope]) to F if its name were operator==, **where S is the scope of the class type of o if F is a class member, and the namespace scope of which F is a member otherwise**. A function template specialization named operator== is a rewrite target if its function template is a rewrite target.

It feels like for `friend` functions (which are class member), `S` is namespace scope. A lookup in the namespace scope does not find a matching `operator!=` unless declared outside the class scope.

The need to add a re-decl of the friend outisde class scope looks unreasonable to me. This looks to me as an oversight to me while considering this. 

That said, I think it should be reasonable for clang to accept `friend operator!= in class scope` as an extension.
cc: @zygoloid @AaronBallman 
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMVk1v4zYT_jX0ZRBDor_igw92snqxwAu0aPayR4ocWdxQHJWk4iS_vhhKSRxvul3soShgKMp8aZ5nPkgVoz16xJ1YHYSUQ3zcroSUYnU7U0NqKeyyaFaTedq1KfVRLPZCVkJWRzI1uTSncBSyehayUrV5wMdvtBHFrSj2Yl2MP933oySmMOgEdyA2h1ECAEA9BpUogPVJyGsht2Jxpm6CRW-gJnKvpmJxyz95rcnHHFCuhbwZI5y5f-gry5_xFZvbt_fz7PcgFvsJw5nNpD18rB2fOY9HEItb2I8GMCKBw6s9jOyC6mp7HGiInK8sLyg9j7o3xvojKDCoHTQUQKyLC7TrAhJBahGE3Au596rD2CuNEDX1OAqhU_cYwSY4UbiHxnpkMP9Udm_CJ_y6vv7ff6bsf-f-q5X_pSj_Ys_8qDm0ppD7IxGI1eF3uVxf_yHhCr60CJ_-HJSz6Ql-eynGVxpgHxD-T3TPXhUFsWK077vgdDrNqUd_FZOZWuFb0qWQVdRSssGR27YypKOQVa96DPwii6ztOYsg523qHJN2njB48lcJu96phNAMXidLHii8vb9qK-BGNhcNAjaCgoCnYBNCUuGICU42tdDYENNo7Q0QDN5hZOOIKug2Dw8PCUe9KDhYn1V5XuAOmkBdFlgfk_LJqpyaJp_wMQE1Wfna5PjYB4yRTRrrDX_zx9BSq3gOB2dAUwgYe_IGeFBWh1pFq-c5k_GZS7TlEldgG7ApjhBOGPC76bmZdsCpZe0ds_UGbMpbOxUjpKdRQhy0GmkdNR12NQaOxUS-UHa2Udjt1FrdvviNHkCpxXCycVo5c9h_gD32qK1y9nnk9KdrPEH_PuAHxvPzpvucoEF0EZy9x5cVOq4QXp0vASPzP6JSAS-o2GZm18Ude9h4SQgjdUT3Q__SSZeMGcIInlJuEGZMJd3yDH64zqfW5Z2vAtMzpGgNnlVv_Ow5TB55j2i4UZQxmZOrfGpMZZ-2Jg3JRvMuTs49wuADqkhe1Q45Sodz-NLaOKmzBFQE5YEeMER7bNMkPbXWIc8HpxnyRmptnMP7BFWCqKxhLj-zgb_n8yi2eRBqhLPPc5m0U-NqU1pjn97K9sH0nqFhAscs8TGh57GciNKad7FYFs9PR3JkDb_vVSB_UM51ysPM7BZmu9iqGe7K9fZaLuWyLGftrrlembKQZaOabbEx2-3GGL1Zq3W5kuVqqWZ2Jwu5KAu5KpdFUZZzs21qI1cKV0Wz2dQolgV2yrq5cw8dr9WZjXHA3aaQZTFzqkYXp5taBs43NXnD_wl5EPIgi-nuFnYc4aoejlEsC2djim8xk00OdzeZOe45L-QmQUBNR2-f35rgPYGJIGAk94DT1YSPDesvxnI2BHd5T7SpHeq5pk7IipOY_lz1gb6hTkJWGSUfDxnoXwEAAP__UWJO1A">