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

    <tr>
        <th>Summary</th>
        <td>
            On instantiation failure of swap with a const-qualified type, provide hint if the corresponding const-removed type is swappable
        </td>
    </tr>

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

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

    <tr>
      <th>Reporter</th>
      <td>
          varungandhi-src
      </td>
    </tr>
</table>

<pre>
    (I'm not 100% sure if this implementable, e.g. with a `static_assert` or some deduction guides in libc++, but suggesting it as a libc++/Clang improvement if it is.)

When trying to sort some values, it is not too hard to accidentally end up trying to sort values for a type that is const-qualified (e.g. because you're trying to sort a field which is a vector inside a const method). In such a case, the `const` is not necessarily in your face (e.g. because the method is long, and the `const` is part of the declaration). In such a situation, the error message is not very helpful. Here is an example:

```
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__algorithm/sort.h:78:9: error: no matching function for call to 'swap'
        swap(*__x3, *__x4);
 ^~~~
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__algorithm/sort.h:295:20: note: in instantiation of function template specialization 'std::__sort4<(lambda at indexer/Driver.cc:590:42) &, const scip_clang::Path *>' requested here
            _VSTD::__sort4<_Compare>(__first, __first+1, __first+2, --__last, __comp);
 ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__algorithm/sort.h:518:16: note: in instantiation of function template specialization 'std::__sort<(lambda at indexer/Driver.cc:590:42) &, const scip_clang::Path *>' requested here
 _VSTD::__sort<_Comp_ref>(_VSTD::__unwrap_iter(__first), _VSTD::__unwrap_iter(__last), _Comp_ref(__comp));
 ^
indexer/Driver.cc:590:13: note: in instantiation of function template specialization 'absl::c_sort<const std::vector<scip_clang::Path>, (lambda at indexer/Driver.cc:590:42)>' requested here
 absl::c_sort(this->indexPartPaths, [](const Path &p1, const Path &p2) -> bool {
 ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__utility/swap.h:36:85: note: candidate template ignored: requirement 'is_move_constructible<const scip_clang::Path>::value' was not satisfied [with _Tp = const scip_clang::Path]
inline _LIBCPP_INLINE_VISIBILITY __swap_result_t<_Tp> _LIBCPP_CONSTEXPR_AFTER_CXX17 swap(_Tp& __x, _Tp& __y)
 ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__utility/pair.h:374:1: note: candidate template ignored: could not match 'pair<type-parameter-0-0, type-parameter-0-1>' against 'const scip_clang::Path'
swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__utility/swap.h:45:1: note: candidate template ignored: could not match '_Tp[_Np]' against 'const scip_clang::Path'
swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) {
^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/tuple:184:6: note: candidate template ignored: could not match '__tuple_leaf<_Ip, type-parameter-0-1, >' against 'const scip_clang::Path'
void swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
 ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/tuple:1120:1: note: candidate template ignored: could not match 'tuple<type-parameter-0-0...>' against 'const scip_clang::Path'
swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__memory/compressed_pair.h:191:6: note: candidate template ignored: could not match '__compressed_pair<type-parameter-0-0, type-parameter-0-1>' against 'const scip_clang::Path'
void swap(__compressed_pair<_T1, _T2>& __x, __compressed_pair<_T1, _T2>& __y)
 ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__memory/unique_ptr.h:567:1: note: candidate template ignored: could not match 'unique_ptr<type-parameter-0-0, type-parameter-0-1>' against 'const scip_clang::Path'
swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT {__x.swap(__y);}
^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__memory/shared_ptr.h:1271:1: note: candidate template ignored: could not match 'shared_ptr<type-parameter-0-0>' against 'const scip_clang::Path'
swap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __y) _NOEXCEPT
^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__memory/shared_ptr.h:1561:1: note: candidate template ignored: could not match 'weak_ptr<type-parameter-0-0>' against 'const scip_clang::Path'
swap(weak_ptr<_Tp>& __x, weak_ptr<_Tp>& __y) _NOEXCEPT
^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/variant:1721:6: note: candidate template ignored: could not match 'variant<type-parameter-0-0...>' against 'const scip_clang::Path'
auto swap(variant<_Types...>& __lhs,
 ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__functional/function.h:1235:1: note: candidate template ignored: could not match 'function<type-parameter-0-0 (type-parameter-0-1...)>' against 'const scip_clang::Path'
swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT
^
```

The main part is kinda' hidden in the middle.

```
requirement 'is_move_constructible<const scip_clang::Path>::value' was not satisfied [with _Tp = const scip_clang::Path]
```

If possible, maybe there could be a check at the end of the chain which ends up with something like: 
1. Check if the type has a `const` on it (`std::is_const<T>::value`)
2. Check if the type without `const` is swappable (`std::is_swappable<std::remove_const<T>>::value`)

If both 1 and 2 are true, then emit an error saying that the likely problem is that the const qualifiers should be removed.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzUWV1z2zrO_jXMDScaiYq_LnzhOPEcz3veNnPqOZu94tASbHFLiSpJOfVe9LfvgJTkj3xst2l3jzMZ2xKhhyAeAAQFYa3cVgBTMrglg7sr0bhCm-lOmKbaiiov5LU12dVa5_spYeMlYaOSVtrRJI4JG1DbGKByQ10hLZVlraCEyom1AsLmFKJtRJ-kK6igZBhbJ5zMuLAWjCPDmGpDrS6B5pA3mZO6ottG5mCprKiS64ywW_8_p-vGUdtst2CdrLZUOiosFSdCi7kSOFTWRu-8GqiYdFTaiLAJie9IPAuffyugos7sEcpparVxQZGdUA1YnNA_51fqtKaFMDlKiiyTOS5QqT2FKqdNfY4TIOhGGyqo29dAXSE8WKYr666_NELJjYScEjb2BlpDJhoLdK8bwkYGzhEF3UhQOX0qZFYgkKA7yJw2VFZW5kBFgKYluELnhE0iuqyobTK0eyas58IVgBx4SbR9u7oKMrBWGKn2aPW9bgzdiAyeaYfPhwnwUaWrLaKKKn8JuRbGUb3xQzlkShiB9J6pZqVr2vtBPzBGG1qiQlvoNNyB2dMCVL1pVER_A-NHREXhq0CHI-nsmFsyjNv_cMkWs7pWMvMTWcIWj5nOIRJ1jS6jKweVw9t3sAOlazCELR6UcBttSrz__yL7-OkxqttbZ5Kf7v7vIJSkURLZ_DNhi8biqKwy1eRA2OLgpbuEsAXnQm21ka5AQGQ5Kkg6G41JOpuQdBYsgT8qTUvhsgIdYtNUIUrQuTKhFLoIYSP7JGrCRmHBtP0LN8eEzTj_mqKFw88bjIX0thUmg_tv375doKnYZICfcbCRQy9A_5WVdaJy0i8BPbC3mYMSFQNqa8ikUPKfQQbt53J0onTGOeLfkHRO2FiJcp0LirFb5fDVr-HOyB2YKMtIOhtMcPIbRtiEEjZEC4cwtJmseYbJKKA-CFeg8Ul6T9iIGvjSgHWQ0wIMnJKGf_zPT6u7c334XJe1MOAxxpxvpLEOp-x_3ianlwwvr685V6KTzHRZn7N_gdQPEgyTZPgLqP8fMP-M7o5tbmDT0n0s0lRPRtRcOlTr4AkTT_FbgsEPglyPjwOdW7zoGW9ZIEl_BgVibVXQOevW31qz4ybsdiSdv2RfbyJMbv8JbW8R8kwfNsbq5pqk9x73QRiHE_syIZRNhI2Dyi3hwzo5OEV_z_sLwtC11oqS0cWEYeOkkm6PQfgkah-EKYbfeHDsAJmocpkjyT3bcltpA0ijt7U0oS4jbCQtL_UOuLeRweoPa8ae-leIDu6AFRbS9yRChWCFkzaUVINbX27yVU1JevdGWCJrrYMrWQHlvy9v5w8PfPnh9-WHe_7n8tPydvn7cvV3yjkumhuwjXLch-eqRha7R-YfP3xa3T8-_MFni9X9H3z--JiMuv0XZdmQcv7VB153te8r0ktivxbSBPZHNxj_389-phuVe7J8NYMegGAknWOJfF0LI0pwYK7j69hXg-d3kzZkxVZglkGAN8jtiqGWhHYqvgp75Ip5sJ6V14cPNF0QS32M3gzeTRI67OCWf6h9lvtB8_toxFJ0yLlAix4Q5_R4cH06OKH8w8f7x_n9w4r7nUpaXmlXGP3kY7IWIWeEeDxJDpNDev2LM-eacIZJxhhSw_exxT0aVyA2aJdl_Uos4c71I_G00zLvM9uLk_Hfwtd9fRpj3y19OZmxZy7xx5D3BVoL9kI6jKLoPbmvA-arukNCM_sjwStjzeVkvRJKbTDpYRFrwFrIeb9LJZPkJ4TUGfKv3rJOQ-z55K9tYt8peznhdURuU8kvDfDaBV4Hw9G74-0A-V-qQU4m9HXgnPK7syz574T2J5si7nGcf416b9m3Z7jR3aWFry2EQb9tGU7YKHk3xQfMlyl-B5kn0G35cWDx1dFT-i6do8Hw_Rw9gfj8Sxg6An7GzytjF8jOThgpKoc0jNj7N7se7ieWIaJxutvPDvh8ta_BHhcdyr9QuZStqXuxJRRhi-6iTV3p-49dHeKLTOBx6fnehLbsX2z9UMgcTcr_8BvKzGx7nlrsPoi-W_rtsDrr1vjPVQG0FLIKbSRp6WdZ5QLXVcg8h4rKKrSjZJ4riN7o_vxVXzq9uOzlhtbaWtk2T0uxX_u2m4HWRda-1VdA9pkKFxpmVd612bICLRZ6hFDlljZ1aL1aXYLz_SMlP3t3DNMlEZ17LBkAfK-y8G3V426erqh0_oQ-jPs3stIGG5J0vjoz0TDuK0z20gyok27cecewP8-_MNXxWb-_b-BAZa_Ga5r0Bl5rV9DEty0ZFb7X2nTt0YpCKZ3vLPo-pBWhDVu0xkbzqT2tjV4rKFHpfihQ3rV2jaW26BgLeubRVT5N80k6EVcwTYajdDy8uWGTq2KaxkyI4QaSLJ0kcRpPYJJlYpMxyIfrdT68klMWszROkmESs5hNoiwZZwCjyVqsk2y8jslNDKWQKlJqV0babK-ktQ1Mh3E8HFwpsQZlfYOfsQqeqB8kjJHB3ZWZ4jPX62ZryU2spHX2gOKkUzD9eP5efyOkagyg4yEzXYP_vL2NbPu3a0bvZA60kKEjH-xlDNhaVzlaODzZGip4ybFHXDVGTQvnaovssgVhi610RbOOMo0JHfVtv65ro_8BmcPkjavE5O6t8K8AAAD__1lvdtk">