1 // RUN: %clang_cc1 -std=c++20 %s -Wno-c++23-extensions -verify
2 // RUN: %clang_cc1 -std=c++23 %s -verify
5 template <auto> struct Nothing
{};
6 Nothing
<[]() { return 0; }()> nothing
;
8 template <typename
> struct NothingT
{};
9 Nothing
<[]() { return 0; }> nothingT
;
12 concept True
= [] { return true; }();
13 static_assert(True
<int>);
15 static_assert(sizeof([] { return 0; }));
16 static_assert(sizeof([] { return 0; }()));
18 void f() noexcept(noexcept([] { return 0; }()));
20 using a
= decltype([] { return 0; });
21 using b
= decltype([] { return 0; }());
22 using c
= decltype([]() noexcept(noexcept([] { return 0; }())) { return 0; });
23 using d
= decltype(sizeof([] { return 0; }));
27 static_assert(&unique_test1
<[](){}> != &unique_test1
<[](){}>);
30 auto g(T
) -> decltype([]() { T::invalid
; } ());
31 auto e
= g(0); // expected-error@-1{{type 'int' cannot be used prior to '::'}}
32 // expected-note@-1{{while substituting deduced template}}
33 // expected-note@-3{{while substituting into a lambda}}
34 // expected-error@-3 {{no matching function for call to 'g'}}
35 // expected-note@-5 {{substitution failure}}
38 auto foo(decltype([] {
39 return [] { return T(); }();
49 auto foo(decltype([] {
50 return [] { return T(); }();
55 C
<int>{}.foo
<long>({});
59 // OK, these are distinct functions not redefinitions.
60 template<typename
> void f(decltype([]{})) {} // expected-note {{candidate}}
61 template<typename
> void f(decltype([]{})) {} // expected-note {{candidate}}
62 void use_f() { f
<int>({}); } // expected-error {{ambiguous}}
65 template<int N
> void g(const char (*)[([]{ return N
; })()]) {} // expected-note {{candidate}}
66 template<int N
> void g(const char (*)[([]{ return N
; })()]) {} // expected-note {{candidate}}
67 void use_g() { g
<6>(&"hello"); } // expected-error {{ambiguous}}
74 void spam(decltype([] {}));
78 void A
<T
>::spam(decltype([] {})) // expected-error{{out-of-line definition of 'spam' does not match}}
83 void spam(decltype([] {}));
87 void B::spam(decltype([] {})) {} // expected-error{{out-of-line definition of 'spam' does not match}}
89 } // namespace GH51416
93 template <typename T
, typename Fn
>
94 struct foo_t
{ // expected-note 2{{candidate constructor}}
95 foo_t(T ptr
) {} // expected-note{{candidate constructor}}
99 using alias
= foo_t
<T
, decltype([](int) { return 0; })>;
101 template <typename T
>
102 auto fun(T
const &t
) -> alias
<T
> {
103 return alias
<T
>{t
}; // expected-error{{no viable conversion from returned value of type 'alias<...>'}}
108 auto const error
= fun(i
); // expected-note{{in instantiation}}
111 } // namespace GH50376
114 template <class T
> void spam(decltype([] {}) (*s
)[sizeof(T
)] = nullptr) {}
118 } // namespace GH51414
122 void foo(decltype(+[](T
) {}) lambda
, T param
);
123 static_assert(!__is_same(decltype(foo
<int>), void));
124 } // namespace GH51641
126 namespace StaticLambdas
{
127 template <auto> struct Nothing
{};
128 Nothing
<[]() static { return 0; }()> nothing
;
130 template <typename
> struct NothingT
{};
131 Nothing
<[]() static { return 0; }> nothingT
;
133 template <typename T
>
134 concept True
= [] static { return true; }();
135 static_assert(True
<int>);
137 static_assert(sizeof([] static { return 0; }));
138 static_assert(sizeof([] static { return 0; }()));
140 void f() noexcept(noexcept([] static { return 0; }()));
142 using a
= decltype([] static { return 0; });
143 using b
= decltype([] static { return 0; }());
144 using c
= decltype([]() static noexcept(noexcept([] { return 0; }())) { return 0; });
145 using d
= decltype(sizeof([] static { return 0; }));
149 namespace lambda_in_trailing_decltype
{
150 auto x
= ([](auto) -> decltype([] {}()) {}(0), 2);
153 namespace lambda_in_constraints
{
154 struct WithFoo
{ static void foo(); };
157 concept lambda_works
= requires
{
158 []() { T::foo(); }; // expected-error{{type 'int' cannot be used prior to '::'}}
159 // expected-note@-1{{while substituting into a lambda expression here}}
160 // expected-note@-2{{in instantiation of requirement here}}
161 // expected-note@-4{{while substituting template arguments into constraint expression here}}
164 static_assert(!lambda_works
<int>); // expected-note {{while checking the satisfaction of concept 'lambda_works<int>' requested here}}
165 static_assert(lambda_works
<WithFoo
>);
168 int* func(T
) requires requires
{ []() { T::foo(); }; }; // expected-error{{type 'int' cannot be used prior to '::'}}
169 // expected-note@-1{{while substituting into a lambda expression here}}
170 // expected-note@-2{{in instantiation of requirement here}}
171 // expected-note@-3{{while substituting template arguments into constraint expression here}}
174 static_assert(__is_same(decltype(func(0)), double*)); // expected-note {{while checking constraint satisfaction for template 'func<int>' required here}}
175 // expected-note@-1 {{in instantiation of function template specialization 'lambda_in_constraints::func<int>'}}
176 static_assert(__is_same(decltype(func(WithFoo())), int*));
179 auto direct_lambda(T
) -> decltype([] { T::foo(); }) {}
180 void direct_lambda(...) {}
183 direct_lambda(0); // expected-error@-4 {{type 'int' cannot be used prior to '::'}}
184 // expected-note@-1 {{while substituting deduced template arguments}}
185 // expected-note@-6 {{while substituting into a lambda}}
186 bool x
= requires
{ direct_lambda(0); }; // expected-error@-7 {{type 'int' cannot be used prior to '::'}}
187 // expected-note@-1 {{while substituting deduced template arguments}}
188 // expected-note@-9 {{while substituting into a lambda}}