xref: /llvm-project/clang/test/CXX/expr/expr.prim/expr.prim.req/nested-requirement.cpp (revision ca9683651e52196f590bc244d9c506ed39fe1d92)
1 // RUN: %clang_cc1 -std=c++2a -x c++ %s -verify
2 
3 static_assert(requires { requires true; });
4 
5 template<typename T> requires requires { requires false; } // expected-note{{because 'false' evaluated to false}}
6 struct r1 {};
7 
8 using r1i = r1<int>; // expected-error{{constraints not satisfied for class template 'r1' [with T = int]}}
9 
10 template<typename T> requires requires { requires sizeof(T) == 0; } // expected-note{{because 'sizeof(int) == 0' (4 == 0) evaluated to false}}
11 struct r2 {};
12 
13 using r2i = r2<int>; // expected-error{{constraints not satisfied for class template 'r2' [with T = int]}}
14 
15 template<typename T> requires requires (T t) { requires sizeof(t) == 0; } // expected-note{{because 'sizeof (t) == 0' (4 == 0) evaluated to false}}
16 struct r3 {};
17 
18 using r3i = r3<int>; // expected-error{{constraints not satisfied for class template 'r3' [with T = int]}}
19 
20 template<typename T>
21 struct X {
22     template<typename U> requires requires (U u) { requires sizeof(u) == sizeof(T); } // expected-note{{because 'sizeof (u) == sizeof(T)' would be invalid: invalid application of 'sizeof' to an incomplete type 'void'}}
23     struct r4 {};
24 };
25 
26 using r4i = X<void>::r4<int>; // expected-error{{constraints not satisfied for class template 'r4' [with U = int]}}
27 
28 // C++ [expr.prim.req.nested] Examples
29 namespace std_example {
30   template<typename U> concept C1 = sizeof(U) == 1; // expected-note{{because 'sizeof(int) == 1' (4 == 1) evaluated to false}}
31   template<typename T> concept D =
32     requires (T t) {
33       requires C1<decltype (+t)>; // expected-note{{because 'decltype(+t)' (aka 'int') does not satisfy 'C1'}}
34   };
35 
operator +std_example::T136   struct T1 { char operator+() { return 'a'; } };
37   static_assert(D<T1>);
38   template<D T> struct D_check {}; // expected-note{{because 'short' does not satisfy 'D'}}
39   using dc1 = D_check<short>; // expected-error{{constraints not satisfied for class template 'D_check' [with T = short]}}
40 
41   template<typename T>
42   concept C2 = requires (T a) {
43       requires sizeof(a) == 4; // OK
44       requires a == 0; // expected-note{{because 'a == 0' would be invalid: constraint variable 'a' cannot be used in an evaluated context}}
45     };
46   static_assert(C2<int>); // expected-note{{because 'int' does not satisfy 'C2'}} expected-error{{static assertion failed}}
47 }
48 
49 template<typename T>
50 concept K = requires (T::Type X) {
51   X.next();
52 };
53 
54 namespace SubstitutionFailureNestedRequires {
55 template<class T>  concept True = true;
56 template<class T>  concept False = false;
57 
58 struct S { double value; };
59 
60 template <class T>
61 concept Pipes = requires (T x) {
62    requires True<decltype(x.value)> || True<T> || False<T>;
63    requires False<T> || True<T> || True<decltype(x.value)>;
64 };
65 
66 template <class T>
67 concept Amps1 = requires (T x) {
68    requires True<decltype(x.value)> && True<T> && !False<T>; // #Amps1
69 };
70 template <class T>
71 concept Amps2 = requires (T x) {
72    requires True<T> && True<decltype(x.value)>;
73 };
74 
75 static_assert(Pipes<S>);
76 static_assert(Pipes<double>);
77 
78 static_assert(Amps1<S>);
79 static_assert(!Amps1<double>);
80 
81 static_assert(Amps2<S>);
82 static_assert(!Amps2<double>);
83 
84 template<class T>
foo1()85 void foo1() requires requires (T x) { // #foo1
86   requires
87   True<decltype(x.value)> // #foo1Value
88   && True<T>;
89 } {}
fooPipes()90 template<class T> void fooPipes() requires Pipes<T> {}
fooAmps1()91 template<class T> void fooAmps1() requires Amps1<T> {} // #fooAmps1
foo()92 void foo() {
93   foo1<S>();
94   foo1<int>(); // expected-error {{no matching function for call to 'foo1'}}
95   // expected-note@#foo1Value {{because 'True<decltype(x.value)> && True<T>' would be invalid: member reference base type 'int' is not a structure or union}}
96   // expected-note@#foo1 {{candidate template ignored: constraints not satisfied [with T = int]}}
97   fooPipes<S>();
98   fooPipes<int>();
99   fooAmps1<S>();
100   fooAmps1<int>(); // expected-error {{no matching function for call to 'fooAmps1'}}
101   // expected-note@#fooAmps1 {{candidate template ignored: constraints not satisfied [with T = int]}}
102   // expected-note@#fooAmps1 {{because 'int' does not satisfy 'Amps1'}}
103   // expected-note@#Amps1 {{because 'True<decltype(x.value)> && True<T> && !False<T>' would be invalid: member reference base type 'int' is not a structure or union}}
104 }
105 
106 template<class T>
107 concept HasNoValue = requires (T x) {
108   requires !True<decltype(x.value)> && True<T>;
109 };
110 // FIXME: 'int' does not satisfy 'HasNoValue' currently since `!True<decltype(x.value)>` is an invalid expression.
111 // But, in principle, it should be constant-evaluated to true.
112 // This happens also for requires expression and is not restricted to nested requirement.
113 static_assert(!HasNoValue<int>);
114 static_assert(!HasNoValue<S>);
115 
116 template<class T> constexpr bool NotAConceptTrue = true;
117 template <class T>
118 concept SFinNestedRequires = requires (T x) {
119     // SF in a non-concept specialisation should also be evaluated to false.
120    requires NotAConceptTrue<decltype(x.value)> || NotAConceptTrue<T>;
121 };
122 static_assert(SFinNestedRequires<int>);
123 static_assert(SFinNestedRequires<S>);
124 template <class T>
foo()125 void foo() requires SFinNestedRequires<T> {}
bar()126 void bar() {
127   foo<int>();
128   foo<S>();
129 }
130 namespace ErrorExpressions_NotSF {
131 template<typename T> struct X { static constexpr bool value = T::value; }; // #X_Value
132 struct True { static constexpr bool value = true; };
133 struct False { static constexpr bool value = false; };
134 template<typename T> concept C = true;
135 template<typename T> concept F = false;
136 
137 template<typename T> requires requires(T) { requires C<T> || X<T>::value; } void foo();
138 
139 template<typename T> requires requires(T) { requires C<T> && X<T>::value; } void bar(); // #bar
140 template<typename T> requires requires(T) { requires F<T> || (X<T>::value && C<T>); } void baz();
141 
func()142 void func() {
143   foo<True>();
144   foo<False>();
145   foo<int>();
146 
147   bar<True>();
148   bar<False>();
149   // expected-error@-1 {{no matching function for call to 'bar'}}
150   // expected-note@#bar {{while substituting template arguments into constraint expression here}}
151   // expected-note@#bar {{while checking the satisfaction of nested requirement requested here}}
152   // expected-note@#bar {{candidate template ignored: constraints not satisfied [with T = False]}}
153   // expected-note@#bar {{because 'X<False>::value' evaluated to false}}
154 
155   bar<int>();
156   // expected-note@-1 {{while checking constraint satisfaction for template 'bar<int>' required here}} \
157   // expected-note@-1 {{in instantiation of function template specialization}}
158   // expected-note@#bar {{in instantiation of static data member}}
159   // expected-note@#bar {{in instantiation of requirement here}}
160   // expected-note@#bar {{while checking the satisfaction of nested requirement requested here}}
161   // expected-note@#bar {{while substituting template arguments into constraint expression here}}
162   // expected-error@#X_Value {{type 'int' cannot be used prior to '::' because it has no members}}
163 }
164 }
165 }
166 
167 namespace no_crash_D138914 {
168 // https://reviews.llvm.org/D138914
169 template <class a, a> struct b;
170 template <bool c> using d = b<bool, c>;
171 template <class a, class e> using f = d<__is_same(a, e)>;
172 template <class a, class e>
173 concept g = f<a, e>::h;
174 template <class a, class e>
175 concept i = g<e, a>;
176 template <typename> class j {
177   template <typename k>
178   requires requires { requires i<j, k>; }
179   j();
180 };
181 template <> j(); // expected-error {{deduction guide declaration without trailing return type}}
182 }
183