<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/58192>58192</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
variant's operator<=> is missing a requires-clause
</td>
</tr>
<tr>
<th>Labels</th>
<td>
libc++,
c++20
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
CaseyCarter
</td>
</tr>
</table>
<pre>
[variant.syn] declares variant's spaceship operator as:
```c++
template<class... Types> requires (three_way_comparable<Types> && ...)
constexpr common_comparison_category_t<compare_three_way_result_t<Types>...>
operator<=>(const variant<Types...>&, const variant<Types...>&);
```
libc++ implements this operator, but without the _requires-clause_ `requires (three_way_comparable<Types> && ...)`:
https://github.com/llvm/llvm-project/blob/e2378d343828df73dd640fd1d1f5e02feb4ac0ef/libcxx/include/variant#L1641-L1643
The absence of the _requires-clause_ causes the operator to sometimes be present under conditions in which the standard specifies it should not be, such as a variant with an alternative type that implements `<=>` but not `==` (https://godbolt.org/z/f7Mh3vMxM):
```c++
struct X {
bool operator==(const X&) const = delete;
auto operator<=>(const X&) const = default;
};
template <class T>
concept can_spaceship = requires(const T& x, const T& y) {
x <=> y;
};
static_assert(!can_spaceship<std::variant<X>>);
```
The `static_assert` in this example program fails with libc++ but should pass. If fact, libc++ has a test case for this exact behavior:
https://github.com/llvm/llvm-project/blob/e2378d343828df73dd640fd1d1f5e02feb4ac0ef/libcxx/test/std/utilities/variant/variant.relops/three_way.pass.cpp#L174
which will also need to be fixed.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzFVctu6zYQ_Rp5Q0SQKFuyFl4k9g1QoNllkZ1BkSOLBS2qJJXY_frO0Jbl5DYt2k0B2nyfGZ45M2qsOm-S1dO7cFr0IfXnPlntmAJphAPPrusJrzzzg5DgOz0wO4ATwTomfFI8JtkuyR6TMrs0mfAnanE1wHEwIkBSbBHR-zRN2et5ALz3gzn4fdRkJeHr0DmA_Yc476U9DsKJxtCl29mEl9gY3k94fcFmTNreBzgNDkfHo-2vd7WnIVo9WHfeB7Id12E_W0Gzowlxc7JB2MWPCZvdXolHkmJHW3wdLd5Yud69XiQPt-yfTtRJ8fSFscvU6OZKHdNIGhyhD56FTvvZE8RvxsA-dOgs9qEDtp9YfECCRw97hoj_nVn05hbR-N-FMMQo82dsB7Q8Niki4cSY96l7GJz9DSQK5bkxtsEOeFGtVbEs1nyt2qpQqlxmrcpV3q4g4y00SyEzaAkAX3464UD30owKcHTTXfFrXi7zB_ov7t16xaeLxkMvgdn2GyYkdT5u3iQbLPP2CEEfcacBNuAFZJqNvQLSUa900BhDpnv20WnZxes-iF4JpzAJQOpW410dmMcoGMV6GxCJguNHPC88E5MAYqiY6JkwAVwvgn4HFpB6RBXhPtCR-UloZRbjTMBxfUcNFzGcX-JhVWNNSK074OwP_LXVS1e8v5xeotT-Njl9cKMM7I0l1dMs-8Zac6f9aHoS_ttFwleR4w5WCgOU3ncAYkSOv0-ev8JoBSbjnBjVbh5_KiNsqiPs9ZaqiCNhCBjsfj-XKMKd9HAz_UpCP81ZGudncuYTAyd28xp3v_cKRRG03KM74FCq64Tnn5xAFB8UBaF4nAvCG3lOfHxbCUjbOPkMj9FHRcZyACdBukHp2oMTR9YKbfxFaXdFhAR0FehAlZf90uJJStHt_bEuyjWAJwY9sJZy5GpFkq478a4pjv9bVSDfsCMq-fMYtMEEpaDORWIapQ6MHWjrVvTS-HY5DLGUVMv7R1zS-0Mbg-npLesBFNUHrAqtPoFKL8cWsMnLcpWVfFnWC7UpVF3UYhF0MLC5_0D-pHmGNB6197o_IMdfytNidGbzr3lEtDE-frXOa77oNkVZQNYKBUquqnIta7XMZd20JfA6r-psYUQDxtNHPuF8DjxOSAnYXRd4Rkur3UJveMZ5nmVlXmBXp1mdtSteNoVsKlSQSJYZHFFzKflGpWfhNtHNZjx43DTaBz9vYgD0AbmNLiA-1ofOus0W1XbeCod1cRFftYlP-hMwiaye">