1629170feSIlya Biryukov // RUN: %clang_cc1 -std=c++20 -verify %s 2629170feSIlya Biryukov // [temp.deduct.p9] 3629170feSIlya Biryukov // A lambda-expression appearing in a function type or a template parameter is 4629170feSIlya Biryukov // not considered part of the immediate context for the purposes of template 5629170feSIlya Biryukov // argument deduction. 6629170feSIlya Biryukov // [Note: The intent is to avoid requiring implementations to deal with 7629170feSIlya Biryukov // substitution failure involving arbitrary statements.] 8629170feSIlya Biryukov template <class T> __anonc5a543d20102() 9629170feSIlya Biryukovauto f(T) -> decltype([]() { T::invalid; } ()); 10629170feSIlya Biryukov void f(...); test_f()11629170feSIlya Biryukovvoid test_f() { 12629170feSIlya Biryukov f(0); // expected-error@-3 {{type 'int' cannot be used prior to '::'}} 13629170feSIlya Biryukov // expected-note@-1 {{while substituting deduced template arguments}} 14629170feSIlya Biryukov // expected-note@-5 {{while substituting into a lambda expression here}} 15629170feSIlya Biryukov } 16629170feSIlya Biryukov 17629170feSIlya Biryukov template <class T, unsigned = sizeof([]() { T::invalid; })> 18629170feSIlya Biryukov void g(T); 19629170feSIlya Biryukov void g(...); test_g()20629170feSIlya Biryukovvoid test_g() { 21629170feSIlya Biryukov g(0); // expected-error@-4 {{type 'int' cannot be used prior to '::'}} 22629170feSIlya Biryukov // expected-note@-4 {{in instantiation of default argument}} 23629170feSIlya Biryukov // expected-note@-2 {{while substituting deduced template arguments}} 24629170feSIlya Biryukov // expected-note@-7 {{while substituting into a lambda expression here}} 25629170feSIlya Biryukov } 26629170feSIlya Biryukov 27629170feSIlya Biryukov template <class T> __anonc5a543d20202() 28629170feSIlya Biryukovauto h(T) -> decltype([x = T::invalid]() { }); 29629170feSIlya Biryukov void h(...); test_h()30629170feSIlya Biryukovvoid test_h() { 31*3eeed799SYounan Zhang h(0); 32629170feSIlya Biryukov } 33629170feSIlya Biryukov 34629170feSIlya Biryukov template <class T> __anonc5a543d20302() 35629170feSIlya Biryukovauto i(T) -> decltype([]() -> typename T::invalid { }); 36629170feSIlya Biryukov void i(...); test_i()37629170feSIlya Biryukovvoid test_i() { 38*3eeed799SYounan Zhang i(0); 39629170feSIlya Biryukov } 40629170feSIlya Biryukov 41629170feSIlya Biryukov 42629170feSIlya Biryukov // In this example, the lambda itself is not part of an immediate context, but 43629170feSIlya Biryukov // substitution to the lambda expression succeeds, producing dependent 44629170feSIlya Biryukov // `decltype(x.invalid)`. The call to the lambda, however, is in the immediate context 45629170feSIlya Biryukov // and it produces a SFINAE failure. Hence, we pick the second overload 46629170feSIlya Biryukov // and don't produce any errors. 47629170feSIlya Biryukov template <class T> 48629170feSIlya Biryukov auto j(T t) -> decltype([](auto x) -> decltype(x.invalid) { } (t)); // #1 49629170feSIlya Biryukov void j(...); // #2 test_j()50629170feSIlya Biryukovvoid test_j() { 51629170feSIlya Biryukov j(0); // deduction fails on #1, calls #2. 52629170feSIlya Biryukov } 53