1 // RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s
10 template <class = void> void f() {
12 static_assert([]<class... Is
>(Is
... x
) {
18 []<class... Is
>(Is
... x
) {
19 return ([](auto y
= Is()) { return y
+ 1; }() + ...); // expected-error {{no matching function}} \
20 // expected-note {{couldn't infer template argument 'y:auto'}} \
21 // expected-note@-1 {{requested here}}
22 // expected-note@#instantiate-f {{requested here}}
30 }.template operator()<char, int, float>();
32 static_assert(__is_same(decltype([]<class... Is
>() {
33 return ([]() -> decltype(Is()) { return {}; }(),
35 }.template operator()<int, char>()),
39 return ([]<class... Ts
>() -> decltype(Is()) { return Ts(); }() + ...);
40 // expected-error@-1 {{unexpanded parameter pack 'Ts'}}
41 }.template operator()<int, int>();
43 // https://github.com/llvm/llvm-project/issues/56852
44 []<class... Is
>(Is
...) {
46 using T
= identity
<Is
>::type
;
56 ([x
..., y
] { }(), ...);
61 // FIXME: https://github.com/llvm/llvm-project/issues/18873
63 ([&](auto ...y
) { // #2
64 ([x
, y
] { }(), ...); // #3
68 // We run into another crash for the above lambda because of the absence of a
69 // mechanism that rebuilds an unexpanded pack from an expanded Decls.
71 // Basically, this happens after `x` at #1 being expanded when the template
72 // arguments at #5, deduced as <int, char>, are ready. When we want to
73 // instantiate the body of #1, we first instantiate the CallExpr at #4, which
74 // boils down to the lambda's instantiation at #2. To that end, we have to
75 // instantiate the body of it, which turns out to be #3. #3 is a CXXFoldExpr,
76 // and we immediately have to hold off on the expansion because we don't have
77 // corresponding template arguments (arguments at #4 are not transformed yet) for it.
78 // Therefore, we want to rebuild a CXXFoldExpr, which requires another pattern
79 // transformation of the lambda inside #3. Then we need to find an unexpanded form
80 // of such a Decl of x at the time of transforming the capture, which is impossible
81 // because the instantiated form has been expanded at #1!
83 [](auto ...x
) { // #outer
84 ([&](auto ...y
) { // #inner
86 // expected-error@-1 {{parameter pack 'y' that has a different length (4 vs. 3) from outer parameter packs}}
87 // expected-note-re@#inner {{function template specialization {{.*}} requested here}}
88 // expected-note-re@#outer {{function template specialization {{.*}} requested here}}
89 // expected-note-re@#instantiate-f {{function template specialization {{.*}} requested here}}
95 template void f(); // #instantiate-f
97 } // namespace GH85667
105 template <class F
> int apply(F f
, tuple v
) { return f(v
.x
[0], v
.x
[1], v
.x
[2]); }
107 int Cartesian1(auto x
, auto y
) {
110 return (apply([xs
](auto... ys
) { return (ys
+ ...); }, y
) + ...);
115 int Cartesian2(auto x
, auto y
) {
118 return (apply([zs
= xs
](auto... ys
) { return (ys
+ ...); }, y
) + ...);
123 template <int...> struct Ints
{};
124 template <int> struct Choose
{
125 template <class> struct Templ
;
127 template <int... x
> int Cartesian3(auto y
) {
128 return [&]<int... xs
>(Ints
<xs
...>) {
129 // check in default template arguments for
130 // - type template parameters,
131 (void)(apply([]<class = decltype(xs
)>(auto... ys
) { return (ys
+ ...); },
134 // - template template parameters.
135 (void)(apply([]<template <class> class = Choose
<xs
>::template Templ
>(
136 auto... ys
) { return (ys
+ ...); },
139 // - non-type template parameters,
140 return (apply([]<int = xs
>(auto... ys
) { return (ys
+ ...); }, y
) + ...);
144 template <int... x
> int Cartesian4(auto y
) {
145 return [&]<int... xs
>(Ints
<xs
...>) {
147 apply([]<decltype(xs
) xx
= 1>(auto... ys
) { return (ys
+ ...); }, y
) +
152 // FIXME: Attributes should preserve the ContainsUnexpandedPack flag.
155 int Cartesian5(auto x
, auto y
) {
158 return (apply([](auto... ys
) __attribute__((
159 diagnose_if(!__is_same(decltype(xs
), int), "message",
160 "error"))) { return (ys
+ ...); },
170 auto x
= tuple({1, 2, 3});
171 auto y
= tuple({4, 5, 6});
174 Cartesian3
<1, 2, 3>(y
);
175 Cartesian4
<1, 2, 3>(y
);
181 } // namespace GH99877
185 template <typename
... Ts
> struct Overloaded
: Ts
... {
186 using Ts::operator()...;
189 template <typename
... Ts
> Overloaded(Ts
...) -> Overloaded
<Ts
...>;
191 template <class T
, class U
>
192 concept same_as
= __is_same(T
, U
); // #same_as
194 template <typename
... Ts
> constexpr auto foo() {
195 return Overloaded
{[](same_as
<Ts
> auto value
) { return value
; }...}; // #lambda
198 static_assert(foo
<int, double>()(123) == 123);
199 static_assert(foo
<int, double>()(2.718) == 2.718);
201 static_assert(foo
<int, double>()('c'));
202 // expected-error@-1 {{no matching function}}
204 // expected-note@#lambda {{constraints not satisfied}}
205 // expected-note@#lambda {{'same_as<char, int>' evaluated to false}}
206 // expected-note@#same_as {{evaluated to false}}
208 // expected-note@#lambda {{constraints not satisfied}}
209 // expected-note@#lambda {{'same_as<char, double>' evaluated to false}}
210 // expected-note@#same_as {{evaluated to false}}
212 template <class T
, class U
, class V
>
213 concept C
= same_as
<T
, U
> && same_as
<U
, V
>; // #C
215 template <typename
... Ts
> constexpr auto bar() {
216 return ([]<class Up
>() {
217 return Overloaded
{[](C
<Up
, Ts
> auto value
) { // #bar
220 }.template operator()<Ts
>(), ...);
222 static_assert(bar
<int, float>()(3.14f
)); // OK, bar() returns the last overload i.e. <float>.
224 static_assert(bar
<int, float>()(123));
225 // expected-error@-1 {{no matching function}}
226 // expected-note@#bar {{constraints not satisfied}}
227 // expected-note@#bar {{'C<int, float, int>' evaluated to false}}
228 // expected-note@#C {{evaluated to false}}
230 // expected-note@#bar {{constraints not satisfied}}
231 // expected-note@#bar {{'C<int, float, float>' evaluated to false}}
232 // expected-note@#C {{evaluated to false}}
233 // expected-note@#same_as 2{{evaluated to false}}
235 } // namespace GH101754