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

    <tr>
        <th>Summary</th>
        <td>
            [libc++] std::map<> with const key doesn't compile
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            libc++
      </td>
    </tr>

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

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

<pre>
    With clang++ 18.1.4 using libc++ the following doesn't compile (as originally seen in https://github.com/canonical/mir/issues/3383)
```cpp
#include <map>

using map=std::map<int const, int>;

int main() {
  map a, b;
  a = b;
}
```
```
$ clang++ -v test.cpp
clang version 18.1.4
Target: x86_64-chimera-linux-musl
Thread model: posix
InstalledDir: /usr/bin
System configuration file directory: /etc/clang
 "/usr/bin/clang-18" -cc1 -triple x86_64-chimera-linux-musl -emit-obj -mrelax-all -dumpdir a- -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name test.cpp -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/home/deathmist -v -fcoverage-compilation-dir=/home/deathmist -resource-dir /usr/lib/clang/18 -internal-isystem /usr/bin/../include/c++/v1 -internal-isystem /usr/local/include -internal-externc-isystem /usr/include/fortify -internal-externc-isystem /usr/include -internal-isystem /usr/lib/clang/18/include -include stdc-predef.h -fdeprecated-macro -ferror-limit 19 -stack-protector 2 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -fcolor-diagnostics -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/test-fdefa8.o -x c++ test.cpp
clang -cc1 version 18.1.4 based upon LLVM 18.1.4 default target x86_64-chimera-linux-musl
#include "..." search starts here:
#include <...> search starts here:
 /usr/bin/../include/c++/v1
 /usr/local/include
 /usr/include/fortify
 /usr/include
 /usr/lib/clang/18/include
End of search list.
In file included from test.cpp:1:
/usr/bin/../include/c++/v1/map:797:13: error: no viable overloaded '='
  797 |     __ref() = __v.__get_value();
      | ~~~~~~~ ^ ~~~~~~~~~~~~~~~~~
/usr/bin/../include/c++/v1/__tree:1435:33: note: in instantiation of member function 'std::__value_type<const int, int>::operator=' requested here
 1435 |       __cache.__get()->__value_ = *__first;
      | ^
/usr/bin/../include/c++/v1/__tree:1398:5: note: in instantiation of function template specialization 'std::__tree<std::__value_type<const int, int>, std::__map_value_compare<const int, std::__value_type<const int, int>, std::less<const int>>, std::allocator<std::__value_type<const int, int>>>::__assign_multi<std::__tree_const_iterator<std::__value_type<const int, int>, std::__tree_node<std::__value_type<const int, int>, void *> *, long>>' requested here
 1398 |     __assign_multi(__t.begin(), __t.end());
      |     ^
/usr/bin/../include/c++/v1/map:1082:13: note: in instantiation of member function 'std::__tree<std::__value_type<const int, int>, std::__map_value_compare<const int, std::__value_type<const int, int>, std::less<const int>>, std::allocator<std::__value_type<const int, int>>>::operator=' requested here
 1082 |     __tree_ = __m.__tree_;
 |             ^
test.cpp:7:5: note: in instantiation of member function 'std::map<const int, int>::operator=' requested here
    7 |   a = b;
 |     ^
/usr/bin/../include/c++/v1/__utility/pair.h:289:3: note: candidate function not viable: no known conversion from 'const value_type' (aka 'const pair<const int, int>') to 'const __conditional_t<is_copy_assignable<first_type>::value && is_copy_assignable<second_type>::value, pair<const int &, int &>, __nat>' (aka 'const std::__nat') for 1st argument
  289 | operator=(__conditional_t< is_copy_assignable<first_type>::value && is_copy_assignable<second_type>::value,
      |   ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 290 |                              pair,
      | ~~~~~
  291 |                              __nat> const& __p)
 | ~~~~~~~~~~~~~~~~~
/usr/bin/../include/c++/v1/__utility/pair.h:298:61: note: candidate function not viable: no known conversion from 'const value_type' (aka 'const pair<const int, int>') to '__conditional_t<is_move_assignable<first_type>::value && is_move_assignable<second_type>::value, pair<const int &, int &>, __nat>' (aka 'std::__nat') for 1st argument
  298 |   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair& operator=(
      | ^
  299 |       __conditional_t< is_move_assignable<first_type>::value && is_move_assignable<second_type>::value, pair, __nat>&&
      | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 300 |           __p)
      | ~~~
/usr/bin/../include/c++/v1/__utility/pair.h:311:61: note: candidate template ignored: requirement 'is_assignable<const int &, const int &>::value' was not satisfied [with _U1 = const int, _U2 = int]
  311 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair& operator=(pair<_U1, _U2> const& __p) {
      | ^
/usr/bin/../include/c++/v1/__utility/pair.h:321:61: note: candidate template ignored: requirement 'is_assignable<const int &, const int>::value' was not satisfied [with _U1 = const int, _U2 = int]
  321 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair& operator=(pair<_U1, _U2>&& __p) {
      | ^
/usr/bin/../include/c++/v1/__utility/pair.h:422:61: note: candidate template ignored: could not match 'tuple' against 'pair'
  422 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair& operator=(tuple<_U1, _U2> const& __p) {
      | ^
/usr/bin/../include/c++/v1/__utility/pair.h:431:61: note: candidate template ignored: could not match 'tuple' against 'pair'
  431 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair& operator=(tuple<_U1, _U2>&& __p) {
      | ^
/usr/bin/../include/c++/v1/__utility/pair.h:463:61: note: candidate template ignored: could not match 'array' against 'pair'
  463 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair& operator=(array<_Up, 2> const& __p) {
      | ^
/usr/bin/../include/c++/v1/__utility/pair.h:470:61: note: candidate template ignored: could not match 'array' against 'pair'
  470 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair& operator=(array<_Up, 2>&& __p) {
      | ^
/usr/bin/../include/c++/v1/__utility/pair.h:80:29: note: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'const pair<const key_type, mapped_type>' to 'const pair<const int &, int &>' for 1st argument
   80 | struct _LIBCPP_TEMPLATE_VIS pair
      |                             ^~~~
1 error generated.
```
Switching line 3 of the example with `using map=std::map<int, int>;` does compile fwiw.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzkWltz4yj2_zTkhcJlIduyH_Lg-PKf_Ld7pmu65_KmwuhIZoJAC8hJ9mE_-xYg3510J-nObNWqUrENHOD8zu9cJMGsFZUCuEbDGzScX7HWrbW5_n9Wi3-Ac60CdbXSxeP1H8KtMZdMVYjeIHqDk3Ev6Q1wa4WqsBQr3rW7NeBSS6nvfUehwSpEM4e5rhshASM6ZhZrIyqhmJSP2AIoLBReO9dYlE4RXSK6rIRbt6se1zWiS86UVoIzieiyFgbRpbC2BYvoMk3HKaIT1J-j_hSN-vGPN03XQlOhuGwLwCid1axB6aLrCf_j9kP73LrCL59Ow8-ZUH7TyjpEZ1go5yXTm0NhP6JmQiE6RnSCUdb1Yj8hZl5utRPBmGGUzg9aUDY_2fbln3RwBDzZYAfW9XY6hk68AWOFVp1dYs8XZipwKJ3ih_EoHw0IX4saDCNSqPaB1K2V3cC1AVbgWhcg_fBGW_EQu26VdUxKKObC-C5El631JlgJFUd8frQOao9VKarWMOe3UXpbF8IAd9o8doLguLdmUCaCgig9mrDrJckYUYoJ5wkmzohGwtMqYAK1cESv_sKkNiDZA2FSYlK0dVMIgxnBpBCWrSSQ0gBgwiUwQ5h1ZAWlNkBWjN-BKvbjpNzUZANGlAJMaObMFGTDZAtEsRosJt70xOsZGnZGiZvQPOBAAqS4ERyTRnAiYQMS0_hDWNIIwKQuDauBNFooBwal87D9smwI18oZxh1K51phUipNjG5VIVRFaubWmNSBoqb1MBMmBbN-a2Wr7oUqiPPKWJTOKSYukIHwpvVQktEAE-_foaECBcbvsYBVW1VgfJdQFUrnVbHCpAztJPpwVKzwdJgjulzrGhBdFsDcuhbWeYKSkusNGFbBt8oYsLo1HPyYPcekWO0IQ5fJGJMAkWKSCBtpd0KfXs9Hh-jyXjQ6DaLLTfKcsLeX3EseDIUH_4Wfi-wXKbVxonx8gdCzWznR-VgqfrGu4KQxUEDZWwfzNAY4c1CQmnGjMSnBGG2IFLVwOJlgYh3jd6Qx2gWX9BwsK9Vy0gUOlM4HPdpLMCntnWiILgzha-B3RChS1aW36cMDgQcOjTemZ9nRD66lNqQQrFLaOsF9GysKY0WFyTzP_282y3-a_r7I539Mf13SfLa8zaefP6J0nmCivf6ubvx_sM5rVLJxT2PygHeZ5ULUCxHiOPThFbNQ4LbRCn_48PvHbbOfsZUORz_4WkQ8TByU9jytKLbADF9j65hxFq_BgE8YFxKNH58unhv_At6eCpxw9bT7jJdPDTid9knexZELVWBdbnWSwrreNkPEaN-NLnBpdL23VjpNDlD6ZqXpMqThaTbJ_BSpTyGB0_6L0ngjfGzDPsxIzfyyiGYhumTbhJtNMoyyGfZXnhsot4k6neM83_TyvAKXh5geew6Stb-87L_jhdFwsf2-v16hVJ47A54GySAdonSaplEf59t8GSR8vlVOxDSqS1xDvQKDy1bx0IRotqtU8rj73D02gNJZyAWhVjkoWfw43YBhTsfom2ED_2zBOigiJ6PKfkM7uDxgnPE1RJAiPASli-2KAUREp3leCmPdBeTQcPEmfNLJGKXT4dfg2eHioG4kc4BtA1wwKf7FLuAVZ5-9BEE6wwfDa9Z0Ij6zMXMm9dqpJVh7NMwb73gIk6Gu8HZ8kQbdXxwdS_68bqUTx_N4bPIgnwu3JcwboArzKV28AvCNFt6hpz6K-g86w1L7eiRi8hSF08n4wOOPNKXjPHe9FVTbet3P6ZtAFduGSwEgfL6KyjF-Jf0x3QWw1_v5_zpvvymC9cf0wPyBfl2wr3vd772F96EOHxv5IHNl3xKBnjNcvJV8U1zGGG_T2Okd5BsJmuetE1K4R0SXDROmt0bplI4nPi0dKs2ZKkThQ-tOR6Vdl4G7dHyn9L3y94DbYiwUAYhmUfcDU9MsPAO4Y_tev_hTTMt8xnZ6Pzj3IaoQfhtM5s7fqduc6-ax8_e4qVlISx25OrTDJjCiI0RH-KKQBT_3BSm_o9Ndxplmu6-R9HmuWLfzMz0PuO8HRd1KbXBiHWamamtQbmt2Op4E-x5xZHyu_WVNvrv653HxYkn0va9uWTrpnzns2RUMdL7Tw3kwnSRfn2hrw-3znxHO82b3lOmwLnxjLXjJ_0LZM0r-Gx3wouvVegMv5t650A9zvZc53a6AyD_c3sw-fcp_up0v8uWvv3zMpze3u9bZLz9__rL489Ov-efbn2eLfPbnn7TfEXB04rJPFsZ-uclxyX3Bt98N3yME_URP3Au929Wtn_ZPff_IGw-3972cME2SZ5xwd6chKqUNeHqF1C0MeC550gl7jP4Zc48bTgyS4Xtmg4tb5oQthb-7Hd7cC7fG-W9JqAKOfDX_jYZG_3M43wKTJjHWfT8qd36Y_5Z0q14IkofPwd96L3jJNPTdTPOjzELfwyxdLHgXmwwofaFNuG5lEaCsmeNrbxfXNjKAzCrma2zfFtXdPdAZUPo65JLBE8jFRf9eRg_SlzL6leilr-Tdy9B7V-KN0rdDx4xhj1-BbpR-Z-jioh66xkP3d9Au678Pdln_x2P3nqQb90OZ_pUC3bvHGrCoGym4cNjfbeGYeEIm2qlEJy8u5o_K4Tt47Or6Ga5Z08C-yKPZ0Z3zt1TR2ZOlMR5HO8a3jTvDfVl8_PRh-mWR_377Oa5w4QHaUxcaLnZVWxIf78d3kcxB0bv4OvzzvXB8HQ8dKMAp1mU4cwAPrG4k4JCN0aj__Jv943f6o344qLA7o1Dei_veVXGdFpN0wq7gOsmSIR0Nsz69Wl-PVuMyTaEY8bRIJmUyTvssG4wgHUyGfJSNr8Q17dNBf9ifJINBMuj3ihUb9Yshg6RYpUUxRoM-1EzInpSbuqdNdRXOM1xPklE_uZJsBdKGExmU7k9WIErRcH5lrsO76VVbWTToS2Gd3U_jhJPhLMeB2HCOT_T3sSbAtCPQ-TmNq9bI62eOZPgluw_SGP0XcHd4LCNo8p8AAAD__7U5oik">