xref: /llvm-project/clang/test/SemaTemplate/generic-lambda.cpp (revision af10d6f350ff3e92c6ffae66cc9dac36884cdd55)
1 // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
2 
3 // expected-no-diagnostics
4 
5 template <class T, class U> constexpr bool is_same_v = false;
6 template <class T> constexpr bool is_same_v<T, T> = true;
7 template <class T, class U>
8 concept is_same = is_same_v<T, U>;
9 
10 template <class T> struct X {};
11 template <class T, class U>
12 concept C1 = is_same<T, X<U>>;
13 
14 template <class T1> X<X<X<T1>>> t1() {
15   return []<class T2>(T2) -> X<X<T2>> {
16     struct S {
17       static X<X<T2>> f() {
18         return []<class T3>(T3) -> X<T3> {
19           static_assert(is_same<T2, X<T1>>);
20           static_assert(is_same<T3, X<T2>>);
21           return X<T3>();
22         }(X<T2>());
23       }
24     };
25     return S::f();
26   }(X<T1>());
27 };
28 template X<X<X<int>>> t1<int>();
29 
30 #if 0 // FIXME: crashes
31 template<class T1> auto t2() {
32   return []<class T2>(T2) {
33     struct S {
34       static auto f() {
35         return []<class T3>(T3) {
36           static_assert(is_same<T2, X<T1>>);
37           static_assert(is_same<T3, X<T2>>);
38           return X<T3>();
39         }(X<T2>());
40       }
41     };
42     return S::f();
43   }(X<T1>());
44 };
45 template auto t2<int>();
46 static_assert(is_same<decltype(t2<int>()), X<X<X<int>>>>);
47 
48 template<class T1> C1<X<X<T1>>> auto t3() {
49   return []<C1<T1> T2>(T2) -> C1<X<T2>> auto {
50     struct S {
51       static auto f() {
52         return []<C1<T2> T3>(T3) -> C1<T3> auto {
53           return X<T3>();
54         }(X<T2>());
55       }
56     };
57     return S::f();
58   }(X<T1>());
59 };
60 template C1<X<X<int>>> auto t3<int>();
61 static_assert(is_same<decltype(t3<int>()), X<X<X<int>>>>);
62 #endif
63