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