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