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