1 // RUN: %clang_cc1 -std=c++20 -verify %s
3 // A lambda-expression appearing in a function type or a template parameter is
4 // not considered part of the immediate context for the purposes of template
6 // [Note: The intent is to avoid requiring implementations to deal with
7 // substitution failure involving arbitrary statements.]
9 auto f(T
) -> decltype([]() { T::invalid
; } ());
12 f(0); // expected-error@-3 {{type 'int' cannot be used prior to '::'}}
13 // expected-note@-1 {{while substituting deduced template arguments}}
14 // expected-note@-5 {{while substituting into a lambda expression here}}
17 template <class T
, unsigned = sizeof([]() { T::invalid
; })>
21 g(0); // expected-error@-4 {{type 'int' cannot be used prior to '::'}}
22 // expected-note@-4 {{in instantiation of default argument}}
23 // expected-note@-2 {{while substituting deduced template arguments}}
24 // expected-note@-7 {{while substituting into a lambda expression here}}
28 auto h(T
) -> decltype([x
= T::invalid
]() { });
31 h(0); // expected-error@-3 {{type 'int' cannot be used prior to '::'}}
32 // expected-note@-1 {{while substituting deduced template arguments}}
33 // expected-note@-5 {{while substituting into a lambda expression here}}
37 auto i(T
) -> decltype([]() -> typename
T::invalid
{ });
40 i(0); // expected-error@-3 {{type 'int' cannot be used prior to '::'}}
41 // expected-note@-1 {{while substituting deduced template arguments}}
42 // expected-note@-5 {{while substituting into a lambda expression here}}
46 // In this example, the lambda itself is not part of an immediate context, but
47 // substitution to the lambda expression succeeds, producing dependent
48 // `decltype(x.invalid)`. The call to the lambda, however, is in the immediate context
49 // and it produces a SFINAE failure. Hence, we pick the second overload
50 // and don't produce any errors.
52 auto j(T t
) -> decltype([](auto x
) -> decltype(x
.invalid
) { } (t
)); // #1
55 j(0); // deduction fails on #1, calls #2.