annotate clang/test/SemaTemplate/instantiate-requires-expr.cpp @ 150:1d019706d866

LLVM10
author anatofuz
date Thu, 13 Feb 2020 15:10:13 +0900
parents
children 0572611fdcc8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 // RUN: %clang_cc1 -std=c++2a -x c++ %s -verify -Wno-unused-value
anatofuz
parents:
diff changeset
2
anatofuz
parents:
diff changeset
3 template<typename T, typename U>
anatofuz
parents:
diff changeset
4 constexpr bool is_same_v = false;
anatofuz
parents:
diff changeset
5
anatofuz
parents:
diff changeset
6 template<typename T>
anatofuz
parents:
diff changeset
7 constexpr bool is_same_v<T, T> = true;
anatofuz
parents:
diff changeset
8
anatofuz
parents:
diff changeset
9 // We use a hack in this file to make the compiler print out the requires
anatofuz
parents:
diff changeset
10 // expression after it has been instantiated - we put false_v<requires {...}> as
anatofuz
parents:
diff changeset
11 // the requires clause of a class template, then instantiate the template.
anatofuz
parents:
diff changeset
12 // The requirement will not be satisfied, and the explaining diagnostic will
anatofuz
parents:
diff changeset
13 // print out false_v<requires {...}> in its raw form (the false_v serves to
anatofuz
parents:
diff changeset
14 // prevent the diagnostic from elaborating on why the requires expr wasn't
anatofuz
parents:
diff changeset
15 // satisfied).
anatofuz
parents:
diff changeset
16
anatofuz
parents:
diff changeset
17 template<bool v>
anatofuz
parents:
diff changeset
18 constexpr bool false_v = false;
anatofuz
parents:
diff changeset
19
anatofuz
parents:
diff changeset
20 template<typename... Ts>
anatofuz
parents:
diff changeset
21 using void_t = void;
anatofuz
parents:
diff changeset
22
anatofuz
parents:
diff changeset
23 // Check that requires parameters are instantiated correctly.
anatofuz
parents:
diff changeset
24
anatofuz
parents:
diff changeset
25 template<typename T> requires
anatofuz
parents:
diff changeset
26 false_v<requires (T t) { requires is_same_v<decltype(t), int>; }>
anatofuz
parents:
diff changeset
27 // expected-note@-1 {{because 'false_v<requires (int t) { requires is_same_v<decltype(t), int>; }>' evaluated to false}}
anatofuz
parents:
diff changeset
28 // expected-note@-2 {{because 'false_v<requires (char t) { requires is_same_v<decltype(t), int>; }>' evaluated to false}}
anatofuz
parents:
diff changeset
29 struct r1 {};
anatofuz
parents:
diff changeset
30
anatofuz
parents:
diff changeset
31 using r1i1 = r1<int>; // expected-error {{constraints not satisfied for class template 'r1' [with T = int]}}
anatofuz
parents:
diff changeset
32 using r1i2 = r1<char>; // expected-error {{constraints not satisfied for class template 'r1' [with T = char]}}
anatofuz
parents:
diff changeset
33
anatofuz
parents:
diff changeset
34 // Check that parameter packs work.
anatofuz
parents:
diff changeset
35
anatofuz
parents:
diff changeset
36 template<typename... Ts> requires
anatofuz
parents:
diff changeset
37 false_v<requires (Ts... ts) {requires ((sizeof(ts) == 2) && ...);}>
anatofuz
parents:
diff changeset
38 // expected-note@-1 {{because 'false_v<requires (short ts, unsigned short ts) { requires (sizeof (ts) == 2) && (sizeof (ts) == 2); }>'}}
anatofuz
parents:
diff changeset
39 // expected-note@-2 {{because 'false_v<requires (short ts) { requires (sizeof (ts) == 2); }>' evaluated to false}}
anatofuz
parents:
diff changeset
40 struct r2 {};
anatofuz
parents:
diff changeset
41
anatofuz
parents:
diff changeset
42 using r2i1 = r2<short, unsigned short>; // expected-error {{constraints not satisfied for class template 'r2' [with Ts = <short, unsigned short>]}}
anatofuz
parents:
diff changeset
43 using r2i2 = r2<short>; // expected-error {{constraints not satisfied for class template 'r2' [with Ts = <short>]}}
anatofuz
parents:
diff changeset
44
anatofuz
parents:
diff changeset
45 template<typename... Ts> requires
anatofuz
parents:
diff changeset
46 false_v<(requires (Ts ts) {requires sizeof(ts) != 0;} && ...)>
anatofuz
parents:
diff changeset
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}}
anatofuz
parents:
diff changeset
48 // expected-note@-2 {{because 'false_v<requires (short ts) { requires sizeof (ts) != 0; }>' evaluated to false}}
anatofuz
parents:
diff changeset
49 struct r3 {};
anatofuz
parents:
diff changeset
50
anatofuz
parents:
diff changeset
51 using r3i1 = r3<short, unsigned short>; // expected-error {{constraints not satisfied for class template 'r3' [with Ts = <short, unsigned short>]}}
anatofuz
parents:
diff changeset
52 using r3i2 = r3<short>; // expected-error {{constraints not satisfied for class template 'r3' [with Ts = <short>]}}
anatofuz
parents:
diff changeset
53
anatofuz
parents:
diff changeset
54 template<typename T>
anatofuz
parents:
diff changeset
55 struct identity { using type = T; };
anatofuz
parents:
diff changeset
56
anatofuz
parents:
diff changeset
57 namespace type_requirement {
anatofuz
parents:
diff changeset
58 struct A {};
anatofuz
parents:
diff changeset
59
anatofuz
parents:
diff changeset
60 // check that nested name specifier is instantiated correctly.
anatofuz
parents:
diff changeset
61 template<typename T> requires false_v<requires { typename T::type; }> // expected-note{{because 'false_v<requires { typename identity<int>::type; }>' evaluated to false}}
anatofuz
parents:
diff changeset
62 struct r1 {};
anatofuz
parents:
diff changeset
63
anatofuz
parents:
diff changeset
64 using r1i = r1<identity<int>>; // expected-error{{constraints not satisfied for class template 'r1' [with T = identity<int>]}}
anatofuz
parents:
diff changeset
65
anatofuz
parents:
diff changeset
66 // check that template argument list is instantiated correctly.
anatofuz
parents:
diff changeset
67 template<typename T>
anatofuz
parents:
diff changeset
68 struct contains_template {
anatofuz
parents:
diff changeset
69 template<typename U> requires is_same_v<contains_template<T>, U>
anatofuz
parents:
diff changeset
70 using temp = int;
anatofuz
parents:
diff changeset
71 };
anatofuz
parents:
diff changeset
72
anatofuz
parents:
diff changeset
73 template<typename T> requires
anatofuz
parents:
diff changeset
74 false_v<requires { typename T::template temp<T>; }>
anatofuz
parents:
diff changeset
75 // expected-note@-1 {{because 'false_v<requires { typename contains_template<int>::temp<contains_template<int> >; }>' evaluated to false}}
anatofuz
parents:
diff changeset
76 // expected-note@-2 {{because 'false_v<requires { typename contains_template<short>::temp<contains_template<short> >; }>' evaluated to false}}
anatofuz
parents:
diff changeset
77 struct r2 {};
anatofuz
parents:
diff changeset
78
anatofuz
parents:
diff changeset
79 using r2i1 = r2<contains_template<int>>; // expected-error{{constraints not satisfied for class template 'r2' [with T = type_requirement::contains_template<int>]}}
anatofuz
parents:
diff changeset
80 using r2i2 = r2<contains_template<short>>; // expected-error{{constraints not satisfied for class template 'r2' [with T = type_requirement::contains_template<short>]}}
anatofuz
parents:
diff changeset
81
anatofuz
parents:
diff changeset
82 // substitution error occurs, then requires expr is instantiated again
anatofuz
parents:
diff changeset
83
anatofuz
parents:
diff changeset
84 template<typename T>
anatofuz
parents:
diff changeset
85 struct a {
anatofuz
parents:
diff changeset
86 template<typename U> requires (requires { typename T::a::a; }, false)
anatofuz
parents:
diff changeset
87 // expected-note@-1{{because 'requires { <<error-type>>; } , false' evaluated to false}}
anatofuz
parents:
diff changeset
88 struct r {};
anatofuz
parents:
diff changeset
89 };
anatofuz
parents:
diff changeset
90
anatofuz
parents:
diff changeset
91 using ari = a<int>::r<short>; // expected-error{{constraints not satisfied for class template 'r' [with U = short]}}
anatofuz
parents:
diff changeset
92
anatofuz
parents:
diff changeset
93 // Parameter pack inside expr
anatofuz
parents:
diff changeset
94 template<typename... Ts> requires
anatofuz
parents:
diff changeset
95 false_v<(requires { typename Ts::type; } && ...)>
anatofuz
parents:
diff changeset
96 // expected-note@-1 {{because 'false_v<requires { typename identity<short>::type; } && requires { typename identity<int>::type; } && requires { <<error-type>>; }>' evaluated to false}}
anatofuz
parents:
diff changeset
97 struct r5 {};
anatofuz
parents:
diff changeset
98
anatofuz
parents:
diff changeset
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>]}}
anatofuz
parents:
diff changeset
100 template<typename... Ts> requires
anatofuz
parents:
diff changeset
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}}
anatofuz
parents:
diff changeset
102 struct r6 {};
anatofuz
parents:
diff changeset
103
anatofuz
parents:
diff changeset
104 using r6i = r6<int, short>; // expected-error{{constraints not satisfied for class template 'r6' [with Ts = <int, short>]}}
anatofuz
parents:
diff changeset
105
anatofuz
parents:
diff changeset
106 template<typename... Ts> requires
anatofuz
parents:
diff changeset
107 false_v<(requires { typename Ts::template aaa<Ts>; } && ...)>
anatofuz
parents:
diff changeset
108 // expected-note@-1 {{because 'false_v<requires { <<error-type>>; } && requires { <<error-type>>; }>' evaluated to false}}
anatofuz
parents:
diff changeset
109 struct r7 {};
anatofuz
parents:
diff changeset
110
anatofuz
parents:
diff changeset
111 using r7i = r7<int, A>; // expected-error{{constraints not satisfied for class template 'r7' [with Ts = <int, type_requirement::A>]}}
anatofuz
parents:
diff changeset
112 }
anatofuz
parents:
diff changeset
113
anatofuz
parents:
diff changeset
114 namespace expr_requirement {
anatofuz
parents:
diff changeset
115 // check that compound/simple requirements are instantiated correctly.
anatofuz
parents:
diff changeset
116
anatofuz
parents:
diff changeset
117 template<typename T> requires false_v<requires { sizeof(T); { sizeof(T) }; }>
anatofuz
parents:
diff changeset
118 // expected-note@-1 {{because 'false_v<requires { sizeof(int); { sizeof(int) }; }>' evaluated to false}}
anatofuz
parents:
diff changeset
119 // expected-note@-2 {{because 'false_v<requires { <<error-expression>>; { sizeof(T) }; }>' evaluated to false}}
anatofuz
parents:
diff changeset
120 struct r1 {};
anatofuz
parents:
diff changeset
121
anatofuz
parents:
diff changeset
122 using r1i1 = r1<int>; // expected-error{{constraints not satisfied for class template 'r1' [with T = int]}}
anatofuz
parents:
diff changeset
123 using r1i2 = r1<void>; // expected-error{{constraints not satisfied for class template 'r1' [with T = void]}}
anatofuz
parents:
diff changeset
124
anatofuz
parents:
diff changeset
125 // substitution error occurs in expr, then expr is instantiated again.
anatofuz
parents:
diff changeset
126
anatofuz
parents:
diff changeset
127 template<typename T>
anatofuz
parents:
diff changeset
128 struct a {
anatofuz
parents:
diff changeset
129 template<typename U> requires (requires { sizeof(T::a); }, false) // expected-note{{because 'requires { <<error-expression>>; } , false' evaluated to false}}
anatofuz
parents:
diff changeset
130 struct r {};
anatofuz
parents:
diff changeset
131 };
anatofuz
parents:
diff changeset
132
anatofuz
parents:
diff changeset
133 using ari = a<int>::r<short>; // expected-error{{constraints not satisfied for class template 'r' [with U = short]}}
anatofuz
parents:
diff changeset
134
anatofuz
parents:
diff changeset
135 // check that the return-type-requirement is instantiated correctly.
anatofuz
parents:
diff changeset
136
anatofuz
parents:
diff changeset
137 template<typename T, typename U = int>
anatofuz
parents:
diff changeset
138 concept C1 = is_same_v<T, U>;
anatofuz
parents:
diff changeset
139
anatofuz
parents:
diff changeset
140 template<typename T> requires false_v<requires(T t) { { t } -> C1<T>; }>
anatofuz
parents:
diff changeset
141 // expected-note@-1 {{because 'false_v<requires (int t) { { t } -> C1<int>; }>' evaluated to false}}
anatofuz
parents:
diff changeset
142 // expected-note@-2 {{because 'false_v<requires (double t) { { t } -> C1<double>; }>' evaluated to false}}
anatofuz
parents:
diff changeset
143 struct r2 {};
anatofuz
parents:
diff changeset
144
anatofuz
parents:
diff changeset
145 using r2i1 = r2<int>; // expected-error{{constraints not satisfied for class template 'r2' [with T = int]}}
anatofuz
parents:
diff changeset
146 using r2i2 = r2<double>; // expected-error{{constraints not satisfied for class template 'r2' [with T = double]}}
anatofuz
parents:
diff changeset
147
anatofuz
parents:
diff changeset
148
anatofuz
parents:
diff changeset
149 // substitution error occurs in return type requirement, then requires expr is
anatofuz
parents:
diff changeset
150 // instantiated again.
anatofuz
parents:
diff changeset
151
anatofuz
parents:
diff changeset
152 template<typename T>
anatofuz
parents:
diff changeset
153 struct b {
anatofuz
parents:
diff changeset
154 template<typename U> requires (requires { { 0 } -> C1<typename T::a>; }, false) // expected-note{{because 'requires { { 0 } -> <<error-type>>; } , false' evaluated to false}}
anatofuz
parents:
diff changeset
155 struct r {};
anatofuz
parents:
diff changeset
156 };
anatofuz
parents:
diff changeset
157
anatofuz
parents:
diff changeset
158 using bri = b<int>::r<short>; // expected-error{{constraints not satisfied for class template 'r' [with U = short]}}
anatofuz
parents:
diff changeset
159
anatofuz
parents:
diff changeset
160
anatofuz
parents:
diff changeset
161 template<typename... Ts> requires
anatofuz
parents:
diff changeset
162 false_v<(requires { { 0 } noexcept -> C1<Ts>; } && ...)>
anatofuz
parents:
diff changeset
163 // expected-note@-1 {{because 'false_v<requires { { 0 } noexcept -> C1<int>; } && requires { { 0 } noexcept -> C1<unsigned int>; }>' evaluated to false}}
anatofuz
parents:
diff changeset
164 struct r3 {};
anatofuz
parents:
diff changeset
165
anatofuz
parents:
diff changeset
166 using r3i = r3<int, unsigned int>; // expected-error{{constraints not satisfied for class template 'r3' [with Ts = <int, unsigned int>]}}
anatofuz
parents:
diff changeset
167 }
anatofuz
parents:
diff changeset
168
anatofuz
parents:
diff changeset
169 namespace nested_requirement {
anatofuz
parents:
diff changeset
170 // check that constraint expression is instantiated correctly
anatofuz
parents:
diff changeset
171 template<typename T> requires false_v<requires { requires sizeof(T) == 2; }> // expected-note{{because 'false_v<requires { requires sizeof(int) == 2; }>' evaluated to false}}
anatofuz
parents:
diff changeset
172 struct r1 {};
anatofuz
parents:
diff changeset
173
anatofuz
parents:
diff changeset
174 using r1i = r1<int>; // expected-error{{constraints not satisfied for class template 'r1' [with T = int]}}
anatofuz
parents:
diff changeset
175
anatofuz
parents:
diff changeset
176 // substitution error occurs in expr, then expr is instantiated again.
anatofuz
parents:
diff changeset
177 template<typename T>
anatofuz
parents:
diff changeset
178 struct a {
anatofuz
parents:
diff changeset
179 template<typename U> requires
anatofuz
parents:
diff changeset
180 (requires { requires sizeof(T::a) == 0; }, false) // expected-note{{because 'requires { requires <<error-expression>>; } , false' evaluated to false}}
anatofuz
parents:
diff changeset
181 struct r {};
anatofuz
parents:
diff changeset
182 };
anatofuz
parents:
diff changeset
183
anatofuz
parents:
diff changeset
184 using ari = a<int>::r<short>; // expected-error{{constraints not satisfied for class template 'r' [with U = short]}}
anatofuz
parents:
diff changeset
185
anatofuz
parents:
diff changeset
186 // Parameter pack inside expr
anatofuz
parents:
diff changeset
187 template<typename... Ts> requires
anatofuz
parents:
diff changeset
188 false_v<(requires { requires sizeof(Ts) == 0; } && ...)>
anatofuz
parents:
diff changeset
189 // expected-note@-1 {{because 'false_v<requires { requires sizeof(int) == 0; } && requires { requires sizeof(short) == 0; }>' evaluated to false}}
anatofuz
parents:
diff changeset
190 struct r2 {};
anatofuz
parents:
diff changeset
191
anatofuz
parents:
diff changeset
192 using r2i = r2<int, short>; // expected-error{{constraints not satisfied for class template 'r2' [with Ts = <int, short>]}}
anatofuz
parents:
diff changeset
193 }
anatofuz
parents:
diff changeset
194
anatofuz
parents:
diff changeset
195 // Parameter pack inside multiple requirements
anatofuz
parents:
diff changeset
196 template<typename... Ts> requires
anatofuz
parents:
diff changeset
197 false_v<(requires { requires sizeof(Ts) == 0; sizeof(Ts); } && ...)>
anatofuz
parents:
diff changeset
198 // expected-note@-1 {{because 'false_v<requires { requires sizeof(int) == 0; sizeof(Ts); } && requires { requires sizeof(short) == 0; sizeof(Ts); }>' evaluated to false}}
anatofuz
parents:
diff changeset
199 struct r4 {};
anatofuz
parents:
diff changeset
200
anatofuz
parents:
diff changeset
201 using r4i = r4<int, short>; // expected-error{{constraints not satisfied for class template 'r4' [with Ts = <int, short>]}}
anatofuz
parents:
diff changeset
202
anatofuz
parents:
diff changeset
203 template<typename... Ts> requires
anatofuz
parents:
diff changeset
204 false_v<(requires(Ts t) { requires sizeof(t) == 0; t++; } && ...)>
anatofuz
parents:
diff changeset
205 // 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}}
anatofuz
parents:
diff changeset
206 struct r5 {};
anatofuz
parents:
diff changeset
207
anatofuz
parents:
diff changeset
208 using r5i = r5<int, short>; // expected-error{{constraints not satisfied for class template 'r5' [with Ts = <int, short>]}}
anatofuz
parents:
diff changeset
209
anatofuz
parents:
diff changeset
210 template<typename T> requires
anatofuz
parents:
diff changeset
211 false_v<(requires(T t) { T{t}; })> // T{t} creates an "UnevaluatedList" context.
anatofuz
parents:
diff changeset
212 // expected-note@-1 {{because 'false_v<(requires (int t) { int{t}; })>' evaluated to false}}
anatofuz
parents:
diff changeset
213 struct r6 {};
anatofuz
parents:
diff changeset
214
anatofuz
parents:
diff changeset
215 using r6i = r6<int>;
anatofuz
parents:
diff changeset
216 // expected-error@-1 {{constraints not satisfied for class template 'r6' [with T = int]}}