<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">