https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89997
--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> --- In GCC 10+ (with -fconcepts-diagnostics-depth=2), GCC produces: <source>: In function 'void test()': <source>:17:16: error: use of function 'void check() requires requires(X x, T val) {x.X::operator<<()("hello") << val;} [with T = int]' with unsatisfied constraints 17 | check<int>(); // mangled error | ^ <source>:13:6: note: declared here 13 | void check() requires requires (X x, T val) { x << "hello" << val; } {} | ^~~~~ <source>:13:6: note: constraints not satisfied <source>: In instantiation of 'void check() requires requires(X x, T val) {x.X::operator<<()("hello") << val;} [with T = int]': <source>:17:16: required from here <source>:13:6: required by the constraints of 'template<class T> void check() requires requires(X x, T val) {x.X::operator<<()("hello") << val;}' <source>:13:23: in requirements with 'X x', 'T val' [with T = int] <source>:13:60: note: the required expression '("hello"->x.X::operator<<() << val)' is invalid, because 13 | void check() requires requires (X x, T val) { x << "hello" << val; } {} | ~~~~~~~~~~~~~^~~~~~ <source>:13:63: error: invalid conversion from 'int' to 'void*' [-fpermissive] 13 | void check() requires requires (X x, T val) { x << "hello" << val; } {} | ^~~ | | | int <source>:9:19: note: initializing argument 1 of 'X Y::operator<<(void*)' 9 | X operator<< (void*); | ^~~~~ Is this good enoug now? Note clang produces: <source>:17:5: error: no matching function for call to 'check' check<int>(); // mangled error ^~~~~~~~~~ <source>:13:6: note: candidate template ignored: constraints not satisfied [with T = int] void check() requires requires (X x, T val) { x << "hello" << val; } {} ^ <source>:13:60: note: because 'x << "hello" << val' would be invalid: invalid operands to binary expression ('Y' and 'int') void check() requires requires (X x, T val) { x << "hello" << val; } {} ^