xref: /llvm-project/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp (revision 3972ed57088f6515b787d7d38dec03dc74e51827)
1 // RUN: %clang_cc1 -fsyntax-only -triple x86_64-unknown-linux -Wno-c++11-narrowing -Wno-literal-conversion -std=c++20 -verify %s
2 
3 namespace test1 {
4 template <typename T>
5 struct Foo { T t; };
6 template <typename U>
7 using Bar = Foo<U>;
8 
9 Bar s = {1};
10 }  // namespace test1
11 
12 namespace test2 {
13 template <typename X, typename Y>
14 struct XYpair {
15   X x;
16   Y y;
17 };
18 // A tricky explicit deduction guide that swapping X and Y.
19 template <typename X, typename Y>
20 XYpair(X, Y) -> XYpair<Y, X>;
21 template <typename U, typename V>
22 using AliasXYpair = XYpair<U, V>;
23 
24 AliasXYpair xy = {1.1, 2};  // XYpair<int, double>
25 static_assert(__is_same(decltype(xy.x), int));
26 static_assert(__is_same(decltype(xy.y), double));
27 }  // namespace test2
28 
29 namespace test3 {
30 template <typename T, class>
31 struct container {
32   // test with default arguments.
33   container(T a, T b = T());
34 };
35 
36 template <class T>
37 using vector = container<T, int>;
38 vector v(0, 0);
39 }  // namespace test3
40 
41 namespace test4 {
42 // Explicit deduction guide.
43 template <class T>
44 struct X {
45   T t;
46   X(T);
47 };
48 
49 template <class T>
50 X(T) -> X<double>;
51 
52 template <class T>
53 using AX = X<T>;
54 
55 AX s = {1};
56 static_assert(__is_same(decltype(s.t), double)); // explicit one is picked.
57 }  // namespace test4
58 
59 namespace test5 {
60 template <int B>
61 struct Foo {};
62 // Template parameter pack
63 template <int... C>
64 using AF = Foo<1>;
65 auto a = AF{};
66 }  // namespace test5
67 
68 namespace test6 {
69 // non-type template argument.
70 template <typename T, bool B = false>
71 struct Foo {
72   Foo(T);
73 };
74 template <typename T>
75 using AF = Foo<T, 1>;
76 
77 AF b{0};
78 }  // namespace test6
79 
80 namespace test7 {
81 template <typename T>
82 struct Foo {
83   Foo(T);
84 };
85 // using alias chain.
86 template <typename U>
87 using AF1 = Foo<U>;
88 template <typename K>
89 using AF2 = AF1<K>;
90 AF2 b = 1;
91 }  // namespace test7
92 
93 namespace test8 {
94 template <typename T, int N>
95 struct Foo {
96   Foo(T const (&)[N]);
97 };
98 
99 template <typename X, int Y>
100 using Bar = Foo<X, Y>;
101 
102 Bar s = {{1}};
103 }  // namespace test8
104 
105 namespace test9 {
106 template <typename T, int N>
107 struct Foo {
108   Foo(T const (&)[N]);
109 };
110 
111 template <typename X, int Y>
112 using Bar = Foo<X, sizeof(X)>; // expected-note {{candidate template ignored: couldn't infer template argument 'X'}} \
113                                // expected-note {{implicit deduction guide declared as 'template <typename X> requires __is_deducible(test9::Bar, Foo<X, sizeof(X)>) Bar(Foo<X, sizeof(X)>) -> Foo<X, sizeof(X)>'}} \
114                                // expected-note {{implicit deduction guide declared as 'template <typename X> requires __is_deducible(test9::Bar, Foo<X, sizeof(X)>) Bar(const X (&)[sizeof(X)]) -> Foo<X, sizeof(X)>'}} \
115                                // expected-note {{candidate template ignored: constraints not satisfied [with X = int]}} \
116                                // expected-note {{cannot deduce template arguments for 'Bar' from 'Foo<int, 4UL>'}}
117 
118 
119 Bar s = {{1}}; // expected-error {{no viable constructor or deduction guide }}
120 }  // namespace test9
121 
122 namespace test10 {
123 template <typename T>
124 struct Foo {
125   template <typename U>
126   Foo(U);
127 };
128 
129 template <typename U>
130 Foo(U) -> Foo<U*>;
131 
132 template <typename K>
133 using A = Foo<K>;
134 A a(2);  // Foo<int*>
135 }  // namespace test10
136 
137 namespace test11 {
138 struct A {};
139 template<class T> struct Foo { T c; };
140 template<class X, class Y=A>
141 using AFoo = Foo<Y>; // expected-note {{candidate template ignored: could not match 'Foo<Y>' against 'int'}} \
142                     // expected-note {{implicit deduction guide declared as 'template <class Y = A> requires __is_deducible(test11::AFoo, Foo<Y>) AFoo(Foo<Y>) -> Foo<Y>'}} \
143                     // expected-note {{candidate template ignored: constraints not satisfied [with Y = int]}} \
144                     // expected-note {{cannot deduce template arguments for 'AFoo' from 'Foo<int>'}} \
145                     // expected-note {{implicit deduction guide declared as 'template <class Y = A> requires __is_deducible(test11::AFoo, Foo<Y>) AFoo(Y) -> Foo<Y>'}} \
146                     // expected-note {{candidate function template not viable: requires 0 arguments, but 1 was provided}} \
147                     // expected-note {{implicit deduction guide declared as 'template <class Y = A> requires __is_deducible(test11::AFoo, Foo<Y>) AFoo() -> Foo<Y>'}}
148 
149 AFoo s = {1}; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'AFoo'}}
150 } // namespace test11
151 
152 namespace test12 {
153 // no crash on null access attribute
154 template<typename X>
155 struct Foo {
156   template<typename K>
157   struct Bar {
158     Bar(K);
159   };
160 
161   template<typename U>
162   using ABar = Bar<U>;
163   void test() { ABar k = 2; }
164 };
165 
166 void func(Foo<int> s) {
167   s.test();
168 }
169 } // namespace test12
170 
171 namespace test13 {
172 template <typename... Ts>
173 struct Foo {
174   Foo(Ts...);
175 };
176 
177 template <typename... Ts>
178 using AFoo = Foo<Ts...>;
179 
180 auto b = AFoo{};
181 AFoo a(1, 2);
182 
183 template <typename T>
184 using BFoo = Foo<T, T>;
185 BFoo b2(1.0, 2.0);
186 } // namespace test13
187 
188 namespace test14 {
189 template<typename T>
190 concept IsInt = __is_same(decltype(T()), int);
191 
192 template<IsInt T, int N>
193 struct Foo {
194   Foo(T const (&)[N]);
195 };
196 
197 template <int K>
198 using Bar = Foo<double, K>; // expected-note {{constraints not satisfied for class template 'Foo'}}
199 // expected-note@-1 {{candidate template ignored: could not match}}
200 // expected-note@-2 {{implicit deduction guide declared as 'template <int K> requires __is_deducible(test14::Bar, Foo<double, K>) Bar(Foo<double, K>) -> Foo<double, K>'}}
201 // expected-note@-3 {{implicit deduction guide declared as 'template <int K> requires __is_deducible(test14::Bar, Foo<double, K>) Bar(const double (&)[K]) -> Foo<double, K>'}}
202 double abc[3];
203 Bar s2 = {abc}; // expected-error {{no viable constructor or deduction guide for deduction }}
204 } // namespace test14
205 
206 namespace test15 {
207 template <class T> struct Foo { Foo(T); };
208 
209 template<class V> using AFoo = Foo<V *>;
210 template<typename> concept False = false;
211 template<False W>
212 using BFoo = AFoo<W>; // expected-note {{candidate template ignored: constraints not satisfied [with V = int]}} \
213                       // expected-note {{cannot deduce template arguments for 'BFoo' from 'Foo<int *>'}} \
214                       // expected-note {{implicit deduction guide declared as 'template <class V> requires __is_deducible(AFoo, Foo<V *>) && __is_deducible(test15::BFoo, Foo<V *>) BFoo(V *) -> Foo<V *>}} \
215                       // expected-note {{candidate template ignored: could not match 'Foo<V *>' against 'int *'}} \
216                       // expected-note {{template <class V> requires __is_deducible(AFoo, Foo<V *>) && __is_deducible(test15::BFoo, Foo<V *>) BFoo(Foo<V *>) -> Foo<V *>}}
217 int i = 0;
218 AFoo a1(&i); // OK, deduce Foo<int *>
219 
220 // the W is not deduced from the deduced type Foo<int *>.
221 BFoo b2(&i); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'BFoo'}}
222 } // namespace test15
223 
224 namespace test16 {
225 struct X { X(int); X(const X&); };
226 template<class T>
227 struct Foo {
228   T t;
229   Foo(T t) : t(t) {}
230 };
231 template<class T>
232 using AFoo = Foo<T>;
233 int i = 0;
234 AFoo s{i};
235 static_assert(__is_same(decltype(s.t), int));
236 
237 // explicit deduction guide.
238 Foo(int) -> Foo<X>;
239 AFoo s2{i};
240 // FIXME: the type should be X because of the above explicit deduction guide.
241 static_assert(__is_same(decltype(s2.t), int));
242 } // namespace test16
243 
244 namespace test17 {
245 template <typename T>
246 struct Foo { T t; };
247 
248 // CTAD for alias templates only works for the RHS of the alias of form of
249 //  [typename] [nested-name-specifier] [template] simple-template-id
250 template <typename U>
251 using AFoo = Foo<U>*; // expected-note {{template is declared here}}
252 
253 AFoo s = {1}; // expected-error {{alias template 'AFoo' requires template arguments; argument deduction only allowed for}}
254 } // namespace test17
255 
256 namespace test18 {
257 template<typename T>
258 concept False = false; // expected-note {{because 'false' evaluated to false}}
259 
260 template <typename T> struct Foo { T t; };
261 
262 template<typename T> requires False<T> // expected-note {{because 'int' does not satisfy 'False'}}
263 Foo(T) -> Foo<int>;
264 
265 template <typename U>
266 using Bar = Foo<U>; // expected-note {{could not match 'Foo<U>' against 'int'}} \
267                     // expected-note {{implicit deduction guide declared as 'template <typename U> requires __is_deducible(test18::Bar, Foo<U>) Bar(Foo<U>) -> Foo<U>'}} \
268                     // expected-note {{candidate template ignored: constraints not satisfied}} \
269                     // expected-note {{implicit deduction guide declared as 'template <typename T> requires False<T> && __is_deducible(test18::Bar, Foo<int>) Bar(T) -> Foo<int>'}} \
270                     // expected-note {{candidate function template not viable}} \
271                     // expected-note {{implicit deduction guide declared as 'template <typename U> requires __is_deducible(test18::Bar, Foo<U>) Bar() -> Foo<U>'}}
272 
273 Bar s = {1}; // expected-error {{no viable constructor or deduction guide for deduction of template arguments}}
274 } // namespace test18
275 
276 // GH85406, verify no crash on invalid alias templates.
277 namespace test19 {
278 template <typename T>
279 class Foo {};
280 
281 template <typename T>
282 template <typename K>
283 using Bar2 = Foo<K>; // expected-error {{extraneous template parameter list in alias template declaration}}
284 
285 Bar2 b = 1; // expected-error {{no viable constructor or deduction guide for deduction of template arguments}}
286 } // namespace test19
287 
288 // GH85385
289 namespace test20 {
290 template <template <typename> typename T>
291 struct K {};
292 
293 template <typename U>
294 class Foo {};
295 
296 // Verify that template template type parameter TTP is referenced/used in the
297 // template arguments of the RHS.
298 template <template<typename> typename TTP>
299 using Bar = Foo<K<TTP>>; // expected-note {{candidate template ignored: could not match 'Foo<K<TTP>>' against 'int'}} \
300                         // expected-note {{implicit deduction guide declared as 'template <template <typename> typename TTP> requires __is_deducible(test20::Bar, Foo<K<TTP>>) Bar(Foo<K<TTP>>) -> Foo<K<TTP>>'}}
301 
302 template <class T>
303 class Container {};
304 Bar t = Foo<K<Container>>();
305 
306 Bar s = 1; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of}}
307 } // namespace test20
308 
309 namespace test21 {
310 template <typename T, unsigned N>
311 struct Array { const T member[N]; };
312 template <unsigned N>
313 using String = Array<char, N>;
314 
315 // Verify no crash on constructing the aggregate deduction guides.
316 String s("hello");
317 } // namespace test21
318 
319 // GH89013
320 namespace test22 {
321 class Base {};
322 template <typename T>
323 class Derived final : public Base {};
324 
325 template <typename T, typename D>
326 requires __is_base_of(Base, D)
327 struct Foo {
328   explicit Foo(D) {}
329 };
330 
331 template <typename U>
332 using AFoo = Foo<int, Derived<U>>;
333 
334 AFoo a(Derived<int>{});
335 } // namespace test22
336 
337 namespace test23 {
338 // We have an aggregate deduction guide "G(T) -> G<T>".
339 template<typename T>
340 struct G { T t1; };
341 
342 template<typename X = int>
343 using AG = G<int>;
344 
345 AG ag(1.0);
346 // Verify that the aggregate deduction guide "AG(int) -> AG<int>" is built and
347 // choosen.
348 static_assert(__is_same(decltype(ag.t1), int));
349 } // namespace test23
350 
351 // GH90177
352 // verify that the transformed require-clause of the alias deduction gudie has
353 // the right depth info.
354 namespace test24 {
355 class Forward;
356 class Key {};
357 
358 template <typename D>
359 constexpr bool C = sizeof(D);
360 
361 // Case1: the alias template and the underlying deduction guide are in the same
362 // scope.
363 template <typename T>
364 struct Case1 {
365   template <typename U>
366   struct Foo {
367     Foo(U);
368   };
369 
370   template <typename V>
371   requires (C<V>)
372   Foo(V) -> Foo<V>;
373 
374   template <typename Y>
375   using Alias = Foo<Y>;
376 };
377 // The require-clause should be evaluated on the type Key.
378 Case1<Forward>::Alias t2 = Key();
379 
380 
381 // Case2: the alias template and underlying deduction guide are in different
382 // scope.
383 template <typename T>
384 struct Foo {
385   Foo(T);
386 };
387 template <typename U>
388 requires (C<U>)
389 Foo(U) -> Foo<U>;
390 
391 template <typename T>
392 struct Case2 {
393   template <typename Y>
394   using Alias = Foo<Y>;
395 };
396 // The require-caluse should be evaluated on the type Key.
397 Case2<Forward>::Alias t1 = Key();
398 
399 // Case3: crashes on the constexpr evaluator due to the mixed-up depth in
400 // require-expr.
401 template <class T1>
402 struct A1 {
403   template<class T2>
404   struct A2 {
405     template <class T3>
406     struct Foo {
407       Foo(T3);
408     };
409     template <class T3>
410     requires C<T3>
411     Foo(T3) -> Foo<T3>;
412   };
413 };
414 template <typename U>
415 using AFoo = A1<int>::A2<int>::Foo<U>;
416 AFoo case3(1);
417 
418 // Case4: crashes on the constexpr evaluator due to the mixed-up index for the
419 // template parameters `V`.
420 template<class T, typename T2>
421 struct Case4 {
422   template<class V> requires C<V>
423   Case4(V, T);
424 };
425 
426 template<class T2>
427 using ACase4 = Case4<T2, T2>;
428 ACase4 case4{0, 1};
429 
430 } // namespace test24
431 
432 namespace GH92212 {
433 template<typename T, typename...Us>
434 struct A{
435   template<typename V> requires __is_same(V, int)
436   A(V);
437 };
438 
439 template<typename...TS>
440 using AA = A<int, TS...>;
441 AA a{0};
442 }
443 
444 namespace GH94927 {
445 template <typename T>
446 struct A {
447   A(T);
448 };
449 A(int) -> A<char>;
450 
451 template <typename U>
452 using B1 = A<U>;
453 B1 b1(100); // deduce to A<char>;
454 static_assert(__is_same(decltype(b1), A<char>));
455 
456 template <typename U>
457 requires (!__is_same(U, char)) // filter out the explicit deduction guide.
458 using B2 = A<U>;
459 template <typename V>
460 using B3 = B2<V>;
461 
462 B2 b2(100); // deduced to A<int>;
463 static_assert(__is_same(decltype(b2), A<int>));
464 B3 b3(100); // decuded to A<int>;
465 static_assert(__is_same(decltype(b3), A<int>));
466 
467 
468 // the nested case
469 template <typename T1>
470 struct Out {
471   template <typename T2>
472   struct A {
473     A(T2);
474   };
475   A(int) -> A<T1>;
476 
477   template <typename T3>
478   using B = A<T3>;
479 };
480 
481 Out<float>::B out(100); // deduced to Out<float>::A<float>;
482 static_assert(__is_same(decltype(out), Out<float>::A<float>));
483 }
484 
485 namespace GH111508 {
486 
487 template <typename V> struct S {
488   using T = V;
489   T Data;
490 };
491 
492 template <typename V> using Alias = S<V>;
493 
494 Alias A(42);
495 
496 } // namespace GH111508
497 
498 namespace GH113518 {
499 
500 template <class T, unsigned N> struct array {
501   T value[N];
502 };
503 
504 template <typename Tp, typename... Up>
505 array(Tp, Up...) -> array<Tp, 1 + sizeof...(Up)>;
506 
507 template <typename T> struct ArrayType {
508   template <unsigned size> using Array = array<T, size>;
509 };
510 
511 template <ArrayType<int>::Array array> void test() {}
512 
513 void foo() { test<{1, 2, 3}>(); }
514 
515 } // namespace GH113518
516