https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99846
Patrick Palka <ppalka at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |ppalka at gcc dot gnu.org --- Comment #7 from Patrick Palka <ppalka at gcc dot gnu.org> --- Before CWG 2369 (i.e. in GCC 10), for the original testcase, overload resolution for 'left < right' would reject the operator<=> candidate due to substitution failure into its return type before ever checking its loopy constraints, and because we also define the (non-constrained) relational operators for std::variant alongside operator<=>, overload resolution would just end up selecting the explicitly defined operator<. After CWG 2369 (i.e. in GCC 11), we check constraints sooner during overload resolution, so when considering the operator<=> candidate we end up looping during constraint checking, which we consider to be a fatal error. Distilled testcase that exhibits the issue: template <typename L, typename R> concept comparable_with = requires(L l, R r) { l < r; }; template <typename b> concept comparable = comparable_with<b, b>; template <typename> class variant; template <typename T> void operator<(variant<T>, variant<T>); template <typename T> requires(comparable<T>) typename T::fail operator<=>(variant<T>, variant<T>); template <typename> class variant {}; struct g; struct g : variant<g> {}; int main() { g left, right; left < right; }