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

    <tr>
        <th>Summary</th>
        <td>
            [libc++] QoI for <type_traits> after 6adbc83ee9e4
        </td>
    </tr>

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

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

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

<pre>
    As reported in https://bugs.freebsd.org/264877, after 6adbc83ee9e4, accidentally including the "wrong" header for `std::swap` can sometimes lead to rather bewildering error messages. E.g.:

```c++
// proper header for std::swap
//#include <utility>

// wrong header for std::swap finds std::swap but fails with undefined hidden symbol: std::__1::enable_if ...
#include <type_traits>

int main() {
  int X1 = 0, X2 = 0;
  std::swap(X1, X2);
  return 0;
}
```

with clang and libc++ 14.0.5 leads to:

```
% clang++ test-type-traits.cpp
ld: error: undefined hidden symbol: std::__1::enable_if<(is_move_constructible<int>::value) && (is_move_assignable<int>::value), void>::type std::__1::swap<int>(int&, int&)
>>> referenced by test-type-traits.cpp
>>>               /tmp/test-type-traits-b34a3a.o:(main)
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
```

This seems to be because 6adbc83ee9e4 ("[libcxx][modularisation] moves <utility> content out of <type_traits>", by @cjdb) moved a bunch of these things to modular headers, but for some reason there is still a partial `swap` declaration in the header:

```c++
template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR_AFTER_CXX17 __swap_result_t<_Tp>
swap(_Tp& __x, _Tp& __y) _NOEXCEPT_(is_nothrow_move_constructible<_Tp>::value &&
                                    is_nothrow_move_assignable<_Tp>::value);
```

It appears to be used in the `__swappable_with` implementation below it, with a comment "ALL generic swap overloads MUST already have a declaration available at this point".

Obviously, users should include the correct headers to get at standards-defined functions, and not expect declarations to get pulled in transitively (e.g. by accident), but the way this particular error is reported is rather ugly.

To make a point, if I comment out the above `swap()` template from `<utility>`, the error message becomes *much* clearer to an end-user, namely:

```
% clang++ test-type-traits.cpp
test-type-traits.cpp:9:8: error: no member named 'swap' in namespace 'std'
  std::swap(X1, X2);
  ~~~~~^
1 error generated.
```

Maybe the two `swap()` declarations can be pulled in from `__utility/swap.h` instead, so you at least get the 'real' swap functions, instead of a HIDDEN_FROM_ABI symbol?

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJytV9uO4jgQ_ZrwYhHlwvWBBxpoLVJPd-8Ms2KfIic24BknjmwHOn-_VU5Chx5m9qJFESSxq1w-deq4SBWrF0tDNC-VtpwRUZCTtaXx4qUXPcKVVkfjHzTnqWG-0kd4FU1Gs-nUi1aEHizXZEJZms1izud85N5mmWC8sFTKGhxmsmKiOBJ74sSLootWBXiJyIlTBtYHpYk3CYxluGa8NBdawjPJaEGMyrkVOTdEwmRiFdEU3GiS8ouQYI1-udbgAiYZeuTGJxv_6KOrYO0F3fckaK7Mix7wat66DZJSqxJc9sK5jaU314viZj-wk3hVWSGFrb14c7NW49Vt86dOyUEUzHx4l1aWHKiQhlyEPZGqYBymQVJOggGexNR5qiTMfrdLkrC54QVNJU_Egfi-3wXSD9bWJU-spsKaDwGLwpKcisKLZl40J960hYcQHNmHYL0mASZ2H7X38XXKLVTRbB82E8FTb5bmttJFz9Cbrj9kph-R234mKQBIC0akSNu8kXDkB_7YscEAHX6W5g6AceOlNbbc2CHiMGxw8LOyza7ETTREwpv_hjyADAAIk-TqzJNMFcbqKrMCRmEIsETcncmZyoo7rKMJXKRnRo0RR-fxJzYI71kJdh3ADd0Jy-Xj6gIWgBtcbUW6u3mLEjrCC7J04JoXGew7rX-B1rvF7Qdob_MSvz-YDtN4RGPqu3xFs4Zs7fK9BN3kQIriO1ROpvIcOYB1AXE5ZvA3YWEAeB0idJXhZHhGcTCcw-7OKqNWqPcl7nJsdxIGDXLkEegJXBlFV301I64mIm_8gBx8e_PGa7jPFask1cI0y4zXBFNnbiUBAiwsiCBRUNXqcKcEwS9kA5D2RkH2jaVICHTECAUpKLITmoHaQUz2BELnAm3XboXFOA8oGygwIJaQQ2pUgWYasECFEVKCw5JqK6h0StsKLOOAvXZ7QNlHeW68_iPxtDwvJbVOW8CPMSTZlVdlEQXkj5Pkafuwen1Nts9P2-dN8sf2y_Zh-7Td_dnM6oZXL89fdpv96-dk-bjbfE5W-304JUmCkSaam0raBGi86q_Q6g2-ggpKkjeE4vpUI5jJ88tmv9q87pKmwAplT1pd7tdn6_u91tri7CTs7z8fV7gp5R_c9wXyLkG3ltCy5FR3BAVysi5RMLeBp3Tig2WBKRWQE57j0euymnKpLkRYhMZVDnX1hKwE9i2fnsiRF3CIZsSdPxC0lgqV9dPXLztCJZCJ1eREzxws-3ShZyhHXJlQi-Q0pFROViK_v4WX9CxUZWSNAUD4sBVzUpVkpDuYcC-Z0ppntqM07vbILXo2FkqfamaGnR4foC4wAkd81AVAHPSgRPtegFcnZSVli5qmhRFWnDk0JcAHDl0CFl_XrLTSisWEQV1o3W4MCydzNdc0GqLfLZmuIamOsr7Z-w5qlX5H4FpoQHgPZHtNgGoXoinAfi1LdwRjJq_lddAqx-HbfmPizmO0v-l-UMQUtktetMyr7AQ_cAIChyBCQAQ6Kl6wIWYCzQuaAxj_1xl6dyReAsuXsxtlLwAZnqcQEgbAINZps_cp5gnfmZJm3L2HYy2a_rtew5tubq5xKxhhC5WjPCDL_F8U3ydapw077UX9mJ0bqmGjCpPfqdalLEm6jEWPaO83NQq6A0zH0I0itaqQ6ZAjYx1jmy55CqUnEZGmWeyzvrXHw4GS37br9eY5efz88ilZPmyvjcpjs40BW8RsHs_pwAor-aI9yFodh4Prd7VtGvCPp9Od1n5Qabm4_XNwBFGpUh84Bw9SnrufIfTU36Am4VEYU3EI_HE8iYLJ4LQ4pEE8z0I6G1PO4zANQzqZB4dwOovT0YjRAQgLlwZjhQgHYhEFEVhGoygMotHMP4RsxrIg5PFoFITBGE5PDh2F9HFh_Icy0AsXA_5zgUEpDJDxOtioMuedf1rZk9KLtciF1fWyYCCHAxf0wkX8F7yOEFY">