Clang's __is_trivially_equality_comparable(T) builtin assumes that if a type has any defaulted trivial comparison operator, then all its comparison operators will be tantamount-to-trivial. That's a sane assumption... but only if the defaulted operator is actually eligible for the given T! If the defaulted operator is requires-clause'd away, then we shouldn't consider it relevant to the question of triviality at all.
https://godbolt.org/z/3hs4EKPKT
template<bool B>
struct S {
int i;
bool operator==(const S&) const requires B = default;
bool operator==(const S& rhs) const { return (i % 3) == (rhs.i % 3); }
};
static_assert(__is_trivially_equality_comparable(S<true>)); // OK
static_assert(not __is_trivially_equality_comparable(S<false>)); // Oops, this line assert-fails
Clang's
__is_trivially_equality_comparable(T)
builtin assumes that if a type has any defaulted trivial comparison operator, then all its comparison operators will be tantamount-to-trivial. That's a sane assumption... but only if the defaulted operator is actually eligible for the givenT
! If the defaulted operator isrequires
-clause'd away, then we shouldn't consider it relevant to the question of triviality at all. https://godbolt.org/z/3hs4EKPKTThis compiler misbehavior causes libc++ to miscompile
std::equal
: https://godbolt.org/z/YPfEG6cv9