xref: /llvm-project/clang/test/SemaTemplate/alias-template-with-lambdas.cpp (revision b412ec5d3924c7570c2c96106f95a92403a4e09b)
1 // RUN: %clang_cc1 -std=c++2c -fsyntax-only -verify %s
2 namespace lambda_calls {
3 
4 template <class>
5 concept True = true;
6 
7 template <class>
8 concept False = false; // #False
9 
10 template <class T> struct S {
11   template <class... U> using type = decltype([](U...) {}(U()...));
12   template <class U> using type2 = decltype([](auto) {}(1));
13   template <class U> using type3 = decltype([](True auto) {}(1));
14   template <class>
15   using type4 = decltype([](auto... pack) { return sizeof...(pack); }(1, 2));
16 
17   template <class U> using type5 = decltype([](False auto...) {}(1)); // #Type5
18 
19   template <class U>
20   using type6 = decltype([]<True> {}.template operator()<char>());
21   template <class U>
22   using type7 = decltype([]<False> {}.template operator()<char>()); // #Type7
23 
24   template <class U>
25   using type8 = decltype([]() // #Type8
26                            requires(sizeof(U) == 32) // #Type8-requirement
27                          {}());
28 
29   template <class... U>
30   using type9 = decltype([]<True>(U...) {}.template operator()<char>(U()...));
31   // https://github.com/llvm/llvm-project/issues/76674
32   template <class U>
33   using type10 = decltype([]<class V> { return V(); }.template operator()<U>());
34 
35   template <class U> using type11 = decltype([] { return U{}; });
36 };
37 
38 template <class> using Meow = decltype([]<True> {}.template operator()<int>());
39 
40 template <class... U>
41 using MeowMeow = decltype([]<True>(U...) {}.template operator()<char>(U()...));
42 
43 // https://github.com/llvm/llvm-project/issues/70601
44 template <class> using U = decltype([]<True> {}.template operator()<int>());
45 
46 U<int> foo();
47 
48 void bar() {
49   using T = S<int>::type<int, int, int>;
50   using T2 = S<int>::type2<int>;
51   using T3 = S<int>::type3<char>;
52   using T4 = S<int>::type4<void>;
53   using T5 = S<int>::type5<void>; // #T5
54   // expected-error@#Type5 {{no matching function for call}}
55   // expected-note@#T5 {{type alias 'type5' requested here}}
56   // expected-note@#Type5 {{constraints not satisfied [with auto:1 = <int>]}}
57   // expected-note@#Type5 {{because 'int' does not satisfy 'False'}}
58   // expected-note@#False {{because 'false' evaluated to false}}
59 
60   using T6 = S<int>::type6<void>;
61   using T7 = S<int>::type7<void>; // #T7
62   // expected-error@#Type7 {{no matching member function for call}}
63   // expected-note@#T7 {{type alias 'type7' requested here}}
64   // expected-note@#Type7 {{constraints not satisfied [with $0 = char]}}
65   // expected-note@#Type7 {{because 'char' does not satisfy 'False'}}
66   // expected-note@#False {{because 'false' evaluated to false}}
67 
68   using T8 = S<int>::type8<char>; // #T8
69   // expected-error@#Type8 {{no matching function for call}}
70   // expected-note@#T8 {{type alias 'type8' requested here}}
71   // expected-note@#Type8 {{constraints not satisfied}}
72   // expected-note@#Type8-requirement {{because 'sizeof(char) == 32' (1 == 32) evaluated to false}}
73 
74   using T9 = S<int>::type9<long, long, char>;
75   using T10 = S<int>::type10<int>;
76   using T11 = S<int>::type11<int>;
77   int x = T11()();
78   using T12 = Meow<int>;
79   using T13 = MeowMeow<char, int, long, unsigned>;
80 
81   static_assert(__is_same(T, void));
82   static_assert(__is_same(T2, void));
83   static_assert(__is_same(T3, void));
84   static_assert(__is_same(T4, decltype(sizeof(0))));
85   static_assert(__is_same(T6, void));
86   static_assert(__is_same(T9, void));
87   static_assert(__is_same(T10, int));
88   static_assert(__is_same(T12, void));
89   static_assert(__is_same(T13, void));
90 }
91 
92 namespace GH82104 {
93 
94 template <typename, typename... D> constexpr int Value = sizeof...(D);
95 
96 template <typename T, typename... U>
97 using T14 = decltype([]<int V = 0>(auto Param) {
98   return Value<T, U...> + V + (int)sizeof(Param);
99 }("hello"));
100 
101 template <typename T> using T15 = T14<T, T>;
102 
103 static_assert(__is_same(T15<char>, int));
104 
105 // FIXME: This still crashes because we can't extract template arguments T and U
106 // outside of the instantiation context of T16.
107 #if 0
108 template <typename T, typename... U>
109 using T16 = decltype([](auto Param) requires (sizeof(Param) != 1 && sizeof...(U) > 0) {
110   return Value<T, U...> + sizeof(Param);
111 });
112 static_assert(T16<int, char, float>()(42) == 2 + sizeof(42));
113 #endif
114 } // namespace GH82104
115 
116 namespace GH89853 {
117 
118 template <typename = void>
119 static constexpr auto innocuous = []<int m> { return m; };
120 
121 template <auto Pred = innocuous<>>
122 using broken = decltype(Pred.template operator()<42>());
123 
124 broken<> *boom;
125 
126 template <auto Pred =
127               []<char c> {
128                 (void)static_cast<char>(c);
129               }>
130 using broken2 = decltype(Pred.template operator()<42>());
131 
132 broken2<> *boom2;
133 
134 template <auto Pred = []<char m> { return m; }>
135 using broken3 = decltype(Pred.template operator()<42>());
136 
137 broken3<> *boom3;
138 
139 static constexpr auto non_default = []<char c>(True auto) {
140     (void) static_cast<char>(c);
141 };
142 
143 template<True auto Pred>
144 using broken4 = decltype(Pred.template operator()<42>(Pred));
145 
146 broken4<non_default>* boom4;
147 
148 } // namespace GH89853
149 
150 namespace GH105885 {
151 
152 template<int>
153 using test = decltype([](auto...) {
154 }());
155 
156 static_assert(__is_same(test<0>, void));
157 
158 } // namespace GH105885
159 
160 namespace GH102760 {
161 
162 auto make_tuple = []< class Tag, class... Captures>(Tag, Captures...) {
163   return []< class _Fun >( _Fun) -> void requires requires { 0; }
164   {};
165 };
166 
167 template < class, class... _As >
168 using Result = decltype(make_tuple(0)(_As{}...));
169 
170 using T = Result<int, int>;
171 
172 } // namespace GH102760
173 
174 } // namespace lambda_calls
175