[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / SemaTemplate / concepts-recursive-inst.cpp
blob9330df8cdd0398a81c820c294b778b0e512568e6
1 // RUN: %clang_cc1 -std=c++20 -verify %s
2 namespace GH53213 {
3 template<typename T>
4 concept c = requires(T t) { f(t); }; // #CDEF
6 auto f(c auto); // #FDEF
8 void g() {
9 f(0);
10 // expected-error@-1{{no matching function for call to 'f'}}
11 // expected-note@#FDEF{{constraints not satisfied}}
12 // expected-note@#FDEF{{because 'int' does not satisfy 'c'}}
13 // expected-note@#CDEF{{because 'f(t)' would be invalid: no matching function for call to 'f'}}
15 } // namespace GH53213
17 namespace GH45736 {
18 struct constrained;
20 template<typename T>
21 struct type {
23 template<typename T>
24 constexpr bool f(type<T>) {
25 return true;
28 template<typename T>
29 concept matches = f(type<T>());
32 struct constrained {
33 template<typename U> requires matches<U>
34 explicit constrained(U value) {
38 bool f(constrained const &) {
39 return true;
42 struct outer {
43 constrained state;
46 bool f(outer const & x) {
47 return f(x.state);
49 } // namespace GH45736
51 namespace DirectRecursiveCheck {
52 template<class T>
53 concept NotInf = true;
54 template<class T>
55 concept Inf = requires(T& v){ // #INF_REQ
56 {begin(v)}; // #INF_BEGIN_EXPR
59 void begin(NotInf auto& v){ } // #NOTINF_BEGIN
60 // This lookup should fail, since it results in a recursive check.
61 // However, this is a 'hard failure'(not a SFINAE failure or constraints
62 // violation), so it needs to cause the entire lookup to fail.
63 void begin(Inf auto& v){ } // #INF_BEGIN
65 struct my_range{
66 } rng;
68 void baz() {
69 auto it = begin(rng); // #BEGIN_CALL
70 // expected-error@#INF_BEGIN {{satisfaction of constraint 'Inf<Inf auto>' depends on itself}}
71 // expected-note@#INF_BEGIN {{while substituting template arguments into constraint expression here}}
72 // expected-note@#INF_BEGIN_EXPR {{while checking constraint satisfaction for template 'begin<DirectRecursiveCheck::my_range>' required here}}
73 // expected-note@#INF_BEGIN_EXPR {{while substituting deduced template arguments into function template 'begin'}}
74 // expected-note@#INF_BEGIN_EXPR {{in instantiation of requirement here}}
75 // expected-note@#INF_REQ {{while substituting template arguments into constraint expression here}}
76 // expected-note@#INF_BEGIN {{while checking the satisfaction of concept 'Inf<DirectRecursiveCheck::my_range>' requested here}}
77 // expected-note@#INF_BEGIN {{while substituting template arguments into constraint expression here}}
78 // expected-note@#BEGIN_CALL {{while checking constraint satisfaction for template 'begin<DirectRecursiveCheck::my_range>' required here}}
79 // expected-note@#BEGIN_CALL {{in instantiation of function template specialization}}
81 // Fallout of the failure is failed lookup, which is necessary to stop odd
82 // cascading errors.
83 // expected-error@#BEGIN_CALL {{no matching function for call to 'begin'}}
84 // expected-note@#NOTINF_BEGIN {{candidate function}}
85 // expected-note@#INF_BEGIN{{candidate template ignored: constraints not satisfied}}
87 } // namespace DirectRecursiveCheck
89 namespace GH50891 {
90 template <typename T>
91 concept Numeric = requires(T a) { // #NUMERIC
92 foo(a); // #FOO_CALL
95 struct Deferred {
96 friend void foo(Deferred);
97 template <Numeric TO> operator TO(); // #OP_TO
100 static_assert(Numeric<Deferred>); // #STATIC_ASSERT
101 // expected-error@#NUMERIC{{satisfaction of constraint 'requires (T a) { foo(a); }' depends on itself}}
102 // expected-note@#NUMERIC {{while substituting template arguments into constraint expression here}}
103 // expected-note@#OP_TO {{while checking the satisfaction of concept 'Numeric<GH50891::Deferred>' requested here}}
104 // expected-note@#OP_TO {{while substituting template arguments into constraint expression here}}
105 // expected-note@#FOO_CALL {{while checking constraint satisfaction for template}}
106 // expected-note@#FOO_CALL {{in instantiation of function template specialization}}
107 // expected-note@#FOO_CALL {{in instantiation of requirement here}}
108 // expected-note@#NUMERIC {{while substituting template arguments into constraint expression here}}
110 // expected-error@#STATIC_ASSERT {{static assertion failed}}
111 // expected-note@#STATIC_ASSERT{{while checking the satisfaction of concept 'Numeric<GH50891::Deferred>' requested here}}
112 // expected-note@#STATIC_ASSERT{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
114 } // namespace GH50891
117 namespace GH60323 {
118 // This should not diagnose, as it does not depend on itself.
119 struct End {
120 template<class T>
121 void go(T t) { }
123 template<class T>
124 auto endparens(T t)
125 requires requires { go(t); }
126 { return go(t); }
129 struct Size {
130 template<class T>
131 auto go(T t)
132 { return End().endparens(t); }
134 template<class T>
135 auto sizeparens(T t)
136 requires requires { go(t); }
137 { return go(t); }
140 int f()
142 int i = 42;
143 Size().sizeparens(i);