https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105926
Bug ID: 105926 Summary: Using a spaceship operator on an optional of a type derived from optional causes infinite constraint recursion Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: ville.voutilainen at gmail dot com Target Milestone: --- Testcase: #include <optional> struct oink : std::optional<int> { }; bool operator<(const oink&, const oink) {return false;} bool operator>(const oink&, const oink) {return true;} bool operator<=(const oink&, const oink) {return false;} bool operator>=(const oink&, const oink) {return true;} bool operator==(const oink&, const oink) {return false;} bool operator!=(const oink&, const oink) {return true;} int main() { oink a; std::optional<oink> b; b <=> a; } Ends up, eventually, with.. error: satisfaction of atomic constraint 'requires(const typename std::remove_reference<_Tp>::type& __t, const typename std::remove_reference<_Arg>::type& __u) {{__t < __u} -> decltype(auto) [requires std::__detail::__boolean_testable<<placeholder>, >];{__t > __u} -> decltype(auto) [requires std::__detail::__boolean_testable<<placeholder>, >];{__t <= __u} -> decltype(auto) [requires std::__detail::__boolean_testable<<placeholder>, >];{__t >= __u} -> decltype(auto) [requires std::__detail::__boolean_testable<<placeholder>, >];{__u < __t} -> decltype(auto) [requires std::__detail::__boolean_testable<<placeholder>, >];{__u > __t} -> decltype(auto) [requires std::__detail::__boolean_testable<<placeholder>, >];{__u <= __t} -> decltype(auto) [requires std::__detail::__boolean_testable<<placeholder>, >];{__u >= __t} -> decltype(auto) [requires std::__detail::__boolean_testable<<placeholder>, >];} [with _Up = oink; _Tp = oink]' depends on itself 302 | = requires(const remove_reference_t<_Tp>& __t, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 303 | const remove_reference_t<_Up>& __u) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 304 | { __t < __u } -> __boolean_testable; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 305 | { __t > __u } -> __boolean_testable; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 306 | { __t <= __u } -> __boolean_testable; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 307 | { __t >= __u } -> __boolean_testable; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 308 | { __u < __t } -> __boolean_testable; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 309 | { __u > __t } -> __boolean_testable; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 310 | { __u <= __t } -> __boolean_testable; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 311 | { __u >= __t } -> __boolean_testable; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 312 | }; The relevant bit being "satisfaction of atomic constraint foo depends on itself".