[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / SemaTemplate / deduction.cpp
blob7a45d1a4257285461ad9915c2844acb0690422ac
1 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
2 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1z
3 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++2b
5 // Template argument deduction with template template parameters.
6 template<typename T, template<T> class A>
7 struct X0 {
8 static const unsigned value = 0;
9 };
11 template<template<int> class A>
12 struct X0<int, A> {
13 static const unsigned value = 1;
16 template<int> struct X0i;
17 template<long> struct X0l;
18 int array_x0a[X0<long, X0l>::value == 0? 1 : -1];
19 int array_x0b[X0<int, X0i>::value == 1? 1 : -1];
21 template<typename T, typename U>
22 struct is_same {
23 static const bool value = false;
26 template<typename T>
27 struct is_same<T, T> {
28 static const bool value = true;
31 template<typename T> struct allocator { };
32 template<typename T, typename Alloc = allocator<T> > struct vector {};
34 // Fun with meta-lambdas!
35 struct _1 {};
36 struct _2 {};
38 // Replaces all occurrences of _1 with Arg1 and _2 with Arg2 in T.
39 template<typename T, typename Arg1, typename Arg2>
40 struct Replace {
41 typedef T type;
44 // Replacement of the whole type.
45 template<typename Arg1, typename Arg2>
46 struct Replace<_1, Arg1, Arg2> {
47 typedef Arg1 type;
50 template<typename Arg1, typename Arg2>
51 struct Replace<_2, Arg1, Arg2> {
52 typedef Arg2 type;
55 // Replacement through cv-qualifiers
56 template<typename T, typename Arg1, typename Arg2>
57 struct Replace<const T, Arg1, Arg2> {
58 typedef typename Replace<T, Arg1, Arg2>::type const type;
61 // Replacement of templates
62 template<template<typename> class TT, typename T1, typename Arg1, typename Arg2>
63 struct Replace<TT<T1>, Arg1, Arg2> {
64 typedef TT<typename Replace<T1, Arg1, Arg2>::type> type;
67 template<template<typename, typename> class TT, typename T1, typename T2,
68 typename Arg1, typename Arg2>
69 struct Replace<TT<T1, T2>, Arg1, Arg2> {
70 typedef TT<typename Replace<T1, Arg1, Arg2>::type,
71 typename Replace<T2, Arg1, Arg2>::type> type;
74 // Just for kicks...
75 template<template<typename, typename> class TT, typename T1,
76 typename Arg1, typename Arg2>
77 struct Replace<TT<T1, _2>, Arg1, Arg2> {
78 typedef TT<typename Replace<T1, Arg1, Arg2>::type, Arg2> type;
81 int array0[is_same<Replace<_1, int, float>::type, int>::value? 1 : -1];
82 int array1[is_same<Replace<const _1, int, float>::type, const int>::value? 1 : -1];
83 int array2[is_same<Replace<vector<_1>, int, float>::type, vector<int> >::value? 1 : -1];
84 int array3[is_same<Replace<vector<const _1>, int, float>::type, vector<const int> >::value? 1 : -1];
85 int array4[is_same<Replace<vector<int, _2>, double, float>::type, vector<int, float> >::value? 1 : -1];
87 // PR5911
88 template <typename T, int N> void f(const T (&a)[N]);
89 int iarr[] = { 1 };
90 void test_PR5911() { f(iarr); }
92 // Must not examine base classes of incomplete type during template argument
93 // deduction.
94 namespace PR6257 {
95 template <typename T> struct X {
96 template <typename U> X(const X<U>& u);
98 struct A;
99 void f(A& a);
100 void f(const X<A>& a);
101 void test(A& a) { (void)f(a); }
104 // PR7463
105 namespace PR7463 {
106 const int f ();
107 template <typename T_> void g (T_&); // expected-note{{T_ = int}}
108 void h (void) { g(f()); } // expected-error{{no matching function for call}}
111 namespace test0 {
112 template <class T> void make(const T *(*fn)()); // expected-note {{candidate template ignored: cannot deduce a type for 'T' that would make 'const T' equal 'char'}}
113 char *char_maker();
114 void test() {
115 make(char_maker); // expected-error {{no matching function for call to 'make'}}
119 namespace test1 {
120 template<typename T> void foo(const T a[3][3]);
121 void test() {
122 int a[3][3];
123 foo(a);
127 // PR7708
128 namespace test2 {
129 template<typename T> struct Const { typedef void const type; };
131 template<typename T> void f(T, typename Const<T>::type*);
132 template<typename T> void f(T, void const *);
134 void test() {
135 void *p = 0;
136 f(0, p);
140 // rdar://problem/8537391
141 namespace test3 {
142 struct Foo {
143 template <void F(char)> static inline void foo();
146 class Bar {
147 template<typename T> static inline void wobble(T ch);
149 public:
150 static void madness() {
151 Foo::foo<wobble<char> >();
156 namespace test4 {
158 template <class> struct a { using b = const float; };
159 template <class c> using d = typename a<c>::b;
161 template <class c> void e(d<c> *, c) {}
162 template void e(const float *, int);
164 } // namespace test4
166 namespace test5 {
168 template <bool, int = 0> class a {};
169 template <class b> void c(b, b);
170 template <bool b> void c(a<b>, a<b>);
171 void d() { c(a<true>(), a<true>()); }
173 } // namespace test5
175 namespace test6 {
176 template <class A1> using A = A1;
178 template <class F1, class... F2> void f(A<F1>, F1, F2...);
179 template <class F3> void f(A<F3>, F3);
181 void g() { f(A<int>{}, int{}); }
182 } // namespace test6
184 namespace test7 {
185 template <class T> void f(T&, T&);
186 template <class T, unsigned long S> void f(T (&)[S], T (&)[S]);
188 void g() {
189 int i[3], j[3];
190 f(i, j);
192 } // namespace test7
194 namespace test8 {
195 template <class T> void foo(T);
196 void test(int a) {
197 char n[a];
198 foo(n);
200 } // namespace test8
202 // Verify that we can deduce enum-typed arguments correctly.
203 namespace test14 {
204 enum E { E0, E1 };
205 template <E> struct A {};
206 template <E e> void foo(const A<e> &a) {}
208 void test() {
209 A<E0> a;
210 foo(a);
214 namespace PR21536 {
215 template<typename ...T> struct X;
216 template<typename A, typename ...B> struct S {
217 static_assert(sizeof...(B) == 1, "");
218 void f() {
219 using T = A;
220 using T = int;
222 using U = X<B...>;
223 using U = X<int>;
226 template<typename ...T> void f(S<T...>);
227 void g() { f(S<int, int>()); }
230 namespace PR19372 {
231 template <template<typename...> class C, typename ...Us> struct BindBack {
232 template <typename ...Ts> using apply = C<Ts..., Us...>;
234 template <typename, typename...> struct Y;
235 template <typename ...Ts> using Z = Y<Ts...>;
237 using T = BindBack<Z, int>::apply<>;
238 using T = Z<int>;
240 using U = BindBack<Z, int, int>::apply<char>;
241 using U = Z<char, int, int>;
243 namespace BetterReduction {
244 template<typename ...> struct S;
245 template<typename ...A> using X = S<A...>; // expected-note {{parameter}}
246 template<typename ...A> using Y = X<A..., A...>;
247 template<typename ...A> using Z = X<A..., 1, 2, 3>; // expected-error {{must be a type}}
249 using T = Y<int>;
250 using T = S<int, int>;
254 namespace PR18645 {
255 template<typename F> F Quux(F &&f);
256 auto Baz = Quux(Quux<float>);
259 namespace NonDeducedNestedNameSpecifier {
260 template<typename T> struct A {
261 template<typename U> struct B {
262 B(int) {}
266 template<typename T> int f(A<T>, typename A<T>::template B<T>);
267 int k = f(A<int>(), 0);
270 namespace PR27601_RecursivelyInheritedBaseSpecializationsDeductionAmbiguity {
271 namespace ns1 {
273 template<class...> struct B { };
274 template<class H, class ... Ts> struct B<H, Ts...> : B<> { };
275 template<class ... Ts> struct D : B<Ts...> { };
277 template<class T, class ... Ts> void f(B<T, Ts...> &) { }
279 int main() {
280 D<int, char> d;
281 f<int>(d);
283 } //end ns1
285 namespace ns2 {
287 template <int i, typename... Es> struct tup_impl;
289 template <int i> struct tup_impl<i> {}; // empty tail
291 template <int i, typename Head, typename... Tail>
292 struct tup_impl<i, Head, Tail...> : tup_impl<i + 1, Tail...> {
293 using value_type = Head;
294 Head head;
297 template <typename... Es> struct tup : tup_impl<0, Es...> {};
299 template <typename Head, int i, typename... Tail>
300 Head &get_helper(tup_impl<i, Head, Tail...> &t) {
301 return t.head;
304 template <typename Head, int i, typename... Tail>
305 Head const &get_helper(tup_impl<i, Head, Tail...> const &t) {
306 return t.head;
309 int main() {
310 tup<int, double, char> t;
311 get_helper<double>(t);
312 return 0;
314 } // end ns2
317 namespace multiple_deduction_different_type {
318 template<typename T, T v> struct X {};
319 template<template<typename T, T> class X, typename T, typename U, int N>
320 void f(X<T, N>, X<U, N>) {} // expected-note 2{{values of conflicting types}}
321 template<template<typename T, T> class X, typename T, typename U, const int *N>
322 void g(X<T, N>, X<U, N>) {} // expected-note 0-2{{values of conflicting types}}
323 int n;
324 void h() {
325 f(X<int, 1+1>(), X<unsigned int, 3-1>()); // expected-error {{no matching function}}
326 f(X<unsigned int, 1+1>(), X<int, 3-1>()); // expected-error {{no matching function}}
327 #if __cplusplus > 201402L
328 g(X<const int*, &n>(), X<int*, &n + 1 - 1>()); // expected-error {{no matching function}}
329 g(X<int*, &n>(), X<const int*, &n + 1 - 1>()); // expected-error {{no matching function}}
330 #endif
333 template<template<typename T, T> class X, typename T, typename U, T N>
334 void x(X<T, N>, int(*)[N], X<U, N>) {} // expected-note 1+{{candidate}}
335 template<template<typename T, T> class X, typename T, typename U, T N>
336 void x(int(*)[N], X<T, N>, X<U, N>) {} // expected-note 1+{{candidate}}
337 int arr[3];
338 void y() {
339 x(X<int, 3>(), &arr, X<int, 3>());
340 x(&arr, X<int, 3>(), X<int, 3>());
342 x(X<int, 3>(), &arr, X<char, 3>()); // expected-error {{no matching function}}
343 x(&arr, X<int, 3>(), X<char, 3>()); // expected-error {{no matching function}}
345 x(X<char, 3>(), &arr, X<char, 3>());
346 x(&arr, X<char, 3>(), X<char, 3>());
350 namespace nullptr_deduction {
351 using nullptr_t = decltype(nullptr);
353 template<typename T, T v> struct X {};
354 template<typename T, T v> void f(X<T, v>) {
355 static_assert(!v, ""); // expected-warning 2{{implicit conversion of nullptr constant to 'bool'}}
357 void g() {
358 f(X<int*, nullptr>()); // expected-note {{instantiation of}}
359 f(X<nullptr_t, nullptr>()); // expected-note {{instantiation of}}
362 template<template<typename T, T> class X, typename T, int *P>
363 void f0(X<T, P>) {} // expected-note {{deduced non-type template argument does not have the same type as the corresponding template parameter ('std::nullptr_t' vs 'int *')}}
364 void h0() {
365 f0(X<int*, nullptr>());
366 f0(X<nullptr_t, nullptr>()); // expected-error {{no matching function}}
369 template<template<typename T, T> class X, typename T, typename U, int *P>
370 void f1(X<T, P>, X<U, P>) {} // expected-note 2{{values of conflicting types}}
371 void h() {
372 f1(X<int*, nullptr>(), X<nullptr_t, nullptr>()); // expected-error {{no matching function}}
373 f1(X<nullptr_t, nullptr>(), X<int*, nullptr>()); // expected-error {{no matching function}}
376 template<template<typename T, T> class X, typename T, typename U, nullptr_t P>
377 void f2(X<T, P>, X<U, P>) {} // expected-note 2{{values of conflicting types}}
378 void i() {
379 f2(X<int*, nullptr>(), X<nullptr_t, nullptr>()); // expected-error {{no matching function}}
380 f2(X<nullptr_t, nullptr>(), X<int*, nullptr>()); // expected-error {{no matching function}}
384 namespace member_pointer {
385 struct A { void f(int); };
386 template<typename T, void (A::*F)(T)> struct B;
387 template<typename T> struct C;
388 template<typename T, void (A::*F)(T)> struct C<B<T, F>> {
389 C() { A a; T t; (a.*F)(t); }
391 C<B<int, &A::f>> c;
394 namespace deduction_substitution_failure {
395 template<typename T> struct Fail { typedef typename T::error error; }; // expected-error 2{{prior to '::'}}
397 template<typename T, typename U> struct A {};
398 template<typename T> struct A<T, typename Fail<T>::error> {}; // expected-note {{instantiation of}}
399 A<int, int> ai; // expected-note {{during template argument deduction for class template partial specialization 'A<T, typename Fail<T>::error>' [with T = int]}} expected-note {{in instantiation of template class 'deduction_substitution_failure::A<int, int>'}}
401 template<typename T, typename U> int B; // expected-warning 0-1 {{extension}}
402 template<typename T> int B<T, typename Fail<T>::error> {}; // expected-note {{instantiation of}}
403 int bi = B<char, char>; // expected-note {{during template argument deduction for variable template partial specialization 'B<T, typename Fail<T>::error>' [with T = char]}}
406 namespace deduction_after_explicit_pack {
407 template<typename ...T, typename U> int *f(T ...t, int &r, U *u) {
408 return u;
410 template<typename U, typename ...T> int *g(T ...t, int &r, U *u) {
411 return u;
413 void h(float a, double b, int c) {
414 f<float&, double&>(a, b, c, &c); // ok
415 g<int, float&, double&>(a, b, c, &c); // ok
418 template<class... ExtraArgs>
419 int test(ExtraArgs..., unsigned vla_size, const char *input);
420 int n = test(0, "");
422 template <typename... T> void i(T..., int, T..., ...); // expected-note 5{{deduced packs of different lengths}}
423 void j() {
424 i(0);
425 i(0, 1); // expected-error {{no match}}
426 i(0, 1, 2); // expected-error {{no match}}
427 i<>(0);
428 i<>(0, 1); // expected-error {{no match}}
429 i<>(0, 1, 2); // expected-error {{no match}}
430 i<int, int>(0, 1, 2, 3, 4);
431 i<int, int>(0, 1, 2, 3, 4, 5); // expected-error {{no match}}
434 // GCC alarmingly accepts this by deducing T={int} by matching the second
435 // parameter against the first argument, then passing the first argument
436 // through the first parameter.
437 template<typename... T> struct X { X(int); operator int(); };
438 template<typename... T> void p(T..., X<T...>, ...); // expected-note {{deduced packs of different lengths for parameter 'T' (<> vs. <int>)}}
439 void q() { p(X<int>(0), 0); } // expected-error {{no match}}
441 struct A {
442 template <typename T> void f(T, void *, int = 0); // expected-note 2{{no known conversion from 'double' to 'void *' for 2nd argument}}
443 void f(); // expected-note 2{{requires 0}}
445 template <typename T> static void g(T, void *, int = 0); // expected-note 2{{no known conversion from 'double' to 'void *' for 2nd argument}}
446 void g(); // expected-note 2{{requires 0}}
448 void h() {
449 f(1.0, 2.0); // expected-error {{no match}}
450 g(1.0, 2.0); // expected-error {{no match}}
453 void f(A a) {
454 a.f(1.0, 2.0); // expected-error {{no match}}
455 a.g(1.0, 2.0); // expected-error {{no match}}
459 namespace overload_vs_pack {
460 void f(int);
461 void f(float);
462 void g(double);
464 template<typename ...T> struct X {};
465 template<typename ...T> void x(T...);
467 template<typename ...T> struct Y { typedef int type(typename T::error...); };
468 template<> struct Y<int, float, double> { typedef int type; };
470 template<typename ...T> typename Y<T...>::type g1(X<T...>, void (*...fns)(T)); // expected-note {{deduced conflicting types for parameter 'T' (<int, float> vs. <(no value), double>)}}
471 template<typename ...T> typename Y<T...>::type g2(void(*)(T...), void (*...fns)(T)); // expected-note {{deduced conflicting types for parameter 'T' (<int, float> vs. <(no value), double>)}}
473 template<typename T> int &h1(decltype(g1(X<int, float, T>(), f, f, g)) *p);
474 template<typename T> float &h1(...);
476 template<typename T> int &h2(decltype(g2(x<int, float, T>, f, f, g)) *p);
477 template<typename T> float &h2(...);
479 int n1 = g1(X<int, float>(), f, g); // expected-error {{no matching function}}
480 int n2 = g2(x<int, float>, f, g); // expected-error {{no matching function}}
482 int &a1 = h1<double>(0); // ok, skip deduction for 'f's, deduce matching value from 'g'
483 int &a2 = h2<double>(0);
485 float &b1 = h1<float>(0); // deduce mismatching value from 'g', so we do not trigger instantiation of Y
486 float &b2 = h2<float>(0);
488 template<typename ...T> int partial_deduction(void (*...f)(T)); // expected-note {{deduced incomplete pack <(no value), double> for template parameter 'T'}}
489 int pd1 = partial_deduction(f, g); // expected-error {{no matching function}}
491 template<typename ...T> int partial_deduction_2(void (*...f)(T), ...); // expected-note {{deduced incomplete pack <(no value), double> for template parameter 'T'}}
492 int pd2 = partial_deduction_2(f, g); // expected-error {{no matching function}}
494 namespace cwg_example {
495 void f(char, char);
496 void f(int, int);
497 void x(int, char);
499 template<typename T, typename ...U> void j(void(*)(U...), void (*...fns)(T, U));
500 void test() { j(x, f, x); }
504 namespace b29946541 {
505 template<typename> class A {};
506 template<typename T, typename U, template<typename, typename> class C>
507 void f(C<T, U>); // expected-note {{failed template argument deduction}}
508 void g(A<int> a) { f(a); } // expected-error {{no match}}
511 namespace deduction_from_empty_list {
512 template<int M, int N = 5> void f(int (&&)[N], int (&&)[N]) { // expected-note {{1 vs. 2}}
513 static_assert(M == N, "");
516 void test() {
517 f<5>({}, {});
518 f<1>({}, {0});
519 f<1>({0}, {});
520 f<1>({0}, {0});
521 f<1>({0}, {0, 1}); // expected-error {{no matching}}
525 namespace check_extended_pack {
526 template<typename T> struct X { typedef int type; };
527 template<typename ...T> void f(typename X<T>::type...);
528 template<typename T> void f(T, int, int);
529 void g() {
530 f<int>(0, 0, 0);
533 template<int, int*> struct Y {};
534 template<int ...N> void g(Y<N...>); // expected-note {{deduced non-type template argument does not have the same type as the corresponding template parameter ('int *' vs 'int')}}
535 int n;
536 void h() { g<0>(Y<0, &n>()); } // expected-error {{no matching function}}
539 namespace dependent_template_template_param_non_type_param_type {
540 template<int N> struct A {
541 template<typename V = int, V M = 12, V (*Y)[M], template<V (*v)[M]> class W>
542 A(W<Y>);
545 int n[12];
546 template<int (*)[12]> struct Q {};
547 Q<&n> qn;
548 A<0> a(qn);
551 namespace dependent_list_deduction {
552 template<typename T, T V> void a(const int (&)[V]) {
553 static_assert(is_same<T, decltype(sizeof(0))>::value, "");
554 static_assert(V == 3, "");
556 template<typename T, T V> void b(const T (&)[V]) {
557 static_assert(is_same<T, int>::value, "");
558 static_assert(V == 3, "");
560 template<typename T, T V> void c(const T (&)[V]) {
561 static_assert(is_same<T, decltype(sizeof(0))>::value, "");
562 static_assert(V == 3, "");
564 void d() {
565 a({1, 2, 3});
566 #if __cplusplus <= 201402L
567 // expected-error@-2 {{no match}} expected-note@-15 {{couldn't infer template argument 'T'}}
568 #endif
569 b({1, 2, 3});
570 c({{}, {}, {}});
571 #if __cplusplus <= 201402L
572 // expected-error@-2 {{no match}} expected-note@-12 {{couldn't infer template argument 'T'}}
573 #endif
576 template<typename ...T> struct X;
577 template<int ...T> struct Y;
578 template<typename ...T, T ...V> void f(const T (&...p)[V]) {
579 static_assert(is_same<X<T...>, X<int, char, char>>::value, "");
580 static_assert(is_same<Y<V...>, Y<3, 2, 4>>::value, "");
582 template<typename ...T, T ...V> void g(const T (&...p)[V]) {
583 static_assert(is_same<X<T...>, X<int, decltype(sizeof(0))>>::value, "");
584 static_assert(is_same<Y<V...>, Y<2, 3>>::value, "");
586 void h() {
587 f({1, 2, 3}, {'a', 'b'}, "foo");
588 g({1, 2}, {{}, {}, {}});
589 #if __cplusplus <= 201402
590 // expected-error@-2 {{no match}}
591 // expected-note@-9 {{deduced incomplete pack}}
592 // We deduce V$1 = (size_t)3, which in C++1z also deduces T$1 = size_t.
593 #endif
597 namespace designators {
598 template<typename T, int N> constexpr int f(T (&&)[N]) { return N; } // expected-note 2{{couldn't infer template argument 'T'}}
599 static_assert(f({1, 2, [20] = 3}) == 3, ""); // expected-error {{no matching function}} expected-warning 2{{C99}} expected-note {{}}
601 static_assert(f({.a = 1, .b = 2}) == 3, ""); // expected-error {{no matching function}}
604 namespace nested_packs {
605 template<typename ...T, typename ...U> void f(T (*...f)(U...)); // expected-note {{deduced packs of different lengths for parameter 'U' (<> vs. <int>)}}
606 void g() { f(g); f(g, g); f(g, g, g); }
607 void h(int) { f(h); f(h, h); f(h, h, h); }
608 void i() { f(g, h); } // expected-error {{no matching function}}
610 #if __cplusplus >= 201703L
611 template<auto ...A> struct Q {};
612 template<typename ...T, T ...A, T ...B> void q(Q<A...>, Q<B...>); // #q
613 void qt(Q<> q0, Q<1, 2> qii, Q<1, 2, 3> qiii) {
614 q(q0, q0);
615 q(qii, qii);
616 q(qii, qiii); // expected-error {{no match}} expected-note@#q {{deduced packs of different lengths for parameter 'T' (<int, int> vs. <int, int, int>)}}
617 q(q0, qiii); // expected-error {{no match}} expected-note@#q {{deduced packs of different lengths for parameter 'T' (<> vs. <int, int, int>)}}
619 #endif
622 namespace PR44890 {
623 template<typename ...Ts>
624 struct tuple {};
626 template<int I, typename ...Ts>
627 int get0(const tuple<Ts...> &t) { return 0; }
629 template<typename ...Ts> struct tuple_wrapper : tuple<Ts...> {
630 template<int I> int get() { return get0<0, Ts...>(*this); }
633 int f() {
634 tuple_wrapper<int> w;
635 return w.get<0>();
639 namespace merge_size_only_deductions {
640 #if __cplusplus >= 201703L
641 // Based on a testcase by Hubert Tong.
642 template<typename ...> struct X {};
643 template<auto ...> struct Y {};
644 template<typename T> struct id { using Type = T; };
646 template<typename ...T, typename T::Type ...V>
647 int f(X<char [V] ...>, Y<V ...>, X<T ...>);
649 using size_t = __SIZE_TYPE__;
650 int a = f(X<char [1], char [2]>(), Y<(size_t)1, (size_t)2>(), X<id<size_t>, id<size_t>>());
651 int b = f(X<char [1], char [2]>(), Y<1, 2>(), X<id<int>, id<int>>());
652 #endif
655 namespace PR49724 {
656 struct A;
657 template<int A::*> class X {};
658 template<int A::*P> void f(X<P>);
659 void g(X<nullptr> x) { f(x); }
661 template<void (A::*)()> class Y {};
662 template<void (A::*P)()> void f(Y<P>);
663 void g(Y<nullptr> y) { f(y); }
666 namespace sugared_deduction {
667 using Int = int;
669 template <class T, int C> void f1(T(&)[C], T(&)[C+1]);
670 // expected-note@-1 {{candidate template ignored: deduced type 'int[3]' of 2nd parameter does not match adjusted type 'Int[2]' (aka 'int[2]') of argument [with T = Int, C = 2]}}
672 void t1() {
673 Int a[2], b[2];
674 f1(a, b); // expected-error {{no matching function for call to 'f1'}}
677 #if defined(__cpp_concepts)
678 template <class T> void f2() requires false {}
679 // expected-note@-1 {{candidate template ignored: constraints not satisfied [with T = Int]}}
680 // expected-note@-2 {{because 'false' evaluated to false}}
682 void t2() {
683 f2<Int>(); // expected-error {{no matching function for call to 'f2'}}
685 #endif
686 } // namespace sugared_deduction