https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90652
--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> --- With a "fixed" source to the new syntax of concepts I get: <source>: In substitution of 'template<class T> requires (ToJson<T>) && !(Serializable<T>) std::ostream& operator<<(std::ostream&, const T&) [with T = char]': <source>:5:86: required from here <source>:5:31: required by the constraints of 'template<class T> concept Serializable' <source>:5:46: in requirements with 'T x', 'std::ostream& os' [with T = char] <source>:5:46: error: satisfaction of atomic constraint 'requires(T x, std::ostream& os) {{os << x};} [with T = T]' depends on itself 5 | template<typename T> concept Serializable = requires (T x, std::ostream& os) { { os << x }; }; | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #include <iostream> void to_json (std::ostream& os, char c) { os << '"' << c << '"'; } template<typename T> concept Serializable = requires (T x, std::ostream& os) { { os << x }; }; template<typename T> concept ToJson = requires (T x, std::ostream& os) { { to_json (os, x) }; }; template<typename T> requires (ToJson<T> && !Serializable<T>) std::ostream& operator << (std::ostream& os, T const& x) { to_json (os, x); return os; } int main () { static_assert (Serializable<char>); static_assert (ToJson<char>); std::cout << 'c'; }