https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102396
--- Comment #4 from Giuseppe D'Angelo <dangelog at gmail dot com> ---
To elaborate on the last comment, this testcase does complain about the
redefinition.
#include <type_traits>
#include <concepts>
template <typename T> class S;
template <typename T>
static inline std::true_type is_S_impl(const S<T>&);
static inline std::false_type is_S_impl(...);
template <typename T>
concept is_S = decltype(is_S_impl(std::declval<T>()))::value;
template <typename T>
struct S {
using type = T;
T data;
S();
explicit S(const T &);
template <typename V, typename U>
requires is_S<V> && (!is_S<U>) &&
std::equality_comparable_with<typename V::type, U>
friend bool operator==(const V &v, const U &u) { return v.data == u; }
};
void f() {
S<int> s1; s1 == 123;
S<double> s2; s2 == 123.4;
}