// RUN: %clang_cc1 -std=c++20 -verify %s namespace GH53213 { template concept c = requires(T t) { f(t); }; // #CDEF auto f(c auto); // #FDEF void g() { f(0); // expected-error@-1{{no matching function for call to 'f'}} // expected-note@#FDEF{{constraints not satisfied}} // expected-note@#FDEF{{because 'int' does not satisfy 'c'}} // expected-note@#CDEF{{because 'f(t)' would be invalid: no matching function for call to 'f'}} } } // namespace GH53213 namespace GH45736 { struct constrained; template struct type { }; template constexpr bool f(type) { return true; } template concept matches = f(type()); struct constrained { template requires matches explicit constrained(U value) { } }; bool f(constrained const &) { return true; } struct outer { constrained state; }; bool f(outer const & x) { return f(x.state); } } // namespace GH45736 namespace DirectRecursiveCheck { template concept NotInf = true; template concept Inf = requires(T& v){ // #INF_REQ {begin(v)}; // #INF_BEGIN_EXPR }; void begin(NotInf auto& v){ } // #NOTINF_BEGIN // This lookup should fail, since it results in a recursive check. // However, this is a 'hard failure'(not a SFINAE failure or constraints // violation), so it needs to cause the entire lookup to fail. void begin(Inf auto& v){ } // #INF_BEGIN struct my_range{ } rng; void baz() { auto it = begin(rng); // #BEGIN_CALL // expected-error@#INF_BEGIN {{satisfaction of constraint 'Inf' depends on itself}} // expected-note@#INF_BEGIN {{while substituting template arguments into constraint expression here}} // expected-note@#INF_BEGIN_EXPR {{while checking constraint satisfaction for template 'begin' required here}} // expected-note@#INF_BEGIN_EXPR {{while substituting deduced template arguments into function template 'begin'}} // expected-note@#INF_BEGIN_EXPR {{in instantiation of requirement here}} // expected-note@#INF_REQ {{while substituting template arguments into constraint expression here}} // expected-note@#INF_BEGIN {{while checking the satisfaction of concept 'Inf' requested here}} // expected-note@#INF_BEGIN {{while substituting template arguments into constraint expression here}} // expected-note@#BEGIN_CALL {{while checking constraint satisfaction for template 'begin' required here}} // expected-note@#BEGIN_CALL {{in instantiation of function template specialization}} // Fallout of the failure is failed lookup, which is necessary to stop odd // cascading errors. // expected-error@#BEGIN_CALL {{no matching function for call to 'begin'}} // expected-note@#NOTINF_BEGIN {{candidate function}} // expected-note@#INF_BEGIN{{candidate template ignored: constraints not satisfied}} } } // namespace DirectRecursiveCheck namespace GH50891 { template concept Numeric = requires(T a) { // #NUMERIC foo(a); // #FOO_CALL }; struct Deferred { friend void foo(Deferred); template operator TO(); // #OP_TO }; static_assert(Numeric); // #STATIC_ASSERT // expected-error@#NUMERIC{{satisfaction of constraint 'requires (T a) { foo(a); }' depends on itself}} // expected-note@#NUMERIC {{while substituting template arguments into constraint expression here}} // expected-note@#OP_TO {{while checking the satisfaction of concept 'Numeric' requested here}} // expected-note@#OP_TO {{while substituting template arguments into constraint expression here}} // expected-note@#FOO_CALL {{while checking constraint satisfaction for template}} // expected-note@#FOO_CALL {{in instantiation of function template specialization}} // expected-note@#FOO_CALL {{in instantiation of requirement here}} // expected-note@#NUMERIC {{while substituting template arguments into constraint expression here}} // expected-error@#STATIC_ASSERT {{static assertion failed}} // expected-note@#STATIC_ASSERT{{while checking the satisfaction of concept 'Numeric' requested here}} // expected-note@#STATIC_ASSERT{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} } // namespace GH50891 namespace GH60323 { // This should not diagnose, as it does not depend on itself. struct End { template void go(T t) { } template auto endparens(T t) requires requires { go(t); } { return go(t); } }; struct Size { template auto go(T t) { return End().endparens(t); } template auto sizeparens(T t) requires requires { go(t); } { return go(t); } }; int f() { int i = 42; Size().sizeparens(i); } }