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
5
6 auto f(c auto); // #FDEF
7
g()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'}}
14 }
15 } // namespace GH53213
16
17 namespace GH45736 {
18 struct constrained;
19
20 template<typename T>
21 struct type {
22 };
23 template<typename T>
f(type<T>)24 constexpr bool f(type<T>) {
25 return true;
26 }
27
28 template<typename T>
29 concept matches = f(type<T>());
30
31
32 struct constrained {
33 template<typename U> requires matches<U>
constrainedGH45736::constrained34 explicit constrained(U value) {
35 }
36 };
37
f(constrained const &)38 bool f(constrained const &) {
39 return true;
40 }
41
42 struct outer {
43 constrained state;
44 };
45
f(outer const & x)46 bool f(outer const & x) {
47 return f(x.state);
48 }
49 } // namespace GH45736
50
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
57 };
58
begin(NotInf auto & v)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.
begin(Inf auto & v)63 void begin(Inf auto& v){ } // #INF_BEGIN
64
65 struct my_range{
66 } rng;
67
baz()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}}
80
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}}
86 }
87 } // namespace DirectRecursiveCheck
88
89 namespace GH50891 {
90 template <typename T>
91 concept Numeric = requires(T a) { // #NUMERIC
92 foo(a); // #FOO_CALL
93 };
94
95 struct Deferred {
96 friend void foo(Deferred);
97 template <Numeric TO> operator TO(); // #OP_TO
98 };
99
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}}
109
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}}
113
114 } // namespace GH50891
115
116
117 namespace GH60323 {
118 // This should not diagnose, as it does not depend on itself.
119 struct End {
120 template<class T>
goGH60323::End121 void go(T t) { }
122
123 template<class T>
endparensGH60323::End124 auto endparens(T t)
125 requires requires { go(t); }
126 { return go(t); }
127 };
128
129 struct Size {
130 template<class T>
goGH60323::Size131 auto go(T t)
132 { return End().endparens(t); }
133
134 template<class T>
sizeparensGH60323::Size135 auto sizeparens(T t)
136 requires requires { go(t); }
137 { return go(t); }
138 };
139
f()140 int f()
141 {
142 int i = 42;
143 Size().sizeparens(i);
144 }
145 }
146