12cee2663SErich Keane // RUN: %clang_cc1 -std=c++20 -verify %s 22cee2663SErich Keane namespace GH53213 { 32cee2663SErich Keane template<typename T> 42cee2663SErich Keane concept c = requires(T t) { f(t); }; // #CDEF 52cee2663SErich Keane 62cee2663SErich Keane auto f(c auto); // #FDEF 72cee2663SErich Keane g()82cee2663SErich Keanevoid g() { 92cee2663SErich Keane f(0); 102cee2663SErich Keane // expected-error@-1{{no matching function for call to 'f'}} 112cee2663SErich Keane // expected-note@#FDEF{{constraints not satisfied}} 122cee2663SErich Keane // expected-note@#FDEF{{because 'int' does not satisfy 'c'}} 132cee2663SErich Keane // expected-note@#CDEF{{because 'f(t)' would be invalid: no matching function for call to 'f'}} 142cee2663SErich Keane } 152cee2663SErich Keane } // namespace GH53213 162cee2663SErich Keane 172cee2663SErich Keane namespace GH45736 { 182cee2663SErich Keane struct constrained; 192cee2663SErich Keane 202cee2663SErich Keane template<typename T> 212cee2663SErich Keane struct type { 222cee2663SErich Keane }; 232cee2663SErich Keane template<typename T> f(type<T>)242cee2663SErich Keane constexpr bool f(type<T>) { 252cee2663SErich Keane return true; 262cee2663SErich Keane } 272cee2663SErich Keane 282cee2663SErich Keane template<typename T> 292cee2663SErich Keane concept matches = f(type<T>()); 302cee2663SErich Keane 312cee2663SErich Keane 322cee2663SErich Keane struct constrained { 332cee2663SErich Keane template<typename U> requires matches<U> constrainedGH45736::constrained342cee2663SErich Keane explicit constrained(U value) { 352cee2663SErich Keane } 362cee2663SErich Keane }; 372cee2663SErich Keane f(constrained const &)382cee2663SErich Keanebool f(constrained const &) { 392cee2663SErich Keane return true; 402cee2663SErich Keane } 412cee2663SErich Keane 422cee2663SErich Keane struct outer { 432cee2663SErich Keane constrained state; 442cee2663SErich Keane }; 452cee2663SErich Keane f(outer const & x)462cee2663SErich Keanebool f(outer const & x) { 472cee2663SErich Keane return f(x.state); 482cee2663SErich Keane } 492cee2663SErich Keane } // namespace GH45736 502cee2663SErich Keane 512cee2663SErich Keane namespace DirectRecursiveCheck { 522cee2663SErich Keane template<class T> 532cee2663SErich Keane concept NotInf = true; 542cee2663SErich Keane template<class T> 552cee2663SErich Keane concept Inf = requires(T& v){ // #INF_REQ 562cee2663SErich Keane {begin(v)}; // #INF_BEGIN_EXPR 572cee2663SErich Keane }; 582cee2663SErich Keane begin(NotInf auto & v)592cee2663SErich Keanevoid begin(NotInf auto& v){ } // #NOTINF_BEGIN 602cee2663SErich Keane // This lookup should fail, since it results in a recursive check. 612cee2663SErich Keane // However, this is a 'hard failure'(not a SFINAE failure or constraints 622cee2663SErich Keane // violation), so it needs to cause the entire lookup to fail. begin(Inf auto & v)632cee2663SErich Keanevoid begin(Inf auto& v){ } // #INF_BEGIN 642cee2663SErich Keane 652cee2663SErich Keane struct my_range{ 662cee2663SErich Keane } rng; 672cee2663SErich Keane baz()682cee2663SErich Keanevoid baz() { 692cee2663SErich Keane auto it = begin(rng); // #BEGIN_CALL 702cee2663SErich Keane // expected-error@#INF_BEGIN {{satisfaction of constraint 'Inf<Inf auto>' depends on itself}} 712cee2663SErich Keane // expected-note@#INF_BEGIN {{while substituting template arguments into constraint expression here}} 722cee2663SErich Keane // expected-note@#INF_BEGIN_EXPR {{while checking constraint satisfaction for template 'begin<DirectRecursiveCheck::my_range>' required here}} 732cee2663SErich Keane // expected-note@#INF_BEGIN_EXPR {{while substituting deduced template arguments into function template 'begin'}} 742cee2663SErich Keane // expected-note@#INF_BEGIN_EXPR {{in instantiation of requirement here}} 752cee2663SErich Keane // expected-note@#INF_REQ {{while substituting template arguments into constraint expression here}} 762cee2663SErich Keane // expected-note@#INF_BEGIN {{while checking the satisfaction of concept 'Inf<DirectRecursiveCheck::my_range>' requested here}} 772cee2663SErich Keane // expected-note@#INF_BEGIN {{while substituting template arguments into constraint expression here}} 782cee2663SErich Keane // expected-note@#BEGIN_CALL {{while checking constraint satisfaction for template 'begin<DirectRecursiveCheck::my_range>' required here}} 792cee2663SErich Keane // expected-note@#BEGIN_CALL {{in instantiation of function template specialization}} 802cee2663SErich Keane 812cee2663SErich Keane // Fallout of the failure is failed lookup, which is necessary to stop odd 822cee2663SErich Keane // cascading errors. 832cee2663SErich Keane // expected-error@#BEGIN_CALL {{no matching function for call to 'begin'}} 842cee2663SErich Keane // expected-note@#NOTINF_BEGIN {{candidate function}} 852cee2663SErich Keane // expected-note@#INF_BEGIN{{candidate template ignored: constraints not satisfied}} 862cee2663SErich Keane } 872cee2663SErich Keane } // namespace DirectRecursiveCheck 882cee2663SErich Keane 892cee2663SErich Keane namespace GH50891 { 902cee2663SErich Keane template <typename T> 912cee2663SErich Keane concept Numeric = requires(T a) { // #NUMERIC 922cee2663SErich Keane foo(a); // #FOO_CALL 932cee2663SErich Keane }; 942cee2663SErich Keane 952cee2663SErich Keane struct Deferred { 962cee2663SErich Keane friend void foo(Deferred); 972cee2663SErich Keane template <Numeric TO> operator TO(); // #OP_TO 982cee2663SErich Keane }; 992cee2663SErich Keane 1002cee2663SErich Keane static_assert(Numeric<Deferred>); // #STATIC_ASSERT 10112cb1cb3SErich Keane // expected-error@#NUMERIC{{satisfaction of constraint 'requires (T a) { foo(a); }' depends on itself}} 1022cee2663SErich Keane // expected-note@#NUMERIC {{while substituting template arguments into constraint expression here}} 10312cb1cb3SErich Keane // expected-note@#OP_TO {{while checking the satisfaction of concept 'Numeric<GH50891::Deferred>' requested here}} 10412cb1cb3SErich Keane // expected-note@#OP_TO {{while substituting template arguments into constraint expression here}} 1052cee2663SErich Keane // expected-note@#FOO_CALL {{while checking constraint satisfaction for template}} 1062cee2663SErich Keane // expected-note@#FOO_CALL {{in instantiation of function template specialization}} 1072cee2663SErich Keane // expected-note@#FOO_CALL {{in instantiation of requirement here}} 1082cee2663SErich Keane // expected-note@#NUMERIC {{while substituting template arguments into constraint expression here}} 1092cee2663SErich Keane 1102cee2663SErich Keane // expected-error@#STATIC_ASSERT {{static assertion failed}} 11112cb1cb3SErich Keane // expected-note@#STATIC_ASSERT{{while checking the satisfaction of concept 'Numeric<GH50891::Deferred>' requested here}} 11212cb1cb3SErich Keane // expected-note@#STATIC_ASSERT{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} 11312cb1cb3SErich Keane 1142cee2663SErich Keane } // namespace GH50891 1152cee2663SErich Keane 116*42667563SErich Keane 117*42667563SErich Keane namespace GH60323 { 118*42667563SErich Keane // This should not diagnose, as it does not depend on itself. 119*42667563SErich Keane struct End { 120*42667563SErich Keane template<class T> goGH60323::End121*42667563SErich Keane void go(T t) { } 122*42667563SErich Keane 123*42667563SErich Keane template<class T> endparensGH60323::End124*42667563SErich Keane auto endparens(T t) 125*42667563SErich Keane requires requires { go(t); } 126*42667563SErich Keane { return go(t); } 127*42667563SErich Keane }; 128*42667563SErich Keane 129*42667563SErich Keane struct Size { 130*42667563SErich Keane template<class T> goGH60323::Size131*42667563SErich Keane auto go(T t) 132*42667563SErich Keane { return End().endparens(t); } 133*42667563SErich Keane 134*42667563SErich Keane template<class T> sizeparensGH60323::Size135*42667563SErich Keane auto sizeparens(T t) 136*42667563SErich Keane requires requires { go(t); } 137*42667563SErich Keane { return go(t); } 138*42667563SErich Keane }; 139*42667563SErich Keane f()140*42667563SErich Keane int f() 141*42667563SErich Keane { 142*42667563SErich Keane int i = 42; 143*42667563SErich Keane Size().sizeparens(i); 144*42667563SErich Keane } 145*42667563SErich Keane } 146