xref: /llvm-project/clang/test/SemaTemplate/concepts-out-of-line-def.cpp (revision 27c917307563eae93c7fef9c3944e56e1f5b5f6d)
1421c098bSAlexander Shaposhnikov // RUN: %clang_cc1 -std=c++20 -verify %s
2421c098bSAlexander Shaposhnikov 
3421c098bSAlexander Shaposhnikov static constexpr int PRIMARY = 0;
4421c098bSAlexander Shaposhnikov static constexpr int SPECIALIZATION_CONCEPT = 1;
5421c098bSAlexander Shaposhnikov static constexpr int SPECIALIZATION_REQUIRES = 2;
6421c098bSAlexander Shaposhnikov 
7421c098bSAlexander Shaposhnikov template <class T>
8421c098bSAlexander Shaposhnikov concept Concept = (sizeof(T) >= 2 * sizeof(int));
9421c098bSAlexander Shaposhnikov 
10421c098bSAlexander Shaposhnikov struct XY {
11421c098bSAlexander Shaposhnikov   int x;
12421c098bSAlexander Shaposhnikov   int y;
13421c098bSAlexander Shaposhnikov };
14421c098bSAlexander Shaposhnikov 
15421c098bSAlexander Shaposhnikov namespace members {
16421c098bSAlexander Shaposhnikov 
17421c098bSAlexander Shaposhnikov template <class T, class U> struct S {
18421c098bSAlexander Shaposhnikov   static constexpr int primary();
19421c098bSAlexander Shaposhnikov };
20421c098bSAlexander Shaposhnikov 
21421c098bSAlexander Shaposhnikov template <class T, class U> constexpr int S<T, U>::primary() {
22421c098bSAlexander Shaposhnikov   return PRIMARY;
23421c098bSAlexander Shaposhnikov };
24421c098bSAlexander Shaposhnikov 
25421c098bSAlexander Shaposhnikov template <Concept C, class U> struct S<C, U> {
26421c098bSAlexander Shaposhnikov   static constexpr int specialization();
27421c098bSAlexander Shaposhnikov };
28421c098bSAlexander Shaposhnikov 
29421c098bSAlexander Shaposhnikov template <class T, class U>
30421c098bSAlexander Shaposhnikov   requires(sizeof(T) == sizeof(int))
31421c098bSAlexander Shaposhnikov struct S<T, U> {
32421c098bSAlexander Shaposhnikov   static constexpr int specialization();
33421c098bSAlexander Shaposhnikov };
34421c098bSAlexander Shaposhnikov 
35421c098bSAlexander Shaposhnikov template <Concept C, class U> constexpr int S<C, U>::specialization() {
36421c098bSAlexander Shaposhnikov   return SPECIALIZATION_CONCEPT;
37421c098bSAlexander Shaposhnikov }
38421c098bSAlexander Shaposhnikov 
39421c098bSAlexander Shaposhnikov template <class T, class U>
40421c098bSAlexander Shaposhnikov   requires(sizeof(T) == sizeof(int))
41421c098bSAlexander Shaposhnikov constexpr int S<T, U>::specialization() {
42421c098bSAlexander Shaposhnikov   return SPECIALIZATION_REQUIRES;
43421c098bSAlexander Shaposhnikov }
44421c098bSAlexander Shaposhnikov 
45421c098bSAlexander Shaposhnikov static_assert(S<char, double>::primary() == PRIMARY);
46421c098bSAlexander Shaposhnikov static_assert(S<XY, double>::specialization() == SPECIALIZATION_CONCEPT);
47421c098bSAlexander Shaposhnikov static_assert(S<int, double>::specialization() == SPECIALIZATION_REQUIRES);
48421c098bSAlexander Shaposhnikov 
49421c098bSAlexander Shaposhnikov } // namespace members
50421c098bSAlexander Shaposhnikov 
51421c098bSAlexander Shaposhnikov namespace enumerations {
52421c098bSAlexander Shaposhnikov 
53421c098bSAlexander Shaposhnikov template <class T, class U> struct S {
54421c098bSAlexander Shaposhnikov   enum class E : int;
55421c098bSAlexander Shaposhnikov };
56421c098bSAlexander Shaposhnikov 
57421c098bSAlexander Shaposhnikov template <class T, class U> enum class S<T, U>::E { Value = PRIMARY };
58421c098bSAlexander Shaposhnikov 
59421c098bSAlexander Shaposhnikov template <Concept C, class U> struct S<C, U> {
60421c098bSAlexander Shaposhnikov   enum class E : int;
61421c098bSAlexander Shaposhnikov };
62421c098bSAlexander Shaposhnikov 
63421c098bSAlexander Shaposhnikov template <Concept C, class U>
64421c098bSAlexander Shaposhnikov enum class S<C, U>::E {
65421c098bSAlexander Shaposhnikov   Value = SPECIALIZATION_CONCEPT
66421c098bSAlexander Shaposhnikov };
67421c098bSAlexander Shaposhnikov 
68421c098bSAlexander Shaposhnikov template <class T, class U>
69421c098bSAlexander Shaposhnikov   requires(sizeof(T) == sizeof(int))
70421c098bSAlexander Shaposhnikov struct S<T, U> {
71421c098bSAlexander Shaposhnikov   enum class E : int;
72421c098bSAlexander Shaposhnikov };
73421c098bSAlexander Shaposhnikov 
74421c098bSAlexander Shaposhnikov template <class T, class U>
75421c098bSAlexander Shaposhnikov   requires(sizeof(T) == sizeof(int))
76421c098bSAlexander Shaposhnikov enum class S<T, U>::E {
77421c098bSAlexander Shaposhnikov   Value = SPECIALIZATION_REQUIRES
78421c098bSAlexander Shaposhnikov };
79421c098bSAlexander Shaposhnikov 
80421c098bSAlexander Shaposhnikov static_assert(static_cast<int>(S<char, double>::E::Value) == PRIMARY);
81421c098bSAlexander Shaposhnikov static_assert(static_cast<int>(S<XY, double>::E::Value) ==
82421c098bSAlexander Shaposhnikov               SPECIALIZATION_CONCEPT);
83421c098bSAlexander Shaposhnikov static_assert(static_cast<int>(S<int, double>::E::Value) ==
84421c098bSAlexander Shaposhnikov               SPECIALIZATION_REQUIRES);
85421c098bSAlexander Shaposhnikov 
86421c098bSAlexander Shaposhnikov } // namespace  enumerations
87421c098bSAlexander Shaposhnikov 
88421c098bSAlexander Shaposhnikov namespace multiple_template_parameter_lists {
89421c098bSAlexander Shaposhnikov 
90421c098bSAlexander Shaposhnikov template <class Outer>
91421c098bSAlexander Shaposhnikov struct S {
92421c098bSAlexander Shaposhnikov   template <class Inner>
93421c098bSAlexander Shaposhnikov   static constexpr int primary(Inner);
94421c098bSAlexander Shaposhnikov };
95421c098bSAlexander Shaposhnikov 
96421c098bSAlexander Shaposhnikov template <class Outer>
97421c098bSAlexander Shaposhnikov template <class Inner>
98421c098bSAlexander Shaposhnikov constexpr int S<Outer>::primary(Inner) {
99421c098bSAlexander Shaposhnikov   return PRIMARY;
100421c098bSAlexander Shaposhnikov };
101421c098bSAlexander Shaposhnikov 
102421c098bSAlexander Shaposhnikov template <Concept Outer>
103421c098bSAlexander Shaposhnikov struct S<Outer> {
104421c098bSAlexander Shaposhnikov   template <class Inner>
105421c098bSAlexander Shaposhnikov   static constexpr int specialization(Inner);
106421c098bSAlexander Shaposhnikov };
107421c098bSAlexander Shaposhnikov 
108421c098bSAlexander Shaposhnikov template <Concept Outer>
109421c098bSAlexander Shaposhnikov template <class Inner>
110421c098bSAlexander Shaposhnikov constexpr int S<Outer>::specialization(Inner) { return SPECIALIZATION_CONCEPT; }
111421c098bSAlexander Shaposhnikov 
112421c098bSAlexander Shaposhnikov template <class Outer>
113421c098bSAlexander Shaposhnikov   requires(sizeof(Outer) == sizeof(int))
114421c098bSAlexander Shaposhnikov struct S<Outer> {
115421c098bSAlexander Shaposhnikov   template <class Inner>
116421c098bSAlexander Shaposhnikov   static constexpr int specialization(Inner);
117421c098bSAlexander Shaposhnikov };
118421c098bSAlexander Shaposhnikov 
119421c098bSAlexander Shaposhnikov template <class Outer>
120421c098bSAlexander Shaposhnikov   requires(sizeof(Outer) == sizeof(int))
121421c098bSAlexander Shaposhnikov template <class Inner>
122421c098bSAlexander Shaposhnikov constexpr int S<Outer>::specialization(Inner) { return SPECIALIZATION_REQUIRES; }
123421c098bSAlexander Shaposhnikov 
124421c098bSAlexander Shaposhnikov static_assert(S<char>::primary("str") == PRIMARY);
125421c098bSAlexander Shaposhnikov static_assert(S<XY>::specialization("str") == SPECIALIZATION_CONCEPT);
126421c098bSAlexander Shaposhnikov static_assert(S<int>::specialization("str") == SPECIALIZATION_REQUIRES);
127421c098bSAlexander Shaposhnikov 
128421c098bSAlexander Shaposhnikov } // namespace multiple_template_parameter_lists
1296db007a0SAlexander Shaposhnikov 
1306db007a0SAlexander Shaposhnikov static constexpr int CONSTRAINED_METHOD_1 = 1;
1316db007a0SAlexander Shaposhnikov static constexpr int CONSTRAINED_METHOD_2 = 2;
1326db007a0SAlexander Shaposhnikov 
1336db007a0SAlexander Shaposhnikov namespace constrained_members {
1346db007a0SAlexander Shaposhnikov 
1356db007a0SAlexander Shaposhnikov template <int>
1366db007a0SAlexander Shaposhnikov struct S {
1376db007a0SAlexander Shaposhnikov   template <Concept C>
1386db007a0SAlexander Shaposhnikov   static constexpr int constrained_method();
1396db007a0SAlexander Shaposhnikov };
1406db007a0SAlexander Shaposhnikov 
1416db007a0SAlexander Shaposhnikov template <>
1426db007a0SAlexander Shaposhnikov template <Concept C>
1436db007a0SAlexander Shaposhnikov constexpr int S<1>::constrained_method() { return CONSTRAINED_METHOD_1; }
1446db007a0SAlexander Shaposhnikov 
1456db007a0SAlexander Shaposhnikov template <>
1466db007a0SAlexander Shaposhnikov template <Concept C>
1476db007a0SAlexander Shaposhnikov constexpr int S<2>::constrained_method() { return CONSTRAINED_METHOD_2; }
1486db007a0SAlexander Shaposhnikov 
1496db007a0SAlexander Shaposhnikov static_assert(S<1>::constrained_method<XY>() == CONSTRAINED_METHOD_1);
1506db007a0SAlexander Shaposhnikov static_assert(S<2>::constrained_method<XY>() == CONSTRAINED_METHOD_2);
1516db007a0SAlexander Shaposhnikov 
1526db007a0SAlexander Shaposhnikov 
1536db007a0SAlexander Shaposhnikov template <class T1, class T2>
1546db007a0SAlexander Shaposhnikov concept ConceptT1T2 = true;
1556db007a0SAlexander Shaposhnikov 
1566db007a0SAlexander Shaposhnikov template<typename T3>
1576db007a0SAlexander Shaposhnikov struct S12 {
1586db007a0SAlexander Shaposhnikov   template<ConceptT1T2<T3> T4>
1596db007a0SAlexander Shaposhnikov   static constexpr int constrained_method();
1606db007a0SAlexander Shaposhnikov };
1616db007a0SAlexander Shaposhnikov 
1626db007a0SAlexander Shaposhnikov template<>
1636db007a0SAlexander Shaposhnikov template<ConceptT1T2<int> T5>
1646db007a0SAlexander Shaposhnikov constexpr int S12<int>::constrained_method() { return CONSTRAINED_METHOD_1; }
1656db007a0SAlexander Shaposhnikov 
1666db007a0SAlexander Shaposhnikov template<>
1676db007a0SAlexander Shaposhnikov template<ConceptT1T2<double> T5>
1686db007a0SAlexander Shaposhnikov constexpr int S12<double>::constrained_method() { return CONSTRAINED_METHOD_2; }
1696db007a0SAlexander Shaposhnikov 
1706db007a0SAlexander Shaposhnikov static_assert(S12<int>::constrained_method<XY>() == CONSTRAINED_METHOD_1);
1716db007a0SAlexander Shaposhnikov static_assert(S12<double>::constrained_method<XY>() == CONSTRAINED_METHOD_2);
1726db007a0SAlexander Shaposhnikov 
1736db007a0SAlexander Shaposhnikov } // namespace constrained members
1746db007a0SAlexander Shaposhnikov 
1756db007a0SAlexander Shaposhnikov namespace constrained_members_of_nested_types {
1766db007a0SAlexander Shaposhnikov 
1776db007a0SAlexander Shaposhnikov template <int>
1786db007a0SAlexander Shaposhnikov struct S {
1796db007a0SAlexander Shaposhnikov   struct Inner0 {
1806db007a0SAlexander Shaposhnikov     struct Inner1 {
1816db007a0SAlexander Shaposhnikov       template <Concept C>
1826db007a0SAlexander Shaposhnikov       static constexpr int constrained_method();
1836db007a0SAlexander Shaposhnikov     };
1846db007a0SAlexander Shaposhnikov   };
1856db007a0SAlexander Shaposhnikov };
1866db007a0SAlexander Shaposhnikov 
1876db007a0SAlexander Shaposhnikov template <>
1886db007a0SAlexander Shaposhnikov template <Concept C>
1896db007a0SAlexander Shaposhnikov constexpr int S<1>::Inner0::Inner1::constrained_method() { return CONSTRAINED_METHOD_1; }
1906db007a0SAlexander Shaposhnikov 
1916db007a0SAlexander Shaposhnikov template <>
1926db007a0SAlexander Shaposhnikov template <Concept C>
1936db007a0SAlexander Shaposhnikov constexpr int S<2>::Inner0::Inner1::constrained_method() { return CONSTRAINED_METHOD_2; }
1946db007a0SAlexander Shaposhnikov 
1956db007a0SAlexander Shaposhnikov static_assert(S<1>::Inner0::Inner1::constrained_method<XY>() == CONSTRAINED_METHOD_1);
1966db007a0SAlexander Shaposhnikov static_assert(S<2>::Inner0::Inner1::constrained_method<XY>() == CONSTRAINED_METHOD_2);
1976db007a0SAlexander Shaposhnikov 
1986db007a0SAlexander Shaposhnikov 
1996db007a0SAlexander Shaposhnikov template <class T1, class T2>
2006db007a0SAlexander Shaposhnikov concept ConceptT1T2 = true;
2016db007a0SAlexander Shaposhnikov 
2026db007a0SAlexander Shaposhnikov template<typename T3>
2036db007a0SAlexander Shaposhnikov struct S12 {
2046db007a0SAlexander Shaposhnikov   struct Inner0 {
2056db007a0SAlexander Shaposhnikov     struct Inner1 {
2066db007a0SAlexander Shaposhnikov       template<ConceptT1T2<T3> T4>
2076db007a0SAlexander Shaposhnikov       static constexpr int constrained_method();
2086db007a0SAlexander Shaposhnikov     };
2096db007a0SAlexander Shaposhnikov   };
2106db007a0SAlexander Shaposhnikov };
2116db007a0SAlexander Shaposhnikov 
2126db007a0SAlexander Shaposhnikov template<>
2136db007a0SAlexander Shaposhnikov template<ConceptT1T2<int> T5>
2146db007a0SAlexander Shaposhnikov constexpr int S12<int>::Inner0::Inner1::constrained_method() { return CONSTRAINED_METHOD_1; }
2156db007a0SAlexander Shaposhnikov 
2166db007a0SAlexander Shaposhnikov template<>
2176db007a0SAlexander Shaposhnikov template<ConceptT1T2<double> T5>
2186db007a0SAlexander Shaposhnikov constexpr int S12<double>::Inner0::Inner1::constrained_method() { return CONSTRAINED_METHOD_2; }
2196db007a0SAlexander Shaposhnikov 
2206db007a0SAlexander Shaposhnikov static_assert(S12<int>::Inner0::Inner1::constrained_method<XY>() == CONSTRAINED_METHOD_1);
2216db007a0SAlexander Shaposhnikov static_assert(S12<double>::Inner0::Inner1::constrained_method<XY>() == CONSTRAINED_METHOD_2);
2226db007a0SAlexander Shaposhnikov 
2236db007a0SAlexander Shaposhnikov } // namespace constrained_members_of_nested_types
2246db007a0SAlexander Shaposhnikov 
2256db007a0SAlexander Shaposhnikov namespace constrained_member_sfinae {
2266db007a0SAlexander Shaposhnikov 
2276db007a0SAlexander Shaposhnikov template<int N> struct S {
2286db007a0SAlexander Shaposhnikov   template<class T>
22984a3aadfSAaron Ballman   static constexpr int constrained_method() requires (sizeof(int[N * 1073741824 + 4]) == 16) { // expected-warning {{variable length arrays in C++ are a Clang extension}} \
23084a3aadfSAaron Ballman                                                                                                   expected-note {{value 4294967296 is outside the range of representable values of type 'int'}} \
23184a3aadfSAaron Ballman                                                                                                   expected-note {{while calculating associated constraint of template 'constrained_method' here}}
2326db007a0SAlexander Shaposhnikov     return CONSTRAINED_METHOD_1;
2336db007a0SAlexander Shaposhnikov   }
2346db007a0SAlexander Shaposhnikov 
2356db007a0SAlexander Shaposhnikov   template<class T>
2366db007a0SAlexander Shaposhnikov   static constexpr int constrained_method() requires (sizeof(int[N]) == 16);
2376db007a0SAlexander Shaposhnikov };
2386db007a0SAlexander Shaposhnikov 
2396db007a0SAlexander Shaposhnikov template<>
2406db007a0SAlexander Shaposhnikov template<typename T>
2416db007a0SAlexander Shaposhnikov constexpr int S<4>::constrained_method() requires (sizeof(int[4]) == 16) {
2426db007a0SAlexander Shaposhnikov   return CONSTRAINED_METHOD_2;
2436db007a0SAlexander Shaposhnikov }
2446db007a0SAlexander Shaposhnikov 
2456db007a0SAlexander Shaposhnikov // Verify that there is no amiguity in this case.
2466db007a0SAlexander Shaposhnikov static_assert(S<4>::constrained_method<double>() == CONSTRAINED_METHOD_2);
2476db007a0SAlexander Shaposhnikov 
2486db007a0SAlexander Shaposhnikov } // namespace constrained_member_sfinae
2496db007a0SAlexander Shaposhnikov 
2506db007a0SAlexander Shaposhnikov namespace requires_expression_references_members {
2516db007a0SAlexander Shaposhnikov 
2526db007a0SAlexander Shaposhnikov void accept1(int x);
2536db007a0SAlexander Shaposhnikov void accept2(XY xy);
2546db007a0SAlexander Shaposhnikov 
2556db007a0SAlexander Shaposhnikov template <class T> struct S {
2566db007a0SAlexander Shaposhnikov   T Field = T();
2576db007a0SAlexander Shaposhnikov 
2586db007a0SAlexander Shaposhnikov   constexpr int constrained_method()
2596db007a0SAlexander Shaposhnikov       requires requires { accept1(Field); };
2606db007a0SAlexander Shaposhnikov 
2616db007a0SAlexander Shaposhnikov   constexpr int constrained_method()
2626db007a0SAlexander Shaposhnikov       requires requires { accept2(Field); };
2636db007a0SAlexander Shaposhnikov };
2646db007a0SAlexander Shaposhnikov 
2656db007a0SAlexander Shaposhnikov template <class T>
2666db007a0SAlexander Shaposhnikov constexpr int S<T>::constrained_method()
2676db007a0SAlexander Shaposhnikov   requires requires { accept1(Field); } {
2686db007a0SAlexander Shaposhnikov   return CONSTRAINED_METHOD_1;
2696db007a0SAlexander Shaposhnikov }
2706db007a0SAlexander Shaposhnikov 
2716db007a0SAlexander Shaposhnikov template <class T>
2726db007a0SAlexander Shaposhnikov constexpr int S<T>::constrained_method()
2736db007a0SAlexander Shaposhnikov   requires requires { accept2(Field); } {
2746db007a0SAlexander Shaposhnikov   return CONSTRAINED_METHOD_2;
2756db007a0SAlexander Shaposhnikov }
2766db007a0SAlexander Shaposhnikov 
2776db007a0SAlexander Shaposhnikov static_assert(S<int>().constrained_method() == CONSTRAINED_METHOD_1);
2786db007a0SAlexander Shaposhnikov static_assert(S<XY>().constrained_method() == CONSTRAINED_METHOD_2);
2796db007a0SAlexander Shaposhnikov 
2806db007a0SAlexander Shaposhnikov } // namespace requires_expression_references_members
2816db007a0SAlexander Shaposhnikov 
2826db007a0SAlexander Shaposhnikov namespace GH60231 {
2836db007a0SAlexander Shaposhnikov 
2846db007a0SAlexander Shaposhnikov template<typename T0> concept C = true;
2856db007a0SAlexander Shaposhnikov 
2866db007a0SAlexander Shaposhnikov template <typename T1>
2876db007a0SAlexander Shaposhnikov struct S {
2886db007a0SAlexander Shaposhnikov   template <typename F1> requires C<S<T1>>
2896db007a0SAlexander Shaposhnikov   void foo1(F1 f);
2906db007a0SAlexander Shaposhnikov 
2916db007a0SAlexander Shaposhnikov   template <typename F2>
2926db007a0SAlexander Shaposhnikov   void foo2(F2 f) requires C<S<T1>>;
2936db007a0SAlexander Shaposhnikov 
2946db007a0SAlexander Shaposhnikov   template <typename F3> requires C<F3>
2956db007a0SAlexander Shaposhnikov   void foo3(F3 f);
2966db007a0SAlexander Shaposhnikov };
2976db007a0SAlexander Shaposhnikov 
2986db007a0SAlexander Shaposhnikov template <typename T2>
2996db007a0SAlexander Shaposhnikov template <typename F4> requires C<S<T2>>
3006db007a0SAlexander Shaposhnikov void S<T2>::foo1(F4 f) {}
3016db007a0SAlexander Shaposhnikov 
3026db007a0SAlexander Shaposhnikov template <typename T3>
3036db007a0SAlexander Shaposhnikov template <typename F5>
3046db007a0SAlexander Shaposhnikov void S<T3>::foo2(F5 f) requires C<S<T3>> {}
3056db007a0SAlexander Shaposhnikov 
3066db007a0SAlexander Shaposhnikov template <typename T4>
3076db007a0SAlexander Shaposhnikov template <typename F6> requires C<F6>
3086db007a0SAlexander Shaposhnikov void S<T4>::foo3(F6 f) {}
3096db007a0SAlexander Shaposhnikov 
3106db007a0SAlexander Shaposhnikov } // namespace GH60231
3116db007a0SAlexander Shaposhnikov 
3126db007a0SAlexander Shaposhnikov namespace GH62003 {
3136db007a0SAlexander Shaposhnikov 
3146db007a0SAlexander Shaposhnikov template <typename T0> concept Concept = true;
3156db007a0SAlexander Shaposhnikov 
3166db007a0SAlexander Shaposhnikov template <class T1>
3176db007a0SAlexander Shaposhnikov struct S1 {
3186db007a0SAlexander Shaposhnikov   template <Concept C1>
3196db007a0SAlexander Shaposhnikov   static constexpr int foo();
3206db007a0SAlexander Shaposhnikov };
3216db007a0SAlexander Shaposhnikov template <class T2>
3226db007a0SAlexander Shaposhnikov template <Concept C2>
3236db007a0SAlexander Shaposhnikov constexpr int S1<T2>::foo() { return 1; }
3246db007a0SAlexander Shaposhnikov 
3256db007a0SAlexander Shaposhnikov template <Concept C3>
3266db007a0SAlexander Shaposhnikov struct S2 {
3276db007a0SAlexander Shaposhnikov   template <class T3>
3286db007a0SAlexander Shaposhnikov   static constexpr int foo();
3296db007a0SAlexander Shaposhnikov };
3306db007a0SAlexander Shaposhnikov template <Concept C4>
3316db007a0SAlexander Shaposhnikov template <class T4>
3326db007a0SAlexander Shaposhnikov constexpr int S2<C4>::foo() { return 2; }
3336db007a0SAlexander Shaposhnikov 
3346db007a0SAlexander Shaposhnikov template <Concept C5>
3356db007a0SAlexander Shaposhnikov struct S3 {
3366db007a0SAlexander Shaposhnikov   template <Concept C6>
3376db007a0SAlexander Shaposhnikov   static constexpr int foo();
3386db007a0SAlexander Shaposhnikov };
3396db007a0SAlexander Shaposhnikov template <Concept C7>
3406db007a0SAlexander Shaposhnikov template <Concept C8>
3416db007a0SAlexander Shaposhnikov constexpr int S3<C7>::foo() { return 3; }
3426db007a0SAlexander Shaposhnikov 
3436db007a0SAlexander Shaposhnikov static_assert(S1<int>::foo<int>() == 1);
3446db007a0SAlexander Shaposhnikov static_assert(S2<int>::foo<int>() == 2);
3456db007a0SAlexander Shaposhnikov static_assert(S3<int>::foo<int>() == 3);
3466db007a0SAlexander Shaposhnikov 
3476db007a0SAlexander Shaposhnikov } // namespace GH62003
3486db007a0SAlexander Shaposhnikov 
3496db007a0SAlexander Shaposhnikov namespace MultilevelTemplateWithPartialSpecialization {
3506db007a0SAlexander Shaposhnikov template <typename>
3516db007a0SAlexander Shaposhnikov concept Concept = true;
3526db007a0SAlexander Shaposhnikov 
3536db007a0SAlexander Shaposhnikov namespace two_level {
3546db007a0SAlexander Shaposhnikov template <typename T1, int>
3556db007a0SAlexander Shaposhnikov struct W0 {
3566db007a0SAlexander Shaposhnikov   template <typename T2>
3576db007a0SAlexander Shaposhnikov   requires (Concept<T2>)
3586db007a0SAlexander Shaposhnikov   void f(const T2 &);
3596db007a0SAlexander Shaposhnikov };
3606db007a0SAlexander Shaposhnikov 
3616db007a0SAlexander Shaposhnikov template <typename T3>
3626db007a0SAlexander Shaposhnikov struct W0<T3, 0> {
3636db007a0SAlexander Shaposhnikov   template <typename T4>
3646db007a0SAlexander Shaposhnikov   requires (Concept<T4>)
3656db007a0SAlexander Shaposhnikov   void f(const T4 &);
3666db007a0SAlexander Shaposhnikov };
3676db007a0SAlexander Shaposhnikov 
3686db007a0SAlexander Shaposhnikov template <typename T3>
3696db007a0SAlexander Shaposhnikov template <typename T4>
3706db007a0SAlexander Shaposhnikov requires (Concept<T4>)
3716db007a0SAlexander Shaposhnikov inline void W0<T3, 0>::f(const T4 &) {}
3726db007a0SAlexander Shaposhnikov } // namespace two_level
3736db007a0SAlexander Shaposhnikov 
3746db007a0SAlexander Shaposhnikov namespace three_level {
3756db007a0SAlexander Shaposhnikov template <typename T1, int>
3766db007a0SAlexander Shaposhnikov struct W0 {
3776db007a0SAlexander Shaposhnikov   template <typename T2>
3786db007a0SAlexander Shaposhnikov   struct W1 {
3796db007a0SAlexander Shaposhnikov     template <typename T3>
3806db007a0SAlexander Shaposhnikov     requires (Concept<T3>)
3816db007a0SAlexander Shaposhnikov     void f(const T3 &);
3826db007a0SAlexander Shaposhnikov   };
3836db007a0SAlexander Shaposhnikov };
3846db007a0SAlexander Shaposhnikov 
3856db007a0SAlexander Shaposhnikov template <typename T4>
3866db007a0SAlexander Shaposhnikov struct W0<T4, 0> {
3876db007a0SAlexander Shaposhnikov   template <typename T5>
3886db007a0SAlexander Shaposhnikov   struct W1 {
3896db007a0SAlexander Shaposhnikov     template <typename T6>
3906db007a0SAlexander Shaposhnikov     requires (Concept<T6>)
3916db007a0SAlexander Shaposhnikov     void f(const T6 &);
3926db007a0SAlexander Shaposhnikov   };
3936db007a0SAlexander Shaposhnikov };
3946db007a0SAlexander Shaposhnikov 
3956db007a0SAlexander Shaposhnikov template <typename T7>
3966db007a0SAlexander Shaposhnikov template <typename T8>
3976db007a0SAlexander Shaposhnikov template <typename T9>
3986db007a0SAlexander Shaposhnikov requires (Concept<T9>)
3996db007a0SAlexander Shaposhnikov inline void W0<T7, 0>::W1<T8>::f(const T9 &) {}
4006db007a0SAlexander Shaposhnikov } // namespace three_level
4016db007a0SAlexander Shaposhnikov 
4026db007a0SAlexander Shaposhnikov } // namespace MultilevelTemplateWithPartialSpecialization
403fbd8f898SErich Keane 
404fbd8f898SErich Keane namespace PR62697 {
405fbd8f898SErich Keane template<typename>
406fbd8f898SErich Keane concept c = true;
407fbd8f898SErich Keane 
408fbd8f898SErich Keane template<typename T>
409fbd8f898SErich Keane struct s {
410fbd8f898SErich Keane     void f() requires c<void(T)>;
411fbd8f898SErich Keane };
412fbd8f898SErich Keane 
413fbd8f898SErich Keane template<typename T>
414fbd8f898SErich Keane void s<T>::f() requires c<void(T)> { }
415fbd8f898SErich Keane }
4163a9683fcSRichard Smith 
4173a9683fcSRichard Smith namespace GH62272 {
4183a9683fcSRichard Smith template<typename T> concept A = true;
4193a9683fcSRichard Smith template<typename T> struct X { A<T> auto f(); };
4203a9683fcSRichard Smith template<typename T> A<T> auto X<T>::f() {}
4213a9683fcSRichard Smith }
422bfddbdafSErich Keane 
423bfddbdafSErich Keane namespace GH65810 {
424bfddbdafSErich Keane template<typename Param>
425bfddbdafSErich Keane concept TrivialConcept =
426bfddbdafSErich Keane requires(Param param) {
427bfddbdafSErich Keane   (void)param;
428bfddbdafSErich Keane };
429bfddbdafSErich Keane 
430bfddbdafSErich Keane template <typename T>
431bfddbdafSErich Keane struct Base {
432bfddbdafSErich Keane   class InnerClass;
433bfddbdafSErich Keane };
434bfddbdafSErich Keane 
435bfddbdafSErich Keane template <typename T>
436bfddbdafSErich Keane class Base<T>::InnerClass {
437bfddbdafSErich Keane   template <typename Param>
438bfddbdafSErich Keane     requires TrivialConcept<Param>
439bfddbdafSErich Keane     int func(Param param) const;
440bfddbdafSErich Keane };
441bfddbdafSErich Keane 
442bfddbdafSErich Keane template <typename T>
443bfddbdafSErich Keane template <typename Param>
444bfddbdafSErich Keane requires TrivialConcept<Param>
445bfddbdafSErich Keane int Base<T>::InnerClass::func(Param param) const {
446bfddbdafSErich Keane   return 0;
447bfddbdafSErich Keane }
448bfddbdafSErich Keane 
449bfddbdafSErich Keane template<typename T>
450bfddbdafSErich Keane struct Outermost {
451bfddbdafSErich Keane   struct Middle {
452bfddbdafSErich Keane     template<typename U>
453bfddbdafSErich Keane     struct Innermost {
454bfddbdafSErich Keane       template <typename Param>
455bfddbdafSErich Keane         requires TrivialConcept<Param>
456bfddbdafSErich Keane         int func(Param param) const;
457bfddbdafSErich Keane     };
458bfddbdafSErich Keane   };
459bfddbdafSErich Keane };
460bfddbdafSErich Keane 
461bfddbdafSErich Keane template <typename T>
462bfddbdafSErich Keane template <typename U>
463bfddbdafSErich Keane template <typename Param>
464bfddbdafSErich Keane requires TrivialConcept<Param>
465bfddbdafSErich Keane int Outermost<T>::Middle::Innermost<U>::func(Param param) const {
466bfddbdafSErich Keane   return 0;
467bfddbdafSErich Keane }
468bfddbdafSErich Keane 
469bfddbdafSErich Keane } // namespace GH65810
47098191d7cSErich Keane 
47198191d7cSErich Keane namespace GH61763 {
47298191d7cSErich Keane template<typename T, typename U>
47398191d7cSErich Keane concept same_as = true;
47498191d7cSErich Keane 
47598191d7cSErich Keane template <class = void>
47698191d7cSErich Keane struct Foo {
47798191d7cSErich Keane       template <same_as<void> Param>
47898191d7cSErich Keane             friend struct Bar;
47998191d7cSErich Keane };
48098191d7cSErich Keane 
48198191d7cSErich Keane template struct Foo<>;
48298191d7cSErich Keane 
48398191d7cSErich Keane template <same_as<void> Param>
48498191d7cSErich Keane struct Bar {
48598191d7cSErich Keane };
48698191d7cSErich Keane 
48798191d7cSErich Keane 
48898191d7cSErich Keane template<typename T>
48998191d7cSErich Keane concept ok = true;
49098191d7cSErich Keane 
49198191d7cSErich Keane struct outer {
49298191d7cSErich Keane     template<typename T>
49398191d7cSErich Keane         requires ok<T>
49498191d7cSErich Keane           struct foo {};
49598191d7cSErich Keane };
49698191d7cSErich Keane 
49798191d7cSErich Keane template<typename U>
49898191d7cSErich Keane struct bar {
49998191d7cSErich Keane     template<typename T>
50098191d7cSErich Keane         requires ok<T>
50198191d7cSErich Keane           friend struct outer::foo;
50298191d7cSErich Keane };
50398191d7cSErich Keane 
50498191d7cSErich Keane bar<int> x;
50598191d7cSErich Keane } // namespace GH61763
50698191d7cSErich Keane 
507f5efa749SIlya Biryukov 
508f5efa749SIlya Biryukov namespace GH74314 {
509f5efa749SIlya Biryukov template <class T, class U> constexpr bool is_same_v = __is_same(T, U);
510f5efa749SIlya Biryukov template <class T, class U> constexpr bool is_not_same_v = !__is_same(T, U);
511f5efa749SIlya Biryukov 
512f5efa749SIlya Biryukov template <class Result>
513f5efa749SIlya Biryukov concept something_interesting = requires {
514f5efa749SIlya Biryukov       true;
515f5efa749SIlya Biryukov       requires is_same_v<int, Result>;
516f5efa749SIlya Biryukov };
517f5efa749SIlya Biryukov 
518f5efa749SIlya Biryukov template <class T>
5198282c58dSc8ef struct X { // #defined-here
520f5efa749SIlya Biryukov       void foo() requires requires { requires is_not_same_v<T, int>; };
521f5efa749SIlya Biryukov       void bar(decltype(requires { requires is_not_same_v<T, int>; }));
522f5efa749SIlya Biryukov };
523f5efa749SIlya Biryukov 
524f5efa749SIlya Biryukov template <class T>
525f5efa749SIlya Biryukov void X<T>::foo() requires requires { requires something_interesting<T>; } {}
526f5efa749SIlya Biryukov // expected-error@-1{{definition of 'foo' does not match any declaration}}
5278282c58dSc8ef // expected-note@#defined-here{{defined here}}
5288282c58dSc8ef // expected-note@-8{{member declaration nearly matches}}
529f5efa749SIlya Biryukov 
530f5efa749SIlya Biryukov template <class T>
531f5efa749SIlya Biryukov void X<T>::foo() requires requires { requires is_not_same_v<T, int>; } {} // ok
532f5efa749SIlya Biryukov 
533f5efa749SIlya Biryukov template <class T>
534f5efa749SIlya Biryukov void X<T>::bar(decltype(requires { requires something_interesting<T>; })) {}
535f5efa749SIlya Biryukov // expected-error@-1{{definition of 'bar' does not match any declaration}}
5368282c58dSc8ef // expected-note@#defined-here{{defined here}}
537f5efa749SIlya Biryukov 
538f5efa749SIlya Biryukov template <class T>
539f5efa749SIlya Biryukov void X<T>::bar(decltype(requires { requires is_not_same_v<T, int>; })) {}
540f5efa749SIlya Biryukov } // namespace GH74314
54104d20b17SYounan Zhang 
542ab70ac60SYounan Zhang namespace GH56482 {
543ab70ac60SYounan Zhang template <typename SlotMap>
544ab70ac60SYounan Zhang concept slot_map_has_reserve = true;
545ab70ac60SYounan Zhang 
546ab70ac60SYounan Zhang template <typename T> struct Slot_map {
547ab70ac60SYounan Zhang   constexpr void reserve() const noexcept
548ab70ac60SYounan Zhang     requires slot_map_has_reserve<Slot_map>;
549ab70ac60SYounan Zhang 
550ab70ac60SYounan Zhang   constexpr void reserve(int) const noexcept
551ab70ac60SYounan Zhang     requires slot_map_has_reserve<Slot_map<T>>;
552ab70ac60SYounan Zhang };
553ab70ac60SYounan Zhang 
554ab70ac60SYounan Zhang template <typename T>
555ab70ac60SYounan Zhang constexpr void Slot_map<T>::reserve() const noexcept
556ab70ac60SYounan Zhang   requires slot_map_has_reserve<Slot_map<T>>
557ab70ac60SYounan Zhang {}
558ab70ac60SYounan Zhang 
559ab70ac60SYounan Zhang template <typename T>
560ab70ac60SYounan Zhang constexpr void Slot_map<T>::reserve(int) const noexcept
561ab70ac60SYounan Zhang   requires slot_map_has_reserve<Slot_map>
562ab70ac60SYounan Zhang {}
563ab70ac60SYounan Zhang } // namespace GH56482
564ab70ac60SYounan Zhang 
56504d20b17SYounan Zhang namespace GH74447 {
56604d20b17SYounan Zhang template <typename T> struct S {
56704d20b17SYounan Zhang   template <typename... U, int V>
56804d20b17SYounan Zhang   void test(T target, U... value)
56904d20b17SYounan Zhang     requires requires {
57004d20b17SYounan Zhang       target;
57104d20b17SYounan Zhang       sizeof...(value) == 1;
57204d20b17SYounan Zhang       V == 2;
57304d20b17SYounan Zhang     };
57404d20b17SYounan Zhang };
57504d20b17SYounan Zhang 
57604d20b17SYounan Zhang template <typename T>
57704d20b17SYounan Zhang template <typename... U, int V>
57804d20b17SYounan Zhang void S<T>::test(T target, U... value)
57904d20b17SYounan Zhang   requires requires {
58004d20b17SYounan Zhang     target;
58104d20b17SYounan Zhang     sizeof...(value) == 1;
58204d20b17SYounan Zhang     V == 2;
58304d20b17SYounan Zhang   }
58404d20b17SYounan Zhang {}
58504d20b17SYounan Zhang } // namespace GH74447
5862c2d291bSYounan Zhang 
5872c2d291bSYounan Zhang namespace GH72557 {
5882c2d291bSYounan Zhang 
5892c2d291bSYounan Zhang template <typename...>
5902c2d291bSYounan Zhang concept IsAnyOf = true;
5912c2d291bSYounan Zhang 
5922c2d291bSYounan Zhang template <class... DerTs> struct DerivedCollection {
5932c2d291bSYounan Zhang   template <class DerT>
5942c2d291bSYounan Zhang     requires IsAnyOf<DerTs...>
5952c2d291bSYounan Zhang   unsigned long index();
5962c2d291bSYounan Zhang };
5972c2d291bSYounan Zhang 
5982c2d291bSYounan Zhang template <class... DerTs>
5992c2d291bSYounan Zhang template <class DerT>
6002c2d291bSYounan Zhang   requires IsAnyOf<DerTs...>
6012c2d291bSYounan Zhang unsigned long DerivedCollection<DerTs...>::index() {}
6022c2d291bSYounan Zhang 
6032c2d291bSYounan Zhang } // namespace GH72557
604e6974daaSYounan Zhang 
605e6974daaSYounan Zhang namespace GH101735 {
606e6974daaSYounan Zhang 
607e6974daaSYounan Zhang template <class, class>
608e6974daaSYounan Zhang concept True = true;
609e6974daaSYounan Zhang 
610e6974daaSYounan Zhang template <typename T>
611e6974daaSYounan Zhang class A {
612e6974daaSYounan Zhang   template <typename... Ts>
613e6974daaSYounan Zhang   void method(Ts&... ts)
614e6974daaSYounan Zhang     requires requires (T t) {
615e6974daaSYounan Zhang       { t.method(static_cast<Ts &&>(ts)...) } -> True<void>;
616e6974daaSYounan Zhang     };
617e6974daaSYounan Zhang };
618e6974daaSYounan Zhang 
619e6974daaSYounan Zhang template <typename T>
620e6974daaSYounan Zhang template <typename... Ts>
621e6974daaSYounan Zhang void A<T>::method(Ts&... ts)
622e6974daaSYounan Zhang   requires requires (T t) {
623e6974daaSYounan Zhang     { t.method(static_cast<Ts &&>(ts)...) } -> True<void>;
624e6974daaSYounan Zhang   } {}
625e6974daaSYounan Zhang 
626e6974daaSYounan Zhang }
627e32a62c0SBalazs Benics 
628e32a62c0SBalazs Benics namespace GH63782 {
629e32a62c0SBalazs Benics // GH63782 was also fixed by PR #80594, so let's add a test for it.
630e32a62c0SBalazs Benics 
631e32a62c0SBalazs Benics template<bool... Vals>
632e32a62c0SBalazs Benics constexpr bool All = (Vals && ...);
633e32a62c0SBalazs Benics 
634e32a62c0SBalazs Benics template<bool... Bs>
635e32a62c0SBalazs Benics class Class {
636e32a62c0SBalazs Benics   template<typename>
637e32a62c0SBalazs Benics   requires All<Bs...>
638e32a62c0SBalazs Benics   void Foo();
639e32a62c0SBalazs Benics };
640e32a62c0SBalazs Benics 
641e32a62c0SBalazs Benics template<bool... Bs>
642e32a62c0SBalazs Benics template<typename>
643e32a62c0SBalazs Benics requires All<Bs...>
644e32a62c0SBalazs Benics void Class<Bs...>::Foo() {
645e32a62c0SBalazs Benics };
646e32a62c0SBalazs Benics 
647e32a62c0SBalazs Benics } // namespace GH63782
648e32a62c0SBalazs Benics 
649e32a62c0SBalazs Benics namespace eve {
650e32a62c0SBalazs Benics // Reduced from the "eve" project
651e32a62c0SBalazs Benics 
652e32a62c0SBalazs Benics template <typename... Ts>
653e32a62c0SBalazs Benics struct tuple {
654e32a62c0SBalazs Benics   template <int I0> requires(I0 <= sizeof...(Ts))
655e32a62c0SBalazs Benics   constexpr auto split();
656e32a62c0SBalazs Benics };
657e32a62c0SBalazs Benics 
658e32a62c0SBalazs Benics template <typename... Ts>
659e32a62c0SBalazs Benics template <int I0>
660e32a62c0SBalazs Benics requires(I0 <= sizeof...(Ts))
661e32a62c0SBalazs Benics constexpr auto tuple<Ts...>::split(){
662e32a62c0SBalazs Benics   return 0;
663e32a62c0SBalazs Benics }
664e32a62c0SBalazs Benics 
665e32a62c0SBalazs Benics int foo() {
666e32a62c0SBalazs Benics   tuple<int, float> x;
667e32a62c0SBalazs Benics   return x.split<0>();
668e32a62c0SBalazs Benics }
669e32a62c0SBalazs Benics 
670e32a62c0SBalazs Benics } // namespace eve
671463a4f15SYounan Zhang 
672463a4f15SYounan Zhang namespace GH93099 {
673463a4f15SYounan Zhang 
674463a4f15SYounan Zhang // Issues with sizeof...(expr)
675463a4f15SYounan Zhang 
676463a4f15SYounan Zhang template <typename T = int> struct C {
677463a4f15SYounan Zhang   template <int... N>
678463a4f15SYounan Zhang     requires(sizeof...(N) > 0)
679463a4f15SYounan Zhang   friend class NTTP;
680463a4f15SYounan Zhang 
681463a4f15SYounan Zhang   template <class... Tp>
682463a4f15SYounan Zhang     requires(sizeof...(Tp) > 0)
683463a4f15SYounan Zhang   friend class TP;
684463a4f15SYounan Zhang 
685463a4f15SYounan Zhang   template <template <typename> class... TTp>
686463a4f15SYounan Zhang     requires(sizeof...(TTp) > 0)
687463a4f15SYounan Zhang   friend class TTP;
688463a4f15SYounan Zhang };
689463a4f15SYounan Zhang 
690463a4f15SYounan Zhang template <int... N>
691463a4f15SYounan Zhang   requires(sizeof...(N) > 0)
692463a4f15SYounan Zhang class NTTP;
693463a4f15SYounan Zhang 
694463a4f15SYounan Zhang template <class... Tp>
695463a4f15SYounan Zhang   requires(sizeof...(Tp) > 0)
696463a4f15SYounan Zhang class TP;
697463a4f15SYounan Zhang 
698463a4f15SYounan Zhang template <template <typename> class... TTp>
699463a4f15SYounan Zhang   requires(sizeof...(TTp) > 0)
700463a4f15SYounan Zhang class TTP;
701463a4f15SYounan Zhang 
702463a4f15SYounan Zhang C v;
703463a4f15SYounan Zhang 
704463a4f15SYounan Zhang } // namespace GH93099
705227afac3SYounan Zhang 
70637b4df43SYounan Zhang namespace GH115098 {
70737b4df43SYounan Zhang 
70837b4df43SYounan Zhang template <typename... Ts> struct c {
70937b4df43SYounan Zhang   template <typename T>
71037b4df43SYounan Zhang     requires(sizeof...(Ts) > 0)
71137b4df43SYounan Zhang   friend bool operator==(c, c);
71237b4df43SYounan Zhang };
71337b4df43SYounan Zhang 
71437b4df43SYounan Zhang template <typename... Ts> struct d {
71537b4df43SYounan Zhang   template <typename T>
71637b4df43SYounan Zhang     requires(sizeof...(Ts) > 0)
71737b4df43SYounan Zhang   friend bool operator==(d, d);
71837b4df43SYounan Zhang };
71937b4df43SYounan Zhang 
72037b4df43SYounan Zhang template struct c<int>;
72137b4df43SYounan Zhang template struct d<int, int>;
72237b4df43SYounan Zhang 
72337b4df43SYounan Zhang } // namespace GH115098
72437b4df43SYounan Zhang 
725*27c91730SYounan Zhang namespace GH123441 {
726*27c91730SYounan Zhang 
727*27c91730SYounan Zhang struct buf {
728*27c91730SYounan Zhang   constexpr buf(auto&&... initList) requires (sizeof...(initList) <= 8);
729*27c91730SYounan Zhang };
730*27c91730SYounan Zhang 
731*27c91730SYounan Zhang constexpr buf::buf(auto&&... initList) requires (sizeof...(initList) <= 8) {}
732*27c91730SYounan Zhang 
733*27c91730SYounan Zhang template <class>
734*27c91730SYounan Zhang struct buffer {
735*27c91730SYounan Zhang   constexpr buffer(auto&&... initList) requires (sizeof...(initList) <= 8);
736*27c91730SYounan Zhang };
737*27c91730SYounan Zhang 
738*27c91730SYounan Zhang template <class T>
739*27c91730SYounan Zhang constexpr buffer<T>::buffer(auto&&... initList) requires (sizeof...(initList) <= 8) {}
740*27c91730SYounan Zhang 
741*27c91730SYounan Zhang template <class...>
742*27c91730SYounan Zhang struct foo { // expected-note {{foo defined here}}
743*27c91730SYounan Zhang   constexpr foo(auto&&... initList)
744*27c91730SYounan Zhang     requires (sizeof...(initList) <= 8);
745*27c91730SYounan Zhang };
746*27c91730SYounan Zhang 
747*27c91730SYounan Zhang template <class... T>
748*27c91730SYounan Zhang constexpr foo<T...>::foo(auto&&... initList) // expected-error {{does not match any declaration}}
749*27c91730SYounan Zhang   requires (sizeof...(T) <= 8) {}
750*27c91730SYounan Zhang 
751*27c91730SYounan Zhang } // namespace GH123441
752*27c91730SYounan Zhang 
753227afac3SYounan Zhang namespace GH114685 {
754227afac3SYounan Zhang 
755227afac3SYounan Zhang template <typename T> struct ptr {
756227afac3SYounan Zhang   template <typename U>
757227afac3SYounan Zhang   friend ptr<U> make_item(auto &&args)
758227afac3SYounan Zhang     requires(sizeof(args) > 1);
759227afac3SYounan Zhang };
760227afac3SYounan Zhang 
761227afac3SYounan Zhang template <typename U>
762227afac3SYounan Zhang ptr<U> make_item(auto &&args)
763227afac3SYounan Zhang   requires(sizeof(args) > 1) {}
764227afac3SYounan Zhang 
765227afac3SYounan Zhang ptr<char> p;
766227afac3SYounan Zhang 
767227afac3SYounan Zhang } // namespace GH114685
76869d0c4c1SYounan Zhang 
76969d0c4c1SYounan Zhang namespace GH123472 {
77069d0c4c1SYounan Zhang 
77169d0c4c1SYounan Zhang consteval bool fn() { return true; }
77269d0c4c1SYounan Zhang 
77369d0c4c1SYounan Zhang struct S {
77469d0c4c1SYounan Zhang   template <typename T>
77569d0c4c1SYounan Zhang   static consteval void mfn() requires (bool(&fn));
77669d0c4c1SYounan Zhang };
77769d0c4c1SYounan Zhang 
77869d0c4c1SYounan Zhang template <typename T>
77969d0c4c1SYounan Zhang consteval void S::mfn() requires (bool(&fn)) {}
78069d0c4c1SYounan Zhang 
78169d0c4c1SYounan Zhang }
782