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

    <tr>
        <th>Summary</th>
        <td>
            ADL can be disabled for make_error_code
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
      </td>
    </tr>

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

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

<pre>
    As far as I can tell this code is correct, and `user::Err` is defined as program-defined error code enums should be, but it fails with libc++:

```c++
int make_error_code; // (1)
#include <system_error>
namespace user {
  enum Err { };
  std::error_code make_error_code(Err); // (2)
}
template<> struct std::is_error_code_enum<user::Err> : std::true_type { };
std::error_code e( user::Err{} );
```

Unqualified name lookup in `error_code`'s constructor finds the global `int` at (1), and because that's not a function, ADL is suppressed, so (2) is not found.

The same problem exists for `make_error_condition` of course.

The solution is to ensure that `std::make_error_code` (or some other function with that name) is found first by unqualified name lookup, so that ADL won't be disabled. However, note the proposed resolution for [LWG 3629](https://wg21.link/lwg3629) which is not approved yet, but is LWG's preferred solution.

The way to implement the proposed resolution for LWG3629 and fix the example above is:

```c++
namespace std {
namespace __adl_only { std::error_code make_error_code() = delete; } // (3)
template<class ErrorCodeEnum>
requires is_error_code_enum_v<ErrorCodeEnum>
error_code::error_code(ErrorCodeEnum e)
{
  using __adl_only::make_error_code; // (4)
  error_code ec = make_error_code(e); // (5)
  assign(ec.value(), ec.category());
}
}
```
The using-declaration at (4) means that unqualified name lookup at (5) finds (3) and doesn't look in enclosing namespaces, so never finds the global `int` that suppressed ADL. Next, (5) does ADL, which finds the user's overload as they intended, and everything works correctly.



</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyNVk1v4zgM_TXORZjAsfPRHHxom87uAoM97WKPgWzTiaaKldFHU__7fZTjOGk6gwHc2JVE8vGRfHZp6q54dKKRVkgn_hKVbIUnrYXfKycqU5OId2up8kn2LGRbi2SZBkc2yR9xvViL__lUTY1qqWZHR2t2Vh6-DEtkrbG9O2rDwQm3N0HXoiT2WQYvlAcIpZ04Kb8XWpVVkj3xhSDpJkmH32XaX8N2XFWtFwf5StsYZ8txkvxJJNlXXLg9zJJsfXaQ5aqtdACSJH92nfN06M2S_KU_0soDuaOsSHCWIlmdo4iIXSBhXsPfBkGGLefrno8Rwh2k7IHJApIbbNmIDR7jAzAdtfRI4hmo4NuGyo8hlLvyumVQOHhbEVjhaTSBB9r67kh30D8DzlDFrUOQsNqIHvyHUlzX59_2R5BaNQpFZx6FNuY1HIVquWuuuIBZtuLOavvs0B5oldqh8UjstCmlZgtUlrtL-ksVzz1YUiWBEMelj55a44UUTWgrr0zLxx4337gtXTgeLTlHNS86M3DOe2zUmNDW0-sk_gEEx-DRxqWmg6B35TymBCCB5qasba1iPIA0DdIJ1tG9M6MDn-KQ3qCNXLA9dPZ3qcDHfoFPYEVQZwDGgBl7SbCfk-iCeT7nE3MBkdZ5UXYifF6NMw_RmEk6MV8rWJColZNIuZ6KP82J3tABOAuWKNYFfBwNiBTgc0gpkrJ4-vbfHyJfoj6LDTDvvT86Tip2-WmXzaZata941qddPAa8p72q9kMVJIpk3uC6I3_RBCfgNlYXFWzADPaHwHckn2TH5CqMDh0IivArxPDLMGIrNeo9nqV3ybZClgCC4L8lPaNYoIyjVozL262s9da0uouj93s6wfQk-QaSqsn3Whanb9CM_KIZV1JRaekcy5Oxz3DzEnXhrGmWfgQFDsS9dmzfYPu51bWc3mLutWw0Ycm4qNhFFINT7e6Kgc_b_EYN5xc_QlwrUhX5uGeK7vR0ceUBhKhdy8eq6ZvU4cwtNxhWKvC2M7YbFq-0bVDi8eFW7bjhYnZ4xYF3K2Nn9TLFKYgDydb1I_aTKTyfZrhn6TsXNjZlbcj1U8mnWT8Jry0TCb00lztPcsuT-iv9jDhGIeSpn4q_6T2O2gCCQ_IOr_WzOXqMLwMeRIyG1UbGtzw2OiDz1Na9uDJwhtLh6wE4T8a-Xj4edHczsf3vhIrZcpktHmbLh3RSF3m9ztdy4pXXVLA08ffIlSzF2f3QBJNgdXErODtoYyinlTmw4ui34fYFcvA9fsh8Vc4F5u_rYrWczSf7YjWjtF7O5-lDvarSNM_SZj4v5WKRLarVfJ1PtCxJuwJaB42bqCJLsyxdp6ssncFqulg0aIX5rFlQ2izXZTJP6YAvmikHnhq7m9giYijDzmFT8ytl3Ow7lWjwL4PfG1t8PyFZ3U0i3CJi_R9HOwwo">