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

    <tr>
        <th>Summary</th>
        <td>
            [libc++] std::conjunction doesn't correctly short circuit
        </td>
    </tr>

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

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

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

<pre>
    The following program demonstrates as failure of `std::conjunction` to correctly short circuit in libc++:

```c++
#include <type_traits>

template <int kSomeInt>
struct Predicate {
  static_assert(kSomeInt != 2);
  static constexpr bool value = false;
};

static_assert(!std::conjunction_v<std::false_type, Predicate<2>, std::true_type>);
```

Because the first template parameter to `std::conjunction_v` is false, it is [required](https://timsong-cpp.github.io/cppwp/n4659/meta.logical#3) to short circuit and not instantiate `Predicate<2>`. But instead it does ([compiler explorer](https://godbolt.org/z/8K9559EPj)):
  
```
<source>:5:3: error: static assertion failed due to requirement '2 != 2'
  static_assert(kSomeInt != 2);
  ^             ~~~~~~~~~~~~~
/opt/compiler-explorer/clang-trunk-20221019/bin/../include/c++/v1/__type_traits/conjunction.h:27:36: note: in instantiation of template class 'Predicate<2>' requested here
  using type = conditional_t<!bool(_Arg::value), _Arg, typename __conjunction_impl<_Args...>::type>;
                                   ^
/opt/compiler-explorer/clang-trunk-20221019/bin/../include/c++/v1/__type_traits/conjunction.h:27:65: note: in instantiation of template class 'std::__conjunction_impl<Predicate<2>, std::integral_constant<bool, true>>' requested here
  using type = conditional_t<!bool(_Arg::value), _Arg, typename __conjunction_impl<_Args...>::type>;
                                                                ^
/opt/compiler-explorer/clang-trunk-20221019/bin/../include/c++/v1/__type_traits/conjunction.h:27:65: note: in instantiation of template class 'std::__conjunction_impl<std::integral_constant<bool, false>, Predicate<2>, std::integral_constant<bool, true>>' requested here
/opt/compiler-explorer/clang-trunk-20221019/bin/../include/c++/v1/__type_traits/conjunction.h:36:22: note: in instantiation of template class 'std::__conjunction_impl<std::integral_constant<bool, true>, std::integral_constant<bool, false>, Predicate<2>, std::integral_constant<bool, true>>' requested here
struct conjunction : __conjunction_impl<true_type, _Args...>::type {};
                     ^
/opt/compiler-explorer/clang-trunk-20221019/bin/../include/c++/v1/__type_traits/conjunction.h:39:39: note: in instantiation of template class 'std::conjunction<std::integral_constant<bool, false>, Predicate<2>, std::integral_constant<bool, true>>' requested here
inline constexpr bool conjunction_v = conjunction<_Args...>::value;
                                      ^
<source>:9:21: note: in instantiation of variable template specialization 'std::conjunction_v<std::integral_constant<bool, false>, Predicate<2>, std::integral_constant<bool, true>>' requested here
static_assert(!std::conjunction_v<std::false_type, Predicate<2>, std::true_type>);
                    ^
1 error generated.
Compiler returned: 1
```

@philnik777 previously committed 8a2a966520 to fix similar issues reported in #54803, but the fix didn't take care of this case (probably because the presence of the trailing `std::true_type` is essential).

After reducing, I understand why this is broken ([this line](https://github.com/llvm/llvm-project/blob/14d9ef29304ee16802657311911813aec5bdb9cf/libcxx/include/__type_traits/conjunction.h#L27) instantiates the next iteration of the template when it doesn't need to). I'll send a fix.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzlWMmO4zYQ_Rr5QrQgUZt18KG3AQbJYYDkblAibbObJhWS6mW-Po-SbKunPT1LgEwjMWTJpmiy6r1XpSo3hj-v_twJsjFKmUept6SzZmvZnnCxN9p5y7xwhDmyYVL1VhCzIVGZOM-j7BJHa_Rdr1svjcYw8Ya0xlrRevVM3M5YT1pp2156IjVRsmkjehUO_Di5iZLDuUzG43B7HKWZ1K3quSBRdu2fO7GGPdK7KLud_9qLfadgZ5gltSf3f5i9-Kj9cRrc6FtPPlnBZTtMrKYtCHGeedmumXPC-oguDz8mEU2j7IbQiNZR9sV0OAlsxFNnSWOMIg9M9WH7G8CknDjOj6qb0-fJlJfbYZdzWK4f4MvxxrDoOgAQ0euTG5hCg48YO06Fp9PMcONk-RHhuTFXomW9E8QHBUjrPDlC2TGIQHhhA6VfIRxGgnLpJqdhRqDZkai4suKvXsLOqLiBkzvvOxd-Tj_g8HLvjN5etF0Xb6Xf9U0sDcbx_bHDVedlUeOK7VmszBa-KkghgzvBmJeqYpoTbYK6gKz2cmC3TF5hVCYxuerHeYLxYCk3UHagoLhqzb6TCs6CUmWssOfs3hreGOVjY7f49hnv5W91UdS3n-4C0gHsy4NMzoMOSk1v24Gb7LLAO8ObCGuNDR8mcY3iAMBD0AlOOMQFzydQ92JQZ0VnEq1-Us5RcUvmr6i6_a5jis8PpvOBuQm-iyN8GFMMHEOO-v6CJpSmSRpIbaTGOY5xmmI7zJ2inn54SHFar-exHpY_Si7eASd4C-TKgBioF-GK5HJSQEAOaeqoZZjiAtPV68ipBlAFNMHJTlhxwKV3IRcGM4aohgVchnWZWiOtXAPMEPfAd30JNQyBMeSAQQjXZBjFNSygEUdkvZ7HjYRhWCXMcjGwGOQQgneK2xM_33yBwHdARln8OBnHjHIWmzeTHJK8wENKrYc0zEKmvx75AORIgAOG_wV2_5fUfxfN03P29psPxH-mlV8F7ZDdKP0l0B5Q-V4U_yUqpiJu5hUJsJz181QFTeH6KhCHEnBWnb3PCMvqw-lnZTCvz99XaEmtpBZfVtIvystDdp558IrMMTH_WE498fqyIgtAhzLpbbQfmJWsUeIEu-tEK5mSn8c5X8H_ZU3_Dhj4Vb3Im5SkYzlMtkKL0HzyeBy_PpToVvjeahH2IOkbzU2UJ91OKi3vq6pCWysepOkd2lLE8F76AMWSUVaXZUGHxnUjn4iTe6mYRRfjABf26tBsYKYMrGZFvkyy4GKDTmJsmp4IlxyBXmGA3UPObOyR_Q6NUMvQXAFY9NQNFPNMmlnDBYuc0O00G2NIAirUJfNu6wTh2GkJcBW0CIbreO7t5cYP2PC-xRrBxo-k11zYIAtOHnfPo0k4GmvuhZ46n2EwBOLZjmfszgAYvij1cLhcwKE79PghyynT4JLmvBYbWmdJLkRaLhNaFlWWpnWaLtOMibZoeFO3m7CAbNqnpxdZ8e00SLPfUWmg-Zv1eG6ATIsndHQ-6OSQCXezsHzcwc2p0Rsp0gJcehPAIx8xohQBnpywwGS8EKu0LEuaZ3lZLvgq43VWs4WXXokVsJr9fVHckHOhMtvqK3-DLHqrVj-M8ihHfCiWeZ0sdqukzfNyUyVp2_BiU3OR5VWdU542TdFUZbZQrBHKBath60KuxgcTTZKC5rSMi5xntG2SlG1qmpUbBIvYQ39x2Dh0uAu7Gmxo-q3DTSWdd6ebSBlyCzAP67Pew8nVHWtN49hiMHc12Po38ya5JA">