1 // RUN: %clang_cc1 -std=c++2a -x c++ %s -verify -Wno-unused-value
3 template<typename T
, typename U
>
4 constexpr bool is_same_v
= false;
7 constexpr bool is_same_v
<T
, T
> = true;
9 // We use a hack in this file to make the compiler print out the requires
10 // expression after it has been instantiated - we put false_v<requires {...}> as
11 // the requires clause of a class template, then instantiate the template.
12 // The requirement will not be satisfied, and the explaining diagnostic will
13 // print out false_v<requires {...}> in its raw form (the false_v serves to
14 // prevent the diagnostic from elaborating on why the requires expr wasn't
18 constexpr bool false_v
= false;
20 template<typename
... Ts
>
23 // Check that requires parameters are instantiated correctly.
25 template<typename T
> requires
26 false_v
<requires (T t
) { requires is_same_v
<decltype(t
), int>; }>
27 // expected-note@-1 {{because 'false_v<requires (int t) { requires is_same_v<decltype(t), int>; }>' evaluated to false}}
28 // expected-note@-2 {{because 'false_v<requires (char t) { requires is_same_v<decltype(t), int>; }>' evaluated to false}}
31 using r1i1
= r1
<int>; // expected-error {{constraints not satisfied for class template 'r1' [with T = int]}}
32 using r1i2
= r1
<char>; // expected-error {{constraints not satisfied for class template 'r1' [with T = char]}}
34 // Check that parameter packs work.
36 template<typename
... Ts
> requires
37 false_v
<requires (Ts
... ts
) {requires ((sizeof(ts
) == 2) && ...);}>
38 // expected-note@-1 {{because 'false_v<requires (short ts, unsigned short ts) { requires (sizeof (ts) == 2) && (sizeof (ts) == 2); }>'}}
39 // expected-note@-2 {{because 'false_v<requires (short ts) { requires (sizeof (ts) == 2); }>' evaluated to false}}
42 using r2i1
= r2
<short, unsigned short>; // expected-error {{constraints not satisfied for class template 'r2' [with Ts = <short, unsigned short>]}}
43 using r2i2
= r2
<short>; // expected-error {{constraints not satisfied for class template 'r2' [with Ts = <short>]}}
45 template<typename
... Ts
> requires
46 false_v
<(requires (Ts ts
) {requires
sizeof(ts
) != 0;} && ...)>
47 // expected-note@-1 {{because 'false_v<requires (short ts) { requires sizeof (ts) != 0; } && requires (unsigned short ts) { requires sizeof (ts) != 0; }>' evaluated to false}}
48 // expected-note@-2 {{because 'false_v<requires (short ts) { requires sizeof (ts) != 0; }>' evaluated to false}}
51 using r3i1
= r3
<short, unsigned short>; // expected-error {{constraints not satisfied for class template 'r3' [with Ts = <short, unsigned short>]}}
52 using r3i2
= r3
<short>; // expected-error {{constraints not satisfied for class template 'r3' [with Ts = <short>]}}
55 struct identity
{ using type
= T
; };
57 namespace type_requirement
{
60 // check that nested name specifier is instantiated correctly.
61 template<typename T
> requires false_v
<requires
{ typename
T::type
; }> // expected-note{{because 'false_v<requires { typename identity<int>::type; }>' evaluated to false}}
64 using r1i
= r1
<identity
<int>>; // expected-error{{constraints not satisfied for class template 'r1' [with T = identity<int>]}}
66 // check that template argument list is instantiated correctly.
68 struct contains_template
{
69 template<typename U
> requires is_same_v
<contains_template
<T
>, U
>
73 template<typename T
> requires
74 false_v
<requires
{ typename
T::template temp
<T
>; }>
75 // expected-note@-1 {{because 'false_v<requires { typename contains_template<int>::temp<contains_template<int> >; }>' evaluated to false}}
76 // expected-note@-2 {{because 'false_v<requires { typename contains_template<short>::temp<contains_template<short> >; }>' evaluated to false}}
79 using r2i1
= r2
<contains_template
<int>>; // expected-error{{constraints not satisfied for class template 'r2' [with T = type_requirement::contains_template<int>]}}
80 using r2i2
= r2
<contains_template
<short>>; // expected-error{{constraints not satisfied for class template 'r2' [with T = type_requirement::contains_template<short>]}}
82 // substitution error occurs, then requires expr is instantiated again
86 template<typename U
> requires (requires
{ typename
T::a::a
; }, false)
87 // expected-note@-1{{because 'requires { <<error-type>>; } , false' evaluated to false}}
91 using ari
= a
<int>::r
<short>; // expected-error{{constraints not satisfied for class template 'r' [with U = short]}}
93 // Parameter pack inside expr
94 template<typename
... Ts
> requires
95 false_v
<(requires
{ typename
Ts::type
; } && ...)>
96 // expected-note@-1 {{because 'false_v<requires { typename identity<short>::type; } && requires { typename identity<int>::type; } && requires { <<error-type>>; }>' evaluated to false}}
99 using r5i
= r5
<identity
<short>, identity
<int>, short>; // expected-error{{constraints not satisfied for class template 'r5' [with Ts = <identity<short>, identity<int>, short>]}}
100 template<typename
... Ts
> requires
101 false_v
<(requires
{ typename void_t
<Ts
>; } && ...)> // expected-note{{because 'false_v<requires { typename void_t<int>; } && requires { typename void_t<short>; }>' evaluated to false}}
104 using r6i
= r6
<int, short>; // expected-error{{constraints not satisfied for class template 'r6' [with Ts = <int, short>]}}
106 template<typename
... Ts
> requires
107 false_v
<(requires
{ typename
Ts::template aaa
<Ts
>; } && ...)>
108 // expected-note@-1 {{because 'false_v<requires { <<error-type>>; } && requires { <<error-type>>; }>' evaluated to false}}
111 using r7i
= r7
<int, A
>; // expected-error{{constraints not satisfied for class template 'r7' [with Ts = <int, type_requirement::A>]}}
114 namespace expr_requirement
{
115 // check that compound/simple requirements are instantiated correctly.
117 template<typename T
> requires false_v
<requires
{ sizeof(T
); { sizeof(T
) }; }>
118 // expected-note@-1 {{because 'false_v<requires { sizeof(int); { sizeof(int) }; }>' evaluated to false}}
119 // expected-note@-2 {{because 'false_v<requires { <<error-expression>>; { sizeof(T) }; }>' evaluated to false}}
122 using r1i1
= r1
<int>; // expected-error{{constraints not satisfied for class template 'r1' [with T = int]}}
123 using r1i2
= r1
<void>; // expected-error{{constraints not satisfied for class template 'r1' [with T = void]}}
125 // substitution error occurs in expr, then expr is instantiated again.
129 template<typename U
> requires (requires
{ sizeof(T::a
); }, false) // expected-note{{because 'requires { <<error-expression>>; } , false' evaluated to false}}
133 using ari
= a
<int>::r
<short>; // expected-error{{constraints not satisfied for class template 'r' [with U = short]}}
135 // check that the return-type-requirement is instantiated correctly.
137 template<typename T
, typename U
= int>
138 concept C1
= is_same_v
<T
, U
>;
140 template<typename T
> requires false_v
<requires(T t
) { { t
} -> C1
<T
>; }>
141 // expected-note@-1 {{because 'false_v<requires (int t) { { t } -> C1<int>; }>' evaluated to false}}
142 // expected-note@-2 {{because 'false_v<requires (double t) { { t } -> C1<double>; }>' evaluated to false}}
145 using r2i1
= r2
<int>; // expected-error{{constraints not satisfied for class template 'r2' [with T = int]}}
146 using r2i2
= r2
<double>; // expected-error{{constraints not satisfied for class template 'r2' [with T = double]}}
149 // substitution error occurs in return type requirement, then requires expr is
150 // instantiated again.
154 template<typename U
> requires (requires
{ { 0 } -> C1
<typename
T::a
>; }, false) // expected-note{{because 'requires { { 0 } -> <<error-type>>; } , false' evaluated to false}}
158 using bri
= b
<int>::r
<short>; // expected-error{{constraints not satisfied for class template 'r' [with U = short]}}
161 template<typename
... Ts
> requires
162 false_v
<(requires
{ { 0 } noexcept
-> C1
<Ts
>; } && ...)>
163 // expected-note@-1 {{because 'false_v<requires { { 0 } noexcept -> C1<int>; } && requires { { 0 } noexcept -> C1<unsigned int>; }>' evaluated to false}}
166 using r3i
= r3
<int, unsigned int>; // expected-error{{constraints not satisfied for class template 'r3' [with Ts = <int, unsigned int>]}}
170 constexpr int foo() {
171 if constexpr (requires
{ this->invalid(); })
177 constexpr void invalid() requires
false { }
179 static_assert(r4
<int>{}.foo() == 0);
182 namespace nested_requirement
{
183 // check that constraint expression is instantiated correctly
184 template<typename T
> requires false_v
<requires
{ requires
sizeof(T
) == 2; }> // expected-note{{because 'false_v<requires { requires sizeof(int) == 2; }>' evaluated to false}}
187 using r1i
= r1
<int>; // expected-error{{constraints not satisfied for class template 'r1' [with T = int]}}
189 // substitution error occurs in expr, then expr is instantiated again.
192 template<typename U
> requires
193 (requires
{ requires
sizeof(T::a
) == 0; }, false) // expected-note{{because 'requires { requires <<error-expression>>; } , false' evaluated to false}}
197 using ari
= a
<int>::r
<short>; // expected-error{{constraints not satisfied for class template 'r' [with U = short]}}
199 // Parameter pack inside expr
200 template<typename
... Ts
> requires
201 false_v
<(requires
{ requires
sizeof(Ts
) == 0; } && ...)>
202 // expected-note@-1 {{because 'false_v<requires { requires sizeof(int) == 0; } && requires { requires sizeof(short) == 0; }>' evaluated to false}}
205 using r2i
= r2
<int, short>; // expected-error{{constraints not satisfied for class template 'r2' [with Ts = <int, short>]}}
208 // Parameter pack inside multiple requirements
209 template<typename
... Ts
> requires
210 false_v
<(requires
{ requires
sizeof(Ts
) == 0; sizeof(Ts
); } && ...)>
211 // expected-note@-1 {{because 'false_v<requires { requires sizeof(int) == 0; sizeof(Ts); } && requires { requires sizeof(short) == 0; sizeof(Ts); }>' evaluated to false}}
214 using r4i
= r4
<int, short>; // expected-error{{constraints not satisfied for class template 'r4' [with Ts = <int, short>]}}
216 template<typename
... Ts
> requires
217 false_v
<(requires(Ts t
) { requires
sizeof(t
) == 0; t
++; } && ...)>
218 // expected-note@-1 {{because 'false_v<requires (int t) { requires sizeof (t) == 0; t++; } && requires (short t) { requires sizeof (t) == 0; t++; }>' evaluated to false}}
221 using r5i
= r5
<int, short>; // expected-error{{constraints not satisfied for class template 'r5' [with Ts = <int, short>]}}
223 template<typename T
> requires
224 false_v
<(requires(T t
) { T
{t
}; })> // T{t} creates an "UnevaluatedList" context.
225 // expected-note@-1 {{because 'false_v<(requires (int t) { int{t}; })>' evaluated to false}}
229 // expected-error@-1 {{constraints not satisfied for class template 'r6' [with T = int]}}