xref: /llvm-project/clang/test/SemaTemplate/concepts-lambda.cpp (revision f07e5162d0e67ec980e0ea282cf294f377407b10)
16b0b306eSErich Keane // RUN: %clang_cc1 -std=c++20 -verify %s
2975740bfSErich Keane // RUN: %clang_cc1 -std=c++20 -verify %s -triple powerpc64-ibm-aix
36b0b306eSErich Keane 
46b0b306eSErich Keane namespace GH57945 {
56b0b306eSErich Keane   template<typename T>
66b0b306eSErich Keane     concept c = true;
76b0b306eSErich Keane 
86b0b306eSErich Keane   template<typename>
96b0b306eSErich Keane     auto f = []() requires c<void> {
106b0b306eSErich Keane     };
116b0b306eSErich Keane 
126b0b306eSErich Keane   void g() {
136b0b306eSErich Keane       f<int>();
146b0b306eSErich Keane   };
156b0b306eSErich Keane }
16939a3d22SErich Keane 
17939a3d22SErich Keane namespace GH57945_2 {
18939a3d22SErich Keane   template<typename>
19939a3d22SErich Keane     concept c = true;
20939a3d22SErich Keane 
21939a3d22SErich Keane   template<typename T>
22939a3d22SErich Keane     auto f = [](auto... args) requires c<T>  {
23939a3d22SErich Keane     };
24939a3d22SErich Keane 
25939a3d22SErich Keane   template <typename T>
26939a3d22SErich Keane   auto f2 = [](auto... args)
27939a3d22SErich Keane     requires (sizeof...(args) > 0)
28939a3d22SErich Keane   {};
29939a3d22SErich Keane 
30939a3d22SErich Keane   void g() {
31939a3d22SErich Keane       f<void>();
32939a3d22SErich Keane       f2<void>(5.0);
33939a3d22SErich Keane   }
34939a3d22SErich Keane }
35939a3d22SErich Keane 
36939a3d22SErich Keane namespace GH57958 {
37939a3d22SErich Keane   template<class> concept C = true;
38939a3d22SErich Keane   template<int> constexpr bool v = [](C auto) { return true; }(0);
39939a3d22SErich Keane   int _ = v<0>;
40939a3d22SErich Keane }
41939a3d22SErich Keane namespace GH57958_2 {
42939a3d22SErich Keane   template<class> concept C = true;
43939a3d22SErich Keane   template<int> constexpr bool v = [](C auto...) { return true; }(0);
44939a3d22SErich Keane   int _ = v<0>;
45939a3d22SErich Keane }
46939a3d22SErich Keane 
47939a3d22SErich Keane namespace GH57971 {
48939a3d22SErich Keane   template<typename>
49939a3d22SErich Keane     concept any = true;
50939a3d22SErich Keane 
51939a3d22SErich Keane   template<typename>
52939a3d22SErich Keane     auto f = [](any auto) {
53939a3d22SErich Keane     };
54939a3d22SErich Keane 
55939a3d22SErich Keane   using function_ptr = void(*)(int);
56939a3d22SErich Keane   function_ptr ptr = f<void>;
57939a3d22SErich Keane }
58975740bfSErich Keane 
59975740bfSErich Keane // GH58368: A lambda defined in a concept requires we store
60975740bfSErich Keane // the concept as a part of the lambda context.
61975740bfSErich Keane namespace LambdaInConcept {
62975740bfSErich Keane using size_t = unsigned long;
63975740bfSErich Keane 
64975740bfSErich Keane template<size_t...Ts>
65975740bfSErich Keane struct IdxSeq{};
66975740bfSErich Keane 
67975740bfSErich Keane template <class T, class... Ts>
68975740bfSErich Keane concept NotLike = true;
69975740bfSErich Keane 
70975740bfSErich Keane template <size_t, class... Ts>
71975740bfSErich Keane struct AnyExcept {
72975740bfSErich Keane   template <NotLike<Ts...> T> operator T&() const;
73975740bfSErich Keane   template <NotLike<Ts...> T> operator T&&() const;
74975740bfSErich Keane };
75975740bfSErich Keane 
76975740bfSErich Keane template <class T>
77975740bfSErich Keane   concept ConstructibleWithN = (requires {
78975740bfSErich Keane                                 []<size_t I, size_t... Idxs>
79975740bfSErich Keane                                 (IdxSeq<I, Idxs...>)
80975740bfSErich Keane                                 requires requires { T{AnyExcept<I, T>{}}; }
81975740bfSErich Keane                                 { }
82975740bfSErich Keane                                 (IdxSeq<1,2,3>{});
83975740bfSErich Keane     });
84975740bfSErich Keane 
85975740bfSErich Keane struct Foo {
86975740bfSErich Keane   int i;
87975740bfSErich Keane   double j;
88975740bfSErich Keane   char k;
89975740bfSErich Keane };
90975740bfSErich Keane 
91975740bfSErich Keane static_assert(ConstructibleWithN<Foo>);
92975740bfSErich Keane 
939fe5aa31SYounan Zhang namespace GH56556 {
949fe5aa31SYounan Zhang 
959fe5aa31SYounan Zhang template <typename It>
969fe5aa31SYounan Zhang inline constexpr It declare ();
979fe5aa31SYounan Zhang 
989fe5aa31SYounan Zhang template <typename It, template <typename> typename Template>
999fe5aa31SYounan Zhang concept D = requires {
1009fe5aa31SYounan Zhang 	{ [] <typename T1> (Template<T1> &) {}(declare<It &>()) };
1019fe5aa31SYounan Zhang };
1029fe5aa31SYounan Zhang 
1039fe5aa31SYounan Zhang template <typename T>
1049fe5aa31SYounan Zhang struct B {};
1059fe5aa31SYounan Zhang 
1069fe5aa31SYounan Zhang template <typename T>
1079fe5aa31SYounan Zhang struct Adapter;
1089fe5aa31SYounan Zhang 
1099fe5aa31SYounan Zhang template <D<B> T>
1109fe5aa31SYounan Zhang struct Adapter<T> {};
1119fe5aa31SYounan Zhang 
1129fe5aa31SYounan Zhang template struct Adapter<B<int>>;
1139fe5aa31SYounan Zhang 
1149fe5aa31SYounan Zhang } // namespace GH56556
1159fe5aa31SYounan Zhang 
1169fe5aa31SYounan Zhang namespace GH82849 {
1179fe5aa31SYounan Zhang 
1189fe5aa31SYounan Zhang template <class T>
1199fe5aa31SYounan Zhang concept C = requires(T t) {
1209fe5aa31SYounan Zhang   requires requires (T u) {
1219fe5aa31SYounan Zhang     []<class V>(V) {
1229fe5aa31SYounan Zhang       return requires(V v) {
1239fe5aa31SYounan Zhang         [](V w) {}(v);
1249fe5aa31SYounan Zhang       };
1259fe5aa31SYounan Zhang     }(t);
1269fe5aa31SYounan Zhang   };
1279fe5aa31SYounan Zhang };
1289fe5aa31SYounan Zhang 
1299fe5aa31SYounan Zhang template <class From>
1309fe5aa31SYounan Zhang struct Widget;
1319fe5aa31SYounan Zhang 
1329fe5aa31SYounan Zhang template <C F>
1339fe5aa31SYounan Zhang struct Widget<F> {
1349fe5aa31SYounan Zhang   static F create(F from) {
1359fe5aa31SYounan Zhang     return from;
1369fe5aa31SYounan Zhang   }
1379fe5aa31SYounan Zhang };
1389fe5aa31SYounan Zhang 
1399fe5aa31SYounan Zhang template <class>
1409fe5aa31SYounan Zhang bool foo() {
1419fe5aa31SYounan Zhang   return C<int>;
1429fe5aa31SYounan Zhang }
1439fe5aa31SYounan Zhang 
1449fe5aa31SYounan Zhang void bar() {
1459fe5aa31SYounan Zhang   // https://github.com/llvm/llvm-project/issues/49570#issuecomment-1664966972
1469fe5aa31SYounan Zhang   Widget<char>::create(0);
1479fe5aa31SYounan Zhang }
1489fe5aa31SYounan Zhang 
1499fe5aa31SYounan Zhang } // namespace GH82849
1509fe5aa31SYounan Zhang 
151975740bfSErich Keane }
1524bf6cc63SErich Keane 
1534bf6cc63SErich Keane // GH60642 reported an assert being hit, make sure we don't assert.
1544bf6cc63SErich Keane namespace GH60642 {
1554bf6cc63SErich Keane template<auto Q> concept C = requires { Q.template operator()<float>(); };
1564bf6cc63SErich Keane template<class> concept D = true;
1574bf6cc63SErich Keane static_assert(C<[]<D>{}>);  // ok
1584bf6cc63SErich Keane template<class> concept E = C<[]<D>{}>;
1594bf6cc63SErich Keane static_assert(E<int>);  // previously Asserted.
1604bf6cc63SErich Keane 
1614bf6cc63SErich Keane // ensure we properly diagnose when "D" is false.
1624bf6cc63SErich Keane namespace DIsFalse {
1634bf6cc63SErich Keane template<auto Q> concept C = requires { Q.template operator()<float>(); };
1644bf6cc63SErich Keane template<class> concept D = false;
1654bf6cc63SErich Keane static_assert(C<[]<D>{}>);
1664bf6cc63SErich Keane // expected-error@-1{{static assertion failed}}
1674bf6cc63SErich Keane // expected-note@-2{{does not satisfy 'C'}}
1684bf6cc63SErich Keane // expected-note@-5{{because 'Q.template operator()<float>()' would be invalid: no matching member function for call to 'operator()'}}
1694bf6cc63SErich Keane template<class> concept E = C<[]<D>{}>;
1704bf6cc63SErich Keane static_assert(E<int>);
1714bf6cc63SErich Keane // expected-error@-1{{static assertion failed}}
1724bf6cc63SErich Keane // expected-note@-2{{because 'int' does not satisfy 'E'}}
1734bf6cc63SErich Keane // expected-note@-4{{does not satisfy 'C'}}
1744bf6cc63SErich Keane // expected-note@-11{{because 'Q.template operator()<float>()' would be invalid: no matching member function for call to 'operator()'}}
1754bf6cc63SErich Keane }
1764bf6cc63SErich Keane }
177e78a1f49S刘雨培 
178e78a1f49S刘雨培 namespace ReturnTypeRequirementInLambda {
179e78a1f49S刘雨培 template <typename T>
180e78a1f49S刘雨培 concept C1 = true;
181e78a1f49S刘雨培 
182e78a1f49S刘雨培 template <class T>
183e78a1f49S刘雨培 concept test = [] {
184e78a1f49S刘雨培   return requires(T t) {
185e78a1f49S刘雨培     { t } -> C1;
186e78a1f49S刘雨培   };
187e78a1f49S刘雨培 }();
188e78a1f49S刘雨培 
189e78a1f49S刘雨培 static_assert(test<int>);
190e78a1f49S刘雨培 
191e78a1f49S刘雨培 template <typename T>
192e78a1f49S刘雨培 concept C2 = true;
193e78a1f49S刘雨培 struct S1 {
194e78a1f49S刘雨培   int f1() { return 1; }
195e78a1f49S刘雨培 };
196e78a1f49S刘雨培 
197e78a1f49S刘雨培 void foo() {
198e78a1f49S刘雨培   auto make_caller = []<auto member> {
199e78a1f49S刘雨培     return [](S1 *ps) {
200e78a1f49S刘雨培       if constexpr (requires {
201e78a1f49S刘雨培                       { (ps->*member)() } -> C2;
202e78a1f49S刘雨培                     })
203e78a1f49S刘雨培         ;
204e78a1f49S刘雨培     };
205e78a1f49S刘雨培   };
206e78a1f49S刘雨培 
207e78a1f49S刘雨培   auto caller = make_caller.operator()<&S1::f1>();
208e78a1f49S刘雨培 }
209e78a1f49S刘雨培 } // namespace ReturnTypeRequirementInLambda
2106e6c506fSYounan Zhang 
2116e6c506fSYounan Zhang namespace GH73418 {
2126e6c506fSYounan Zhang void foo() {
2136e6c506fSYounan Zhang   int x;
2146e6c506fSYounan Zhang   [&x](auto) {
2156e6c506fSYounan Zhang     return [](auto y) {
2166e6c506fSYounan Zhang       return [](auto obj, auto... params)
2176e6c506fSYounan Zhang         requires requires {
2186e6c506fSYounan Zhang           sizeof...(params);
2196e6c506fSYounan Zhang           [](auto... pack) {
2206e6c506fSYounan Zhang             return sizeof...(pack);
2216e6c506fSYounan Zhang           }(params...);
2226e6c506fSYounan Zhang         }
2236e6c506fSYounan Zhang       { return false; }(y);
2246e6c506fSYounan Zhang     }(x);
2256e6c506fSYounan Zhang   }(x);
2266e6c506fSYounan Zhang }
2276e6c506fSYounan Zhang } // namespace GH73418
22816397e8eSYounan Zhang 
22916397e8eSYounan Zhang namespace GH93821 {
23016397e8eSYounan Zhang 
23116397e8eSYounan Zhang template <class>
23216397e8eSYounan Zhang concept C = true;
23316397e8eSYounan Zhang 
23416397e8eSYounan Zhang template <class...>
23516397e8eSYounan Zhang concept D = []<C T = int>() { return true; }();
23616397e8eSYounan Zhang 
23716397e8eSYounan Zhang D auto x = 0;
23816397e8eSYounan Zhang 
23916397e8eSYounan Zhang } // namespace GH93821
240f0c7505fSYupei Liu 
241f0c7505fSYupei Liu namespace dependent_param_concept {
242f0c7505fSYupei Liu template <typename... Ts> void sink(Ts...) {}
243f0c7505fSYupei Liu void dependent_param() {
244f0c7505fSYupei Liu   auto L = [](auto... x) {
245f0c7505fSYupei Liu     return [](decltype(x)... y) {
246f0c7505fSYupei Liu       return [](int z)
247f0c7505fSYupei Liu         requires requires { sink(y..., z); }
248f0c7505fSYupei Liu       {};
249f0c7505fSYupei Liu     };
250f0c7505fSYupei Liu   };
251f0c7505fSYupei Liu   L(0, 1)(1, 2)(1);
252f0c7505fSYupei Liu }
253f0c7505fSYupei Liu } // namespace dependent_param_concept
25452126dc7SYupei Liu 
25552126dc7SYupei Liu namespace init_captures {
25652126dc7SYupei Liu template <int N> struct V {};
25752126dc7SYupei Liu 
25852126dc7SYupei Liu void sink(V<0>, V<1>, V<2>, V<3>, V<4>) {}
25952126dc7SYupei Liu 
26052126dc7SYupei Liu void init_capture_pack() {
26152126dc7SYupei Liu   auto L = [](auto... z) {
26252126dc7SYupei Liu     return [=](auto... y) {
26352126dc7SYupei Liu       return [... w = z, y...](auto)
26452126dc7SYupei Liu         requires requires { sink(w..., y...); }
26552126dc7SYupei Liu       {};
26652126dc7SYupei Liu     };
26752126dc7SYupei Liu   };
26852126dc7SYupei Liu   L(V<0>{}, V<1>{}, V<2>{})(V<3>{}, V<4>{})(1);
26952126dc7SYupei Liu }
27052126dc7SYupei Liu 
27152126dc7SYupei Liu void dependent_capture_packs() {
27252126dc7SYupei Liu   auto L = [](auto... z) {
27352126dc7SYupei Liu     return [... w = z](auto... y) {
27452126dc7SYupei Liu       return [... c = w](auto)
27552126dc7SYupei Liu         requires requires { sink(c..., y...); }
27652126dc7SYupei Liu       {};
27752126dc7SYupei Liu     };
27852126dc7SYupei Liu   };
27952126dc7SYupei Liu   L(V<0>{}, V<1>{}, V<2>{})(V<3>{}, V<4>{})(1);
28052126dc7SYupei Liu }
28152126dc7SYupei Liu } // namespace init_captures
2825064c4c4SYounan Zhang 
2835064c4c4SYounan Zhang namespace GH110721 {
2845064c4c4SYounan Zhang 
2855064c4c4SYounan Zhang template <int N> void connect() {
2865064c4c4SYounan Zhang   int x = N, y = N;
2875064c4c4SYounan Zhang   [x, y = y]()
2885064c4c4SYounan Zhang     requires requires { x; }
2895064c4c4SYounan Zhang   {}();
2905064c4c4SYounan Zhang }
2915064c4c4SYounan Zhang 
2925064c4c4SYounan Zhang void foo() {
2935064c4c4SYounan Zhang   connect<42>();
2945064c4c4SYounan Zhang }
2955064c4c4SYounan Zhang 
2965064c4c4SYounan Zhang } // namespace GH110721
297*f07e5162SYounan Zhang 
298*f07e5162SYounan Zhang namespace GH123441 {
299*f07e5162SYounan Zhang 
300*f07e5162SYounan Zhang void test() {
301*f07e5162SYounan Zhang   auto L = [](auto... x) {
302*f07e5162SYounan Zhang     return [](decltype(x)... y)
303*f07e5162SYounan Zhang       requires true
304*f07e5162SYounan Zhang     {};
305*f07e5162SYounan Zhang   };
306*f07e5162SYounan Zhang   L(0, 1)(1, 2);
307*f07e5162SYounan Zhang }
308*f07e5162SYounan Zhang 
309*f07e5162SYounan Zhang }
310