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

    <tr>
        <th>Summary</th>
        <td>
            [libc++] Regression with std::variant move construction
        </td>
    </tr>

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

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

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

<pre>
    This breaks some valid code. Here a partially reduced test case that depends on libc++ and Google Test: https://gcc.godbolt.org/z/dPznsz44M

```
#include <variant>
#include <vector>

#include <gmock/gmock.h>

template <typename T>
class Nullable {
 public:
  Nullable() : value_() {}
  template <typename V>
 Nullable(V value) : value_(value) {}

  const T& value() const { return value_; }

 private:
  T value_;
};

template <typename L, typename R>
inline bool operator== (const Nullable<L>& lhs, const Nullable<R>& rhs) {
  return lhs.value() == rhs.value();
}

void f() {
  std::vector<std::variant<int, Nullable<int>>> v;
 ASSERT_THAT(v, ::testing::ElementsAre(16));
}
```

It used to compile fine, but now it triggers a compilation error:
```
/opt/compiler-explorer/clang-trunk-20250722/bin/../include/c++/v1/variant:1186:37: fatal error: recursive template instantiation exceeded maximum depth of 1024
 1186 |              enable_if_t<!is_same_v<__remove_cvref_t<_Arg>, variant>, int>        = 0,
      | ^
/opt/compiler-explorer/clang-trunk-20250722/bin/../include/c++/v1/variant:1192:35: note: while substituting prior template arguments into non-type template parameter [with _Arg = testing::Matcher<const std::variant<int, Nullable<int>> &>]
 1192 |   _LIBCPP_HIDE_FROM_ABI constexpr variant(_Arg&& __arg) noexcept(is_nothrow_constructible_v<_Tp, _Arg>)
 | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 1193 |       : __impl_(in_place_index<_Ip>, std::forward<_Arg>(__arg)) {}
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/clang-trunk-20250722/bin/../include/c++/v1/__type_traits/invoke.h:71:69: note: while substituting deduced template arguments into function template 'variant' [with _Arg = testing::Matcher<const std::variant<int, Nullable<int>> &>, $1 = (no value), $2 = (no value), $3 = (no value), _Tp = (no value), _Ip = (no value), $6 = (no value)]
   71 | using __invoke_result_t _LIBCPP_NODEBUG = decltype(__builtin_invoke(std::declval<_Args>()...));
      | ^
/opt/compiler-explorer/clang-trunk-20250722/bin/../include/c++/v1/__type_traits/invoke.h:387:1: note: in instantiation of template type alias '__invoke_result_t' requested here
  387 | using invoke_result_t = __invoke_result_t<_Fn, _Args...>;
 | ^
/opt/compiler-explorer/clang-trunk-20250722/bin/../include/c++/v1/variant:1140:1: note: in instantiation of template type alias 'invoke_result_t' requested here
 1140 | using __best_match_t _LIBCPP_NODEBUG = typename invoke_result_t<_MakeOverloads<_Types...>, _Tp, _Tp>::type;
      | ^
/opt/compiler-explorer/clang-trunk-20250722/bin/../include/c++/v1/variant:1189:45: note: in instantiation of template type alias '__best_match_t' requested here
 1189 |              class _Tp  = __variant_detail::__best_match_t<_Arg, _Types...>,
      | ^
/opt/compiler-explorer/clang-trunk-20250722/bin/../include/c++/v1/variant:1192:35: note: (skipping 2533 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
 1192 |   _LIBCPP_HIDE_FROM_ABI constexpr variant(_Arg&& __arg) noexcept(is_nothrow_constructible_v<_Tp, _Arg>)
      | ^
/opt/compiler-explorer/libs/googletest/trunk/googlemock/include/gmock/gmock-matchers.h:356:12: note: in instantiation of function template specialization 'testing::internal::MatcherCastImpl<const std::vector<std::variant<int, Nullable<int>>> &, testing::internal::ElementsAreMatcher<std::tuple<int>>>::CastImpl<false>' requested here
  356 |     return CastImpl(polymorphic_matcher_or_value,
      | ^
/opt/compiler-explorer/libs/googletest/trunk/googlemock/include/gmock/gmock-matchers.h:529:43: note: in instantiation of member function 'testing::internal::MatcherCastImpl<const std::vector<std::variant<int, Nullable<int>>> &, testing::internal::ElementsAreMatcher<std::tuple<int>>>::Cast' requested here
  529 |   return internal::MatcherCastImpl<T, M>::Cast(matcher);
 | ^
/opt/compiler-explorer/libs/googletest/trunk/googlemock/include/gmock/gmock-matchers.h:536:10: note: in instantiation of function template specialization 'testing::MatcherCast<const std::vector<std::variant<int, Nullable<int>>> &, testing::internal::ElementsAreMatcher<std::tuple<int>>>' requested here
 536 |   return MatcherCast<T>(polymorphic_matcher_or_value);
      | ^
/opt/compiler-explorer/libs/googletest/trunk/googlemock/include/gmock/gmock-matchers.h:1661:39: note: in instantiation of function template specialization 'testing::SafeMatcherCast<const std::vector<std::variant<int, Nullable<int>>> &, testing::internal::ElementsAreMatcher<std::tuple<int>>>' requested here
 1661 |     const Matcher<const T&> matcher = SafeMatcherCast<const T&>(matcher_);
      | ^
<source>:26:3: note: in instantiation of function template specialization 'testing::internal::PredicateFormatterFromMatcher<testing::internal::ElementsAreMatcher<std::tuple<int>>>::operator()<std::vector<std::variant<int, Nullable<int>>>>' requested here
   26 |   ASSERT_THAT(v, ::testing::ElementsAre(16));
      | ^
/opt/compiler-explorer/libs/googletest/trunk/googlemock/include/gmock/gmock-matchers.h:5736:3: note: expanded from macro 'ASSERT_THAT'
 5736 |   ASSERT_PRED_FORMAT1( \
      | ^
/opt/compiler-explorer/libs/googletest/trunk/googletest/include/gtest/gtest_pred_impl.h:112:3: note: expanded from macro 'ASSERT_PRED_FORMAT1'
  112 | GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_)
      | ^
/opt/compiler-explorer/libs/googletest/trunk/googletest/include/gtest/gtest_pred_impl.h:100:28: note: expanded from macro 'GTEST_PRED_FORMAT1_'
  100 | GTEST_ASSERT_(pred_format(#v1, v1), on_failure)
      | ^
/opt/compiler-explorer/libs/googletest/trunk/googletest/include/gtest/gtest_pred_impl.h:79:52: note: expanded from macro 'GTEST_ASSERT_'
   79 |   if (const ::testing::AssertionResult gtest_ar = (expression)) \
      | ^
1 error generated.
```

@philnik777 please take a look.

_Originally posted by @alexfh in https://github.com/llvm/llvm-project/issues/116709#issuecomment-3105095648_
 
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzcWltv27gS_jXMCxFDoixLfsiDL_FugGZbpN59FWhpbPOEInVIyk36cH77wVA327l0200v2MCQLZIiZ7755kIq3FqxUwBXJJ6TeHnBa7fX5koWQisFFxtdPF6t98LSjQF-b6nVJdADl6KguS5gRH8HA5TTihsnuJSP1EBR51BQB9bRnFugbs8dLaACVViqFZVikxM2J2xOuSrob1rvJNA1WEeiGd07V1kSzQhbEbba5flop4uNlm6kzY6w1WfCVsWHz8p-Ho9vSbAkway9ToL209yySKhc1gVQEi0O3AiuHImun-2F3GkzdD4zZFfq_B4Fwu_R_mysg7KS3PmR7rECxUug635QLrm19I9aSr6RQEkyb9ppVW-kyFHb5r4fQ1hK2JQiIAcua8i6hmROkmU3-tll_-qXPZ7tr2aeJ5MOrUczd_PnWllH14RNuqe9EE0zSebUgKuN6maL5vR8isqIA3dwpOF6GN2OTJbD75fRfEfYgvZ3d72SQkmhgG60llRXYLi35JJES0pY2oja4xAt3uGDbELl3uKET_rv2n6D_dMjU3W6yr0dHYPRrmVOm0-0O1LtoEVBt0fGbCe3rkCMollHxcXQ0lF3IZRDmY-kFQ2l_Yce-kXp7OPH67t1tv59tkYb41PNZOiVQu2am2sJJShnZwalDico97Oin3mWv944Wlv0c01zXVZCAt0KBbjUpnZU6U9UOOqM2O3AWMrbUdwJrSgYg0q-5LkrXTnCVu285hIeKqkNGGyTXO0unanV_SULWBwkjBG22ghF2Go0ImzVOi2ObaIMYatDiJcOyFkYphMSzaIEXWHLHZe9RNRAXhsrDjB4l1DWceVEK_tDDlBAQUv-IMq6xNDm9lRvaRiwcWsAXIGSZEFP_kCh3TKxzdCchIXCZpaXkB1ItMgyA6U-QJYfDDQjspnZeT4u6FEAYwva2L2bFvkXELboyOTbkgUl8fWPQ3TKENEYIVTaezz9tEdW2HpjnXA18g7jgTYDstzsak9B1EhTpdUluvgwoOKGl-DAUBLPPwm3p4iJ1_iEyrfc5XtAv2k8-uu8hxI2wV_xsjfflLXmy97dzBcfPmS_3yyvs9Xd-9tsNr9p4gY8VKY3DEu9tdgEo0eWcfw9pUojXRD7VNhMabc3-lPmnzZ17gTSwRt_XaFwvcGnrSCtGf_3Bn-DatERM9FOWSbKSmI2ECqrJM8hE6qAB5Trpmop1yO61eYTN8UxPdNO3ycpChf650J_L_5mGbItc4YLZ_3Ag74HzO6zJCTRbDL9Ap2Lvth5ntDbWuU-aAwpjSU9Y5IfQmqM_Wwc0jYjKt1XAm0Xe7kreqErW1cv9dy81EPYePJcV-90lCahJ0xtEdssa8yRGbC1dJnrXfGP98vr-Z-_-ckKyCUa0ZNwUwvphGofJCztEcNhBy5b0tqGtYRNR0iQk6z3A8PnK_SLUsxN4TH9hDpLRHo70MpHTS4Ft8iwJ9Ah1wz8twbroKB7MNApG6XJEebniCPCTyeLFtlKdeHKIoRIuPlpyPpxmWcc_AOo_i5QuMwJOTdgXVaih77AzL5WfQa-W34P7w9gpOaF9eH_sYIOyca_ui-E1lduSPKfQNKTqgnj4Tj-ZlYeY_YK0un0aenUbKEw7rSkbOXKCnBcyAajsxXaDOWBPMH3VyuUMFLdi6pCZrE4irC8cPDgswjd8PzeGZ6j9bHkppfbDuDLvu9SilI4Ei0DLMgtIOxyKCN-mXrmKyGXYoOBceePCDA3ErbyBugb2235gPzJRv2ybFKobYJqjFV_yL7E36dZ21aQCy7F52YMYclJohbKgVFcnqTtBbfupqzkM-n72_d43h4L-srqR5u6oX7oF3J19WTSpudI3C2XFrzZXswa8bC7affF_fMsrbR8LLWp9iLPWgNk2mRtxv9G73tbKsTMh7LoS1QoodyAGRjxb7X8y6aOWReNW0N_SeU1inl7Nnvaon9Saf0040c-DgRvHgeOwPj1bf-SxeNocmrwU63WTe38uo9_ezn9tpYOJxMsDKPpm5v6I9_Cv8LcCFEfyxsdzved62YnSVtofQH2kv7rbtfZeXz2JTZEC6trk0MTMZg_mPvOGfqDgULk3MFKm5I7B2ZldDmo_R2CbH803R4PL96AKK-maMo6N36Tw-CfnK6T6Akv4KHiqoCCbo0uaclzo9HsJ9omXUxLojM0PtxdL7PV-7vb2TokLKUk_m51Sdt4pGjb4r-zykDhD-CaiOXL069Q9FSRTmEahk3B_9v6-uPpoAyjN6659eT3h8shXpuhq9l69i5bzW7e_Xl3nX3Hyv3rYAkwW7P0b-DyrMYDLkFwhEuL4TkiKWFRgwle_emVVtmWC1kb-FUgSaa-jv3biPS6JsN5W1faie3wsuyZ2DCzFgzG1Tt_hkEbcbjpjvNw4wjWCq26M-BXvCls3rXQHSgMiVCMXnnLRMZBtRdSifskSWglwb9Q5vdAOZVa34-OB2fvjdgJ5V9DV9pHxM0jJeOAS3jY7jGTnL1dFm5fb0a5LtE88tB9XVZG_wdybwtra0CzheEkCaaERb4l1yVGy8soDOJgGk_GadYqfFFcRcU0mvILuAqTOErTIInDi_3VJAy3UBTbAoJJOM4naTFNJvE2KDZRGuZheiGumlOFKAijII7D0YTnnMVFNE3HEAY5kHEAJRdyhDKOtNldeFmuwjiMWHoh-Qak9W_yGRteshPGSLy8MFdes029s2QcSGGdHeZxwkn_PwBHj8VLege71q7UH1OfZyha6gPQYfev1UVt5NU_ALnR5HDF_h8AAP__rxshsQ">