1 // RUN: %clang_cc1 -std=c++2a -x c++ %s -verify -Wno-unused-value 2 3 template<typename T, typename U> 4 constexpr bool is_same_v = false; 5 6 template<typename T> 7 constexpr bool is_same_v<T, T> = true; 8 9 // We use a hack in this file to make the compiler print out the requires 10 // expression after it has been instantiated - we put false_v<requires {...}> as 11 // the requires clause of a class template, then instantiate the template. 12 // The requirement will not be satisfied, and the explaining diagnostic will 13 // print out false_v<requires {...}> in its raw form (the false_v serves to 14 // prevent the diagnostic from elaborating on why the requires expr wasn't 15 // satisfied). 16 17 template<bool v> 18 constexpr bool false_v = false; 19 20 template<typename... Ts> 21 using void_t = void; 22 23 // Check that requires parameters are instantiated correctly. 24 25 template<typename T> requires 26 false_v<requires (T t) { requires is_same_v<decltype(t), int>; }> 27 // expected-note@-1 {{because 'false_v<requires (int t) { requires is_same_v<decltype(t), int>; }>' evaluated to false}} 28 // expected-note@-2 {{because 'false_v<requires (char t) { requires is_same_v<decltype(t), int>; }>' evaluated to false}} 29 struct r1 {}; 30 31 using r1i1 = r1<int>; // expected-error {{constraints not satisfied for class template 'r1' [with T = int]}} 32 using r1i2 = r1<char>; // expected-error {{constraints not satisfied for class template 'r1' [with T = char]}} 33 34 // Check that parameter packs work. 35 36 template<typename... Ts> requires 37 false_v<requires (Ts... ts) {requires ((sizeof(ts) == 2) && ...);}> 38 // expected-note@-1 {{because 'false_v<requires (short ts, unsigned short ts) { requires (sizeof (ts) == 2) && (sizeof (ts) == 2); }>'}} 39 // expected-note@-2 {{because 'false_v<requires (short ts) { requires (sizeof (ts) == 2); }>' evaluated to false}} 40 struct r2 {}; 41 42 using r2i1 = r2<short, unsigned short>; // expected-error {{constraints not satisfied for class template 'r2' [with Ts = <short, unsigned short>]}} 43 using r2i2 = r2<short>; // expected-error {{constraints not satisfied for class template 'r2' [with Ts = <short>]}} 44 45 template<typename... Ts> requires 46 false_v<(requires (Ts ts) {requires sizeof(ts) != 0;} && ...)> 47 // expected-note@-1 {{because 'false_v<requires (short ts) { requires sizeof (ts) != 0; } && requires (unsigned short ts) { requires sizeof (ts) != 0; }>' evaluated to false}} 48 // expected-note@-2 {{because 'false_v<requires (short ts) { requires sizeof (ts) != 0; }>' evaluated to false}} 49 struct r3 {}; 50 51 using r3i1 = r3<short, unsigned short>; // expected-error {{constraints not satisfied for class template 'r3' [with Ts = <short, unsigned short>]}} 52 using r3i2 = r3<short>; // expected-error {{constraints not satisfied for class template 'r3' [with Ts = <short>]}} 53 54 template<typename T> 55 struct identity { using type = T; }; 56 57 namespace type_requirement { 58 struct A {}; 59 60 // check that nested name specifier is instantiated correctly. 61 template<typename T> requires false_v<requires { typename T::type; }> // expected-note{{because 'false_v<requires { typename identity<int>::type; }>' evaluated to false}} 62 struct r1 {}; 63 64 using r1i = r1<identity<int>>; // expected-error{{constraints not satisfied for class template 'r1' [with T = identity<int>]}} 65 66 // check that template argument list is instantiated correctly. 67 template<typename T> 68 struct contains_template { 69 template<typename U> requires is_same_v<contains_template<T>, U> 70 using temp = int; 71 }; 72 73 template<typename T> requires 74 false_v<requires { typename T::template temp<T>; }> 75 // expected-note@-1 {{because 'false_v<requires { typename contains_template<int>::temp<contains_template<int> >; }>' evaluated to false}} 76 // expected-note@-2 {{because 'false_v<requires { typename contains_template<short>::temp<contains_template<short> >; }>' evaluated to false}} 77 struct r2 {}; 78 79 using r2i1 = r2<contains_template<int>>; // expected-error{{constraints not satisfied for class template 'r2' [with T = type_requirement::contains_template<int>]}} 80 using r2i2 = r2<contains_template<short>>; // expected-error{{constraints not satisfied for class template 'r2' [with T = type_requirement::contains_template<short>]}} 81 82 // substitution error occurs, then requires expr is instantiated again 83 84 template<typename T> 85 struct a { 86 template<typename U> requires (requires { typename T::a::a; }, false) 87 // expected-note@-1{{because 'requires { <<error-type>>; } , false' evaluated to false}} 88 struct r {}; 89 }; 90 91 using ari = a<int>::r<short>; // expected-error{{constraints not satisfied for class template 'r' [with U = short]}} 92 93 // Parameter pack inside expr 94 template<typename... Ts> requires 95 false_v<(requires { typename Ts::type; } && ...)> 96 // expected-note@-1 {{because 'false_v<requires { typename identity<short>::type; } && requires { typename identity<int>::type; } && requires { <<error-type>>; }>' evaluated to false}} 97 struct r5 {}; 98 99 using r5i = r5<identity<short>, identity<int>, short>; // expected-error{{constraints not satisfied for class template 'r5' [with Ts = <identity<short>, identity<int>, short>]}} 100 template<typename... Ts> requires 101 false_v<(requires { typename void_t<Ts>; } && ...)> // expected-note{{because 'false_v<requires { typename void_t<int>; } && requires { typename void_t<short>; }>' evaluated to false}} 102 struct r6 {}; 103 104 using r6i = r6<int, short>; // expected-error{{constraints not satisfied for class template 'r6' [with Ts = <int, short>]}} 105 106 template<typename... Ts> requires 107 false_v<(requires { typename Ts::template aaa<Ts>; } && ...)> 108 // expected-note@-1 {{because 'false_v<requires { <<error-type>>; } && requires { <<error-type>>; }>' evaluated to false}} 109 struct r7 {}; 110 111 using r7i = r7<int, A>; // expected-error{{constraints not satisfied for class template 'r7' [with Ts = <int, type_requirement::A>]}} 112 } 113 114 namespace expr_requirement { 115 // check that compound/simple requirements are instantiated correctly. 116 117 template<typename T> requires false_v<requires { sizeof(T); { sizeof(T) }; }> 118 // expected-note@-1 {{because 'false_v<requires { sizeof(int); { sizeof(int) }; }>' evaluated to false}} 119 // expected-note@-2 {{because 'false_v<requires { <<error-expression>>; { sizeof(T) }; }>' evaluated to false}} 120 struct r1 {}; 121 122 using r1i1 = r1<int>; // expected-error{{constraints not satisfied for class template 'r1' [with T = int]}} 123 using r1i2 = r1<void>; // expected-error{{constraints not satisfied for class template 'r1' [with T = void]}} 124 125 // substitution error occurs in expr, then expr is instantiated again. 126 127 template<typename T> 128 struct a { 129 template<typename U> requires (requires { sizeof(T::a); }, false) // expected-note{{because 'requires { <<error-expression>>; } , false' evaluated to false}} 130 struct r {}; 131 }; 132 133 using ari = a<int>::r<short>; // expected-error{{constraints not satisfied for class template 'r' [with U = short]}} 134 135 // check that the return-type-requirement is instantiated correctly. 136 137 template<typename T, typename U = int> 138 concept C1 = is_same_v<T, U>; 139 140 template<typename T> requires false_v<requires(T t) { { t } -> C1<T>; }> 141 // expected-note@-1 {{because 'false_v<requires (int t) { { t } -> C1<int>; }>' evaluated to false}} 142 // expected-note@-2 {{because 'false_v<requires (double t) { { t } -> C1<double>; }>' evaluated to false}} 143 struct r2 {}; 144 145 using r2i1 = r2<int>; // expected-error{{constraints not satisfied for class template 'r2' [with T = int]}} 146 using r2i2 = r2<double>; // expected-error{{constraints not satisfied for class template 'r2' [with T = double]}} 147 148 149 // substitution error occurs in return type requirement, then requires expr is 150 // instantiated again. 151 152 template<typename T> 153 struct b { 154 template<typename U> requires (requires { { 0 } -> C1<typename T::a>; }, false) // expected-note{{because 'requires { { 0 } -> <<error-type>>; } , false' evaluated to false}} 155 struct r {}; 156 }; 157 158 using bri = b<int>::r<short>; // expected-error{{constraints not satisfied for class template 'r' [with U = short]}} 159 160 161 template<typename... Ts> requires 162 false_v<(requires { { 0 } noexcept -> C1<Ts>; } && ...)> 163 // expected-note@-1 {{because 'false_v<requires { { 0 } noexcept -> C1<int>; } && requires { { 0 } noexcept -> C1<unsigned int>; }>' evaluated to false}} 164 struct r3 {}; 165 166 using r3i = r3<int, unsigned int>; // expected-error{{constraints not satisfied for class template 'r3' [with Ts = <int, unsigned int>]}} 167 168 template<typename T> 169 struct r4 { fooexpr_requirement::r4170 constexpr int foo() { 171 if constexpr (requires { this->invalid(); }) 172 return 1; 173 else 174 return 0; 175 } 176 invalidexpr_requirement::r4177 constexpr void invalid() requires false { } 178 }; 179 static_assert(r4<int>{}.foo() == 0); 180 } 181 182 namespace nested_requirement { 183 // check that constraint expression is instantiated correctly 184 template<typename T> requires false_v<requires { requires sizeof(T) == 2; }> // expected-note{{because 'false_v<requires { requires sizeof(int) == 2; }>' evaluated to false}} 185 struct r1 {}; 186 187 using r1i = r1<int>; // expected-error{{constraints not satisfied for class template 'r1' [with T = int]}} 188 189 // substitution error occurs in expr, then expr is instantiated again. 190 template<typename T> 191 struct a { 192 template<typename U> requires 193 (requires { requires sizeof(T::a) == 0; }, false) // expected-note{{because 'requires { requires <<error-expression>>; } , false' evaluated to false}} 194 struct r {}; 195 }; 196 197 using ari = a<int>::r<short>; // expected-error{{constraints not satisfied for class template 'r' [with U = short]}} 198 199 // Parameter pack inside expr 200 template<typename... Ts> requires 201 false_v<(requires { requires sizeof(Ts) == 0; } && ...)> 202 // expected-note@-1 {{because 'false_v<requires { requires sizeof(int) == 0; } && requires { requires sizeof(short) == 0; }>' evaluated to false}} 203 struct r2 {}; 204 205 using r2i = r2<int, short>; // expected-error{{constraints not satisfied for class template 'r2' [with Ts = <int, short>]}} 206 } 207 208 // Parameter pack inside multiple requirements 209 template<typename... Ts> requires 210 false_v<(requires { requires sizeof(Ts) == 0; sizeof(Ts); } && ...)> 211 // expected-note@-1 {{because 'false_v<requires { requires sizeof(int) == 0; sizeof(Ts); } && requires { requires sizeof(short) == 0; sizeof(Ts); }>' evaluated to false}} 212 struct r4 {}; 213 214 using r4i = r4<int, short>; // expected-error{{constraints not satisfied for class template 'r4' [with Ts = <int, short>]}} 215 216 template<typename... Ts> requires 217 false_v<(requires(Ts t) { requires sizeof(t) == 0; t++; } && ...)> 218 // expected-note@-1 {{because 'false_v<requires (int t) { requires sizeof (t) == 0; t++; } && requires (short t) { requires sizeof (t) == 0; t++; }>' evaluated to false}} 219 struct r5 {}; 220 221 using r5i = r5<int, short>; // expected-error{{constraints not satisfied for class template 'r5' [with Ts = <int, short>]}} 222 223 template<typename T> requires 224 false_v<(requires(T t) { T{t}; })> // T{t} creates an "UnevaluatedList" context. 225 // expected-note@-1 {{because 'false_v<(requires (int t) { int{t}; })>' evaluated to false}} 226 struct r6 {}; 227 228 using r6i = r6<int>; 229 // expected-error@-1 {{constraints not satisfied for class template 'r6' [with T = int]}} 230