xref: /llvm-project/clang/test/SemaTemplate/temp_arg_template_p0522.cpp (revision e29c085812e259910a3d8b6c2d2f471d1c3eede4)
1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
2 
3 // expected-note@temp_arg_template_p0522.cpp:* 1+{{template is declared here}}
4 // expected-note@temp_arg_template_p0522.cpp:* 1+{{template parameter is declared here}}
5 // expected-note@temp_arg_template_p0522.cpp:* 1+{{previous template template parameter is here}}
6 
7 template<template<int> typename> struct Ti; // #Ti
8 template<template<int...> typename> struct TPi; // #TPi
9 template<template<int, int...> typename> struct TiPi;
10 template<template<int..., int...> typename> struct TPiPi; // FIXME: Why is this not ill-formed?
11 
12 template<typename T, template<T> typename> struct tT0; // #tT0
13 template<template<typename T, T> typename> struct Tt0; // #Tt0
14 
15 template<template<typename> typename> struct Tt;
16 template<template<typename, typename...> typename> struct TtPt;
17 
18 template<int> struct i;
19 template<int, int = 0> struct iDi;
20 template<int, int> struct ii;
21 template<int...> struct Pi;
22 template<int, int, int...> struct iiPi;
23 
24 template<int, typename = int> struct iDt; // #iDt
25 template<int, typename> struct it; // #it
26 
27 template<typename T, T v> struct t0;
28 
29 template<typename...> struct Pt;
30 
31 namespace IntParam {
32   using ok = Pt<Ti<i>,
33         Ti<iDi>,
34         Ti<Pi>,
35         Ti<iDt>>;
36   using err1 = Ti<ii>; // expected-error {{too few template arguments for class template 'ii'}}
37                        // expected-note@-1 {{different template parameters}}
38   using err2 = Ti<iiPi>; // expected-error {{too few template arguments for class template 'iiPi'}}
39                          // expected-note@-1 {{different template parameters}}
40   using err3 = Ti<t0>; // expected-error@#Ti {{template argument for template type parameter must be a type}}
41                        // expected-note@-1 {{different template parameters}}
42   using err4 = Ti<it>; // expected-error {{too few template arguments for class template 'it'}}
43                        // expected-note@-1 {{different template parameters}}
44 }
45 
46 // These are accepted by the backwards-compatibility "parameter pack in
47 // parameter matches any number of parameters in arguments" rule.
48 namespace IntPackParam {
49   using ok = TPi<Pi>;
50   using ok_compat = Pt<TPi<i>, TPi<iDi>, TPi<ii>, TPi<iiPi>>;
51   using err1 = TPi<t0>; // expected-error@#TPi {{template argument for template type parameter must be a type}}
52                         // expected-note@-1 {{different template parameters}}
53   using err2 = TPi<iDt>; // expected-error@#TPi {{template argument for template type parameter must be a type}}
54                          // expected-note@-1 {{different template parameters}}
55   using err3 = TPi<it>; // expected-error@#TPi {{template argument for template type parameter must be a type}}
56                         // expected-note@-1 {{different template parameters}}
57 }
58 
59 namespace IntAndPackParam {
60   using ok = TiPi<Pi>;
61   using ok_compat = Pt<TiPi<ii>, TiPi<iDi>, TiPi<iiPi>>;
62   using err = TiPi<iDi>;
63 }
64 
65 namespace DependentType {
66   using ok = Pt<tT0<int, i>, tT0<int, iDi>>;
67   using err1 = tT0<int, ii>; // expected-error {{too few template arguments for class template 'ii'}}
68                              // expected-note@-1 {{different template parameters}}
69   using err2 = tT0<short, i>;
70   using err2a = tT0<long long, i>; // expected-error@#tT0 {{cannot be narrowed from type 'long long' to 'int'}}
71                                    // expected-note@-1 {{different template parameters}}
72   using err2b = tT0<void*, i>; // expected-error@#tT0 {{value of type 'void *' is not implicitly convertible to 'int'}}
73                                // expected-note@-1 {{different template parameters}}
74   using err3 = tT0<short, t0>; // expected-error@#tT0 {{template argument for template type parameter must be a type}}
75                                // expected-note@-1 {{different template parameters}}
76 
77   using ok2 = Tt0<t0>;
78   using err4 = Tt0<it>; // expected-error@#Tt0 {{template argument for non-type template parameter must be an expression}}
79                         // expected-note@-1 {{different template parameters}}
80 }
81 
82 namespace Auto {
83   template<template<int> typename T> struct TInt {}; // #TInt
84   template<template<int*> typename T> struct TIntPtr {}; // #TIntPtr
85   template<template<auto> typename T> struct TAuto {};
86   template<template<auto*> typename T> struct TAutoPtr {};
87   template<template<decltype(auto)> typename T> struct TDecltypeAuto {};
88   template<auto> struct Auto;
89   template<auto*> struct AutoPtr; // #AutoPtr
90   template<decltype(auto)> struct DecltypeAuto;
91   template<int> struct Int;
92   template<int*> struct IntPtr;
93 
94   TInt<Auto> ia;
95   TInt<AutoPtr> iap; // expected-error@#TInt {{non-type template parameter '' with type 'auto *' has incompatible initializer of type 'int'}}
96                      // expected-note@-1 {{different template parameters}}
97   TInt<DecltypeAuto> ida;
98   TInt<Int> ii;
99   TInt<IntPtr> iip; // expected-error@#TInt {{conversion from 'int' to 'int *' is not allowed in a converted constant expression}}
100                     // expected-note@-1 {{different template parameters}}
101 
102   TIntPtr<Auto> ipa;
103   TIntPtr<AutoPtr> ipap;
104   TIntPtr<DecltypeAuto> ipda;
105   TIntPtr<Int> ipi; // expected-error@#TIntPtr {{value of type 'int *' is not implicitly convertible to 'int'}}
106                     // expected-note@-1 {{different template parameters}}
107   TIntPtr<IntPtr> ipip;
108 
109   TAuto<Auto> aa;
110   TAuto<AutoPtr> aap; // expected-error@#AutoPtr {{could not match 'auto *' against 'auto'}}
111                       // expected-note@-1 {{different template parameters}}
112   TAuto<Int> ai; // FIXME: ill-formed (?)
113   TAuto<IntPtr> aip; // FIXME: ill-formed (?)
114 
115   TAutoPtr<Auto> apa;
116   TAutoPtr<AutoPtr> apap;
117   TAutoPtr<Int> api; // FIXME: ill-formed (?)
118   TAutoPtr<IntPtr> apip; // FIXME: ill-formed (?)
119 
120   TDecltypeAuto<DecltypeAuto> dada;
121   TDecltypeAuto<Int> dai; // FIXME: ill-formed (?)
122   TDecltypeAuto<IntPtr> daip; // FIXME: ill-formed (?)
123 
124   // FIXME: It's completely unclear what should happen here, but these results
125   // seem at least plausible:
126   TAuto<DecltypeAuto> ada;
127   TAutoPtr<DecltypeAuto> apda;
128   // Perhaps this case should be invalid, as there are valid 'decltype(auto)'
129   // parameters (such as 'user-defined-type &') that are not valid 'auto'
130   // parameters.
131   TDecltypeAuto<Auto> daa;
132   TDecltypeAuto<AutoPtr> daap; // expected-error@#AutoPtr {{could not match 'auto *' against 'decltype(auto)'}}
133                                // expected-note@-1 {{different template parameters}}
134 
135   int n;
136   template<auto A, decltype(A) B = &n> struct SubstFailure;
137   TInt<SubstFailure> isf; // FIXME: this should be ill-formed
138   TIntPtr<SubstFailure> ipsf;
139 }
140 
141 namespace GH62529 {
142   // Note: the constraint here is just for bypassing a fast-path.
143   template<class T1> requires(true) using A = int;
144   template<template<class ...T2s> class TT1, class T3> struct B {};
145   template<class T4> B<A, T4> f();
146   auto t = f<int>();
147 } // namespace GH62529
148 
149 namespace GH101394 {
150   struct X {}; // #X
151   struct Y {
152     constexpr Y(const X &) {}
153   };
154 
155   namespace t1 {
156     template<template<X> class> struct A {};
157     template<Y> struct B;
158     template struct A<B>;
159   } // namespace t1
160   namespace t2 {
161     template<template<Y> class> struct A {}; // #A
162     template<X> struct B; // #B
163     template struct A<B>;
164     // expected-error@#A {{no viable conversion from 'const Y' to 'X'}}
165     // expected-note@-2  {{different template parameters}}
166     // expected-note@#X 2{{not viable}}
167     // expected-note@#B  {{passing argument to parameter here}}
168   } // namespace t2
169 } // namespace GH101394
170