xref: /llvm-project/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp (revision b86e0992bfa6c58be077d82d824016f590ac5d90)
1 // RUN:  %clang_cc1 -std=c++2a -verify %s
2 
3 template<typename T> concept C = T::f(); // #C
4 template<typename T> concept D = C<T> && T::g();
5 template<typename T> concept F = T::f(); // #F
6 template<template<C> class P> struct S1 { }; // #S1
7 
8 template<C> struct X { };
9 
10 template<D> struct Y { }; // #Y
11 template<typename T> struct Z { };
12 template<F> struct W { }; // #W
13 S1<X> s11;
14 S1<Y> s12;
15 // expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
16 // expected-note@#S1 {{'P' declared here}}
17 // expected-note@#Y {{'Y' declared here}}
18 S1<Z> s13;
19 S1<W> s14;
20 // expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
21 // expected-note@#S1 {{'P' declared here}}
22 // expected-note@#W {{'W' declared here}}
23 // expected-note@#F 1-2{{similar constraint expressions not considered equivalent}}
24 // expected-note@#C 1-2{{similar constraint}}
25 
26 template<template<typename> class P> struct S2 { };
27 
28 S2<X> s21;
29 S2<Y> s22;
30 S2<Z> s23;
31 
32 template <template <typename...> class C>
33 struct S3;
34 
35 template <C T>
36 using N = typename T::type;
37 
38 using s31 = S3<N>;
39 using s32 = S3<Z>;
40 
41 template<template<typename T> requires C<T> class P> struct S4 { }; // #S4
42 
43 S4<X> s41;
44 S4<Y> s42;
45 // expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
46 // expected-note@#S4 {{'P' declared here}}
47 // expected-note@#Y {{'Y' declared here}}
48 S4<Z> s43;
49 S4<W> s44;
50 // expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
51 // expected-note@#S4 {{'P' declared here}}
52 // expected-note@#W {{'W' declared here}}
53 
54 template<template<typename T> requires C<T> typename U> struct S5 {
55   template<typename T> static U<T> V;
56 };
57 
58 struct Nothing {};
59 
60 // FIXME: Wait the standard to clarify the intent.
61 template<> template<> Z<Nothing> S5<Z>::V<Nothing>;
62 
63 namespace GH57410 {
64 
65 template<typename T>
66 concept True = true;
67 
68 template<typename T>
69 concept False = false; // #False
70 
71 template <class> struct S {};
72 
73 template<template<True T> typename Wrapper>
74 using Test = Wrapper<int>;
75 
76 template<template<False T> typename Wrapper> // #TTP-Wrapper
77 using Test = Wrapper<int>; // expected-error {{constraints not satisfied for template template parameter 'Wrapper' [with T = int]}}
78 
79 // expected-note@#TTP-Wrapper {{'int' does not satisfy 'False'}}
80 // expected-note@#False {{evaluated to false}}
81 
82 template <typename U, template<False> typename T>
83 void foo(T<U>); // #foo
84 
bar()85 void bar() {
86   foo<int>(S<int>{}); // expected-error {{no matching function for call to 'foo'}}
87   // expected-note@#foo {{substitution failure [with U = int]: constraints not satisfied for template template parameter 'T' [with $0 = int]}}
88 }
89 
90 }
91