xref: /llvm-project/clang/test/SemaTemplate/nested-implicit-deduction-guides.cpp (revision 3b639d7d1d9b9f352c57460deaf70aaad238f8d9)
1bee78b88Santangelo // RUN: %clang_cc1 -std=c++20 -verify %s
2bee78b88Santangelo 
3bee78b88Santangelo template<class T> struct S {
4bee78b88Santangelo     template<class U> struct N {
NS::N5bee78b88Santangelo         N(T) {}
NS::N6bee78b88Santangelo         N(T, U) {}
NS::N7bee78b88Santangelo         template<class V> N(V, U) {}
8bee78b88Santangelo     };
9bee78b88Santangelo };
10bee78b88Santangelo 
11bee78b88Santangelo S<int>::N x{"a", 1};
12bee78b88Santangelo using T = decltype(x);
13bee78b88Santangelo using T = S<int>::N<int>;
14bee78b88Santangelo 
15bee78b88Santangelo template<class X> struct default_ftd_argument {
16bee78b88Santangelo     template<class Y> struct B {
17bee78b88Santangelo         template<class W = X, class Z = Y, class V = Z, int I = 0> B(Y);
18bee78b88Santangelo     };
19bee78b88Santangelo };
20bee78b88Santangelo 
21bee78b88Santangelo default_ftd_argument<int>::B default_arg("a");
22bee78b88Santangelo using DefaultArg = decltype(default_arg);
23bee78b88Santangelo using DefaultArg = default_ftd_argument<int>::B<const char *>;
24bee78b88Santangelo 
25bee78b88Santangelo template<bool> struct test;
26bee78b88Santangelo template<class X> struct non_type_param {
27bee78b88Santangelo     template<class Y> struct B {
28bee78b88Santangelo         B(Y);
29bee78b88Santangelo         template<class Z, test<Z::value> = 0> B(Z);
30bee78b88Santangelo     };
31bee78b88Santangelo };
32bee78b88Santangelo 
33bee78b88Santangelo non_type_param<int>::B ntp = 5;
34bee78b88Santangelo using NonTypeParam = decltype(ntp);
35bee78b88Santangelo using NonTypeParam = non_type_param<int>::B<int>;
36bee78b88Santangelo 
37bee78b88Santangelo template<typename A, typename T>
38b3ea9b39Santangelo concept True = true;
39b3ea9b39Santangelo 
40b3ea9b39Santangelo template<typename T>
41b3ea9b39Santangelo concept False = false;
42bee78b88Santangelo 
43bee78b88Santangelo template<class X> struct concepts {
44bee78b88Santangelo     template<class Y> struct B {
45b3ea9b39Santangelo         template<class K = X, True<K> Z> B(Y, Z);
46bee78b88Santangelo     };
47bee78b88Santangelo };
48bee78b88Santangelo 
49bee78b88Santangelo concepts<int>::B cc(1, 3);
50bee78b88Santangelo using Concepts = decltype(cc);
51bee78b88Santangelo using Concepts = concepts<int>::B<int>;
52bee78b88Santangelo 
53bee78b88Santangelo template<class X> struct requires_clause {
54bee78b88Santangelo     template<class Y> struct B {
55b3ea9b39Santangelo         template<class Z> requires true
56bee78b88Santangelo             B(Y, Z);
57bee78b88Santangelo     };
58bee78b88Santangelo };
59bee78b88Santangelo 
60bee78b88Santangelo requires_clause<int>::B req(1, 2);
61bee78b88Santangelo using RC = decltype(req);
62bee78b88Santangelo using RC = requires_clause<int>::B<int>;
63b3ea9b39Santangelo 
64b3ea9b39Santangelo template<typename X> struct nested_init_list {
65b3ea9b39Santangelo     template<True<X> Y>
66b3ea9b39Santangelo     struct B {
67b3ea9b39Santangelo         X x;
68b3ea9b39Santangelo         Y y;
69b3ea9b39Santangelo     };
70b3ea9b39Santangelo 
71b3ea9b39Santangelo     template<False F>
72b3ea9b39Santangelo     struct concept_fail { // #INIT_LIST_INNER_INVALID
73b3ea9b39Santangelo         X x;
74b3ea9b39Santangelo         F f;
75b3ea9b39Santangelo     };
76b3ea9b39Santangelo };
77b3ea9b39Santangelo 
78b3ea9b39Santangelo nested_init_list<int>::B nil {1, 2};
79b3ea9b39Santangelo using NIL = decltype(nil);
80b3ea9b39Santangelo using NIL = nested_init_list<int>::B<int>;
81b3ea9b39Santangelo 
829c4a716cSMatheus Izvekov // expected-error@+1 {{no viable constructor or deduction guide for deduction of template arguments of 'nested_init_list<int>::concept_fail'}}
83b3ea9b39Santangelo nested_init_list<int>::concept_fail nil_invalid{1, ""};
84b3ea9b39Santangelo // expected-note@#INIT_LIST_INNER_INVALID {{candidate template ignored: substitution failure [with F = const char *]: constraints not satisfied for class template 'concept_fail' [with F = const char *]}}
85*3b639d7dSYounan Zhang // expected-note@#INIT_LIST_INNER_INVALID {{implicit deduction guide declared as 'template <False F> concept_fail(int, F) -> concept_fail<F>'}}
86b3ea9b39Santangelo // expected-note@#INIT_LIST_INNER_INVALID {{candidate function template not viable: requires 1 argument, but 2 were provided}}
87*3b639d7dSYounan Zhang // expected-note@#INIT_LIST_INNER_INVALID {{implicit deduction guide declared as 'template <False F> concept_fail(concept_fail<F>) -> concept_fail<F>'}}
88b3ea9b39Santangelo // expected-note@#INIT_LIST_INNER_INVALID {{candidate function template not viable: requires 0 arguments, but 2 were provided}}
89*3b639d7dSYounan Zhang // expected-note@#INIT_LIST_INNER_INVALID {{implicit deduction guide declared as 'template <False F> concept_fail() -> concept_fail<F>'}}
908c852ab5SYounan Zhang 
918c852ab5SYounan Zhang namespace GH88142 {
928c852ab5SYounan Zhang 
938c852ab5SYounan Zhang template <typename, typename...> struct X {
948c852ab5SYounan Zhang   template <typename> struct Y {
YGH88142::X::Y958c852ab5SYounan Zhang     template <typename T> Y(T) {}
968c852ab5SYounan Zhang   };
978c852ab5SYounan Zhang 
988c852ab5SYounan Zhang   template <typename T> Y(T) -> Y<T>;
998c852ab5SYounan Zhang };
1008c852ab5SYounan Zhang 
1018c852ab5SYounan Zhang X<int>::Y y(42);
1028c852ab5SYounan Zhang 
1038c852ab5SYounan Zhang } // namespace PR88142
104