495 lines · cpp
1// RUN: %clang_cc1 -std=c++2c -verify %s2 3template <class T> concept A = (T(), true);4template <class T> concept C = A<T> && true; // #C5template <class T> concept D = A<T> && __is_same(T, int);6 7 8template <class T> requires (A<T>)9constexpr int f(T) { return 0; };10template <class... T> requires (C<T> && ...)11constexpr int f(T...) { return 1; };12 13static_assert(f(0) == 0);14static_assert(f(1) == 0);15 16 17template <class... T> requires (A<T> && ...)18constexpr int g(T...) { return 0; };19template <class... T> requires (C<T> && ...)20constexpr int g(T...) { return 1; };21 22static_assert(g(0) == 1);23static_assert(g() == 1);24static_assert(g(1, 2) == 1);25 26 27 28template <class... T> requires (A<T> && ...)29constexpr int h(T...) { return 0; }; // expected-note {{candidate}}30template <class... T> requires (C<T> || ...)31constexpr int h(T...) { return 1; }; // expected-note {{candidate}}32 33static_assert(h(0) == 1); // expected-error {{call to 'h' is ambiguous}}34 35template <class... T> requires (A<T> || ...)36constexpr int i(T...) { return 0; }; // expected-note {{candidate}}37template <class... T> requires (C<T> && ...)38constexpr int i(T...) { return 1; }; // expected-note {{candidate}}39 40static_assert(i(0) == 1); // expected-error {{call to 'i' is ambiguous}}41 42 43template <class... T> requires (A<T> || ... || true) constexpr int j(T...) { return 0; }; // #j144template <class... T> requires (C<T> && ... && true) constexpr int j(T...) { return 1; }; // #j245 46static_assert(j(0) == 1);47// expected-error@-1 {{call to 'j' is ambiguous}}48// expected-note@#j1 {{candidate function [with T = <int>]}}49// expected-note@#j2 {{candidate function [with T = <int>]}}50// expected-note@#j2 {{imilar constraint expressions not considered equivalent}}51// expected-note@#j1 {{similar constraint expression here}}52 53 54static_assert(j() == 1);55// expected-error@-1 {{call to 'j' is ambiguous}}56// expected-note@#j1 {{candidate function [with T = <>]}}57// expected-note@#j2 {{candidate function [with T = <>]}}58// expected-note@#j2 {{imilar constraint expressions not considered equivalent}}59// expected-note@#j1 {{similar constraint expression here}}60 61 62 63template <class... T> requires (A<T> || ...)64constexpr int k(T...) { return 0; }; // expected-note {{candidate template ignored: constraints not satisfied [with T = <>]}}65template <class... T> requires (C<T> || ...)66constexpr int k(T...) { return 1; }; // expected-note {{candidate template ignored: constraints not satisfied [with T = <>]}}67 68static_assert(k(0) == 1);69static_assert(k() == 0); // expected-error {{no matching function for call to 'k'}}70static_assert(k(1, 2) == 1);71 72 73consteval int terse(A auto...) {return 1;}74consteval int terse(D auto...) {return 2;}75 76static_assert(terse() == 2);77static_assert(terse(0, 0) == 2);78static_assert(terse(0L, 0) == 1);79 80template <A... T>81consteval int tpl_head(A auto...) {return 1;}82template <D... T>83consteval int tpl_head(D auto...) {return 2;}84 85static_assert(tpl_head() == 2);86static_assert(tpl_head(0, 0) == 2);87static_assert(tpl_head(0L, 0) == 1);88 89 90namespace equivalence {91 92template <typename... T>93struct S {94 template <typename... U>95 void f() requires (A<U> && ...);96 template <typename... U>97 void f() requires (C<U> && ...);98 99 template <typename... U>100 void g() requires (A<T> && ...);101 template <typename... U>102 void g() requires (C<T> && ...);103 104 template <typename... U>105 void h() requires (A<U> && ...); // expected-note {{candidate}}106 template <typename... U>107 void h() requires (C<T> && ...); // expected-note {{candidate}}108};109 110void test() {111 S<int>{}.f<int>();112 S<int>{}.g<int>();113 S<int>{}.h<int>(); // expected-error {{call to member function 'h' is ambiguous}}114}115 116 117}118 119namespace substitution {120struct S {121 using type = int;122};123 124template <typename... T>125consteval int And1() requires (C<typename T::type> && ...) { // #and1126 return 1;127}128 129template <typename T, typename... U>130consteval int And2() requires (C<typename U::type> && ... && C<typename T::type>) { // #and2131 return 2;132}133 134template <typename T, typename... U>135consteval int And3() requires (C<typename T::type> && ... && C<typename U::type>) { // #and3136 return 3;137}138 139template <typename... T>140consteval int Or1() requires (C<typename T::type> || ...) { // #or1141 return 1;142}143 144template <typename T, typename... U>145consteval int Or2() requires (C<typename U::type> || ... || C<typename T::type>) { // #or2146 return 2;147}148 149template <typename T, typename... U>150consteval int Or3() requires (C<typename T::type> || ... || C<typename U::type>) { // #or3151 return 3;152}153 154static_assert(And1<>() == 1);155static_assert(And1<S>() == 1);156static_assert(And1<S, S>() == 1);157// FIXME: The diagnostics are not so great158static_assert(And1<int>() == 1); // expected-error {{no matching function for call to 'And1'}}159 // expected-note@#and1 {{candidate template ignored: constraints not satisfied [with T = <int>]}}160 // expected-note@#and1 {{because substituted constraint expression is ill-formed: type 'int' cannot be used prior to '::' because it has no members}}161 162static_assert(And1<S, int>() == 1); // expected-error {{no matching function for call to 'And1'}}163 // expected-note@#and1 {{candidate template ignored: constraints not satisfied [with T = <S, int>]}}164 // expected-note@#and1 {{because substituted constraint expression is ill-formed: type 'int' cannot be used prior to '::' because it has no members}}165 166static_assert(And1<int, S>() == 1); // expected-error {{no matching function for call to 'And1'}}167 // expected-note@#and1 {{candidate template ignored: constraints not satisfied [with T = <int, S>]}}168 // expected-note@#and1 {{because substituted constraint expression is ill-formed: type 'int' cannot be used prior to '::' because it has no members}}169 170static_assert(And2<S>() == 2);171static_assert(And2<S, S>() == 2);172static_assert(And2<int>() == 2); // expected-error {{no matching function for call to 'And2'}}173 // expected-note@#and2 {{candidate template ignored: constraints not satisfied [with T = int, U = <>]}}174 // expected-note@#and2 {{because substituted constraint expression is ill-formed: type 'int' cannot be used prior to '::' because it has no members}}175 176 177static_assert(And2<int, int>() == 2); // expected-error {{no matching function for call to 'And2'}}178 // expected-note@#and2 {{candidate template ignored: constraints not satisfied [with T = S, U = <int>]}} \179 // expected-note@#and2 {{because substituted constraint expression is ill-formed: type 'int' cannot be used prior to '::' because it has no members}}180 181static_assert(And2<S, int>() == 2); // expected-error {{no matching function for call to 'And2'}}182 // expected-note@#and2 {{candidate template ignored: constraints not satisfied [with T = int, U = <S>]}}183 // expected-note@#and2 {{because substituted constraint expression is ill-formed: type 'int' cannot be used prior to '::' because it has no members}}184 185static_assert(And2<int, S>() == 2); // expected-error {{no matching function for call to 'And2'}}186 // expected-note@#and2 {{candidate template ignored: constraints not satisfied [with T = int, U = <int>]}}187 // expected-note@#and2 {{because substituted constraint expression is ill-formed: type 'int' cannot be used prior to '::' because it has no members}}188 189static_assert(And3<S>() == 3);190static_assert(And3<S, S>() == 3);191static_assert(And3<int>() == 3); // expected-error {{no matching function for call to 'And3'}}192 // expected-note@#and3 {{candidate template ignored: constraints not satisfied [with T = int, U = <>]}}193 // expected-note@#and3 {{because substituted constraint expression is ill-formed: type 'int' cannot be used prior to '::' because it has no members}}194 195 196static_assert(And3<int, int>() == 3); // expected-error {{no matching function for call to 'And3'}}197 // expected-note@#and3 {{candidate template ignored: constraints not satisfied [with T = int, U = <int>]}}198 // expected-note@#and3 {{because substituted constraint expression is ill-formed: type 'int' cannot be used prior to '::' because it has no members}}199 200 201static_assert(And3<S, int>() == 3); // expected-error {{no matching function for call to 'And3'}}202 // expected-note@#and3 {{candidate template ignored: constraints not satisfied [with T = S, U = <int>]}}203 // expected-note@#and3 {{because substituted constraint expression is ill-formed: type 'int' cannot be used prior to '::' because it has no members}}204 205 206static_assert(And3<int, S>() == 3); // expected-error {{no matching function for call to 'And3'}}207 // expected-note@#and3 {{candidate template ignored: constraints not satisfied [with T = int, U = <S>]}}208 // expected-note@#and3 {{because substituted constraint expression is ill-formed: type 'int' cannot be used prior to '::' because it has no members}}209 210 211static_assert(Or1<>() == 1); // expected-error {{no matching function for call to 'Or1'}}212 // expected-note@#or1 {{candidate template ignored: constraints not satisfied}}213static_assert(Or1<S>() == 1);214static_assert(Or1<int, S>() == 1);215static_assert(Or1<S, int>() == 1);216static_assert(Or1<S, S>() == 1);217static_assert(Or1<int>() == 1); // expected-error {{no matching function for call to 'Or1'}}218 // expected-note@#or1 {{candidate template ignored: constraints not satisfied}}219 // expected-note@#or1 {{because substituted constraint expression is ill-formed: type 'int' cannot be used prior to '::' because it has no members}}220 221static_assert(Or2<S>() == 2);222static_assert(Or2<int, S>() == 2);223static_assert(Or2<S, int>() == 2);224static_assert(Or2<S, S>() == 2);225static_assert(Or2<int>() == 2); // expected-error {{no matching function for call to 'Or2'}}226 // expected-note@#or2 {{candidate template ignored: constraints not satisfied [with T = int, U = <>]}}227 // expected-note@#or2 {{because substituted constraint expression is ill-formed: type 'int' cannot be used prior to '::' because it has no members}}228static_assert(Or3<S>() == 3);229static_assert(Or3<int, S>() == 3);230static_assert(Or3<S, int>() == 3);231static_assert(Or3<S, S>() == 3);232static_assert(Or3<int>() == 3); // expected-error {{no matching function for call to 'Or3'}}233 // expected-note@#or3 {{candidate template ignored: constraints not satisfied}}234 // expected-note@#or3 {{because substituted constraint expression is ill-formed: type 'int' cannot be used prior to '::' because it has no members}}235}236 237namespace bool_conversion_break {238 239template <typename ...V> struct A;240struct Thingy {241 static constexpr int compare(const Thingy&) {return 1;}242};243template <typename ...T, typename ...U>244void f(A<T ...> *, A<U ...> *) // expected-note {{candidate template ignored: constraints not satisfied}}245requires (T::compare(U{}) && ...); // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}246 247void g() {248 A<Thingy, Thingy> *ap;249 f(ap, ap); // expected-error{{no matching function for call to 'f'}} \250 // expected-note {{while checking constraint satisfaction}} \251 // expected-note {{while substituting deduced template arguments}}252}253 254}255 256namespace nested {257 258template <typename... T>259struct S {260 template <typename... U>261 consteval static int f()262 requires ((A<T> && ...) && ... && A<U> ) {263 return 1;264 }265 266 template <typename... U>267 consteval static int f()268 requires ((C<T> && ...) && ... && C<U> ) {269 return 2;270 }271 272 template <typename... U>273 consteval static int g() // #nested-ambiguous-g1274 requires ((A<T> && ...) && ... && A<U> ) {275 return 1;276 }277 278 template <typename... U>279 consteval static int g() // #nested-ambiguous-g2280 requires ((C<U> && ...) && ... && C<T> ) {281 return 2;282 }283};284 285static_assert(S<int>::f<int>() == 2);286 287static_assert(S<int>::g<int>() == 2);288 289 290}291 292namespace GH99430 {293 294template <class _Ty1, class _Ty2>295using _Synth_three_way_result = int;296 297template <class... _Types>298class tuple;299 300template <int _Index>301struct tuple_element;302 303template <class, int...>304struct _Three_way_comparison_result_with_tuple_like {305 using type = int;306};307 308template <class... _TTypes, int... _Indices>309 requires(requires {310 typename _Synth_three_way_result<_TTypes, tuple_element<_Indices>>;311 } && ...)312 313struct _Three_way_comparison_result_with_tuple_like<tuple<_TTypes...>, _Indices...>{314 using type = long;315};316 317static_assert(__is_same_as(_Three_way_comparison_result_with_tuple_like<tuple<int>, 0, 1>::type, int));318static_assert(__is_same_as(_Three_way_comparison_result_with_tuple_like<tuple<int>, 0>::type, long));319 320}321 322namespace GH88866 {323 324template <typename...Ts> struct index_by;325 326template <typename T, typename Indices>327concept InitFunc = true;328 329namespace ExpandsBoth {330 331template <typename Indices, InitFunc<Indices> auto... init>332struct LazyLitMatrix; // expected-note {{here}}333 334template <335 typename...Indices,336 InitFunc<index_by<Indices>> auto... init337>338struct LazyLitMatrix<index_by<Indices...>, init...> {339};340 341// FIXME: Explain why we didn't pick up the partial specialization - pack sizes don't match.342template struct LazyLitMatrix<index_by<int, char>, 42>;343// expected-error@-1 {{instantiation of undefined template}}344template struct LazyLitMatrix<index_by<int, char>, 42, 43>;345 346}347 348namespace ExpandsRespectively {349 350template <typename Indices, InitFunc<Indices> auto... init>351struct LazyLitMatrix;352 353template <354 typename...Indices,355 InitFunc<index_by<Indices...>> auto... init356>357struct LazyLitMatrix<index_by<Indices...>, init...> {358};359 360template struct LazyLitMatrix<index_by<int, char>, 42>;361template struct LazyLitMatrix<index_by<int, char>, 42, 43>;362 363}364 365namespace TypeParameter {366 367template <typename Indices, InitFunc<Indices>... init>368struct LazyLitMatrix; // expected-note {{here}}369 370template <371 typename...Indices,372 InitFunc<index_by<Indices>>... init373>374struct LazyLitMatrix<index_by<Indices...>, init...> {375};376 377// FIXME: Explain why we didn't pick up the partial specialization - pack sizes don't match.378template struct LazyLitMatrix<index_by<int, char>, float>;379// expected-error@-1 {{instantiation of undefined template}}380template struct LazyLitMatrix<index_by<int, char>, unsigned, float>;381 382}383 384namespace Invalid {385 386template <typename Indices, InitFunc<Indices>... init>387struct LazyLitMatrix;388 389template <390 typename...Indices,391 InitFunc<index_by<Indices>> init392 // expected-error@-1 {{unexpanded parameter pack 'Indices'}}393>394struct LazyLitMatrix<index_by<Indices...>, init> {395};396 397}398 399}400 401namespace GH135190 {402template <typename T>403concept A = __is_same_as(T, int) || __is_same_as(T, double) ;404 405template <typename T>406concept B = A<T> && __is_same_as(T, double);407 408template <class... Ts>409requires(A<Ts> && ...)410constexpr int g() {411 return 1;412}413 414template <class... Ts>415requires(B<Ts> && ...)416constexpr int g() {417 return 2;418}419 420static_assert(g<double>() == 2);421 422 423template <class... Ts>424concept all_A = (A<Ts> && ...);425 426template <class... Ts>427concept all_B = (B<Ts> && ...);428 429template <class... Ts>430requires all_A<Ts...>431constexpr int h() {432 return 1;433}434 435template <class... Ts>436requires all_B<Ts...>437constexpr int h() {438 return 2;439}440 441static_assert(h<double>() == 2);442}443 444 445namespace parameter_mapping_regressions {446 447namespace case1 {448namespace std {449template <class _Tp, class... _Args>450constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...);451template <class _Tp, class... _Args>452concept constructible_from = is_constructible_v<_Tp, _Args...>;453template <class _Tp>454concept default_initializable = true;455template <class> using iterator_t = int;456template <class _Tp>457concept view = constructible_from<_Tp, _Tp>;458template <class... _Views>459 requires(view<_Views> && ...)460class zip_transform_view;461} // namespace std462struct IterDefaultCtrView {};463template <class... Views>464using Iter = std::iterator_t<std::zip_transform_view<Views...>>;465static_assert(466 std::default_initializable<Iter<IterDefaultCtrView, IterDefaultCtrView>>);467 468}469 470namespace case2 {471 472template <class _Bp>473constexpr bool False = false;474 475template <class... _Views>476concept __zip_all_random_access = (False<_Views> && ...);477// expected-note@-1 {{evaluated to false}}478 479template <typename... _Views>480struct zip_view {481 void f() requires __zip_all_random_access<_Views...>{};482 // expected-note@-1 {{because 'int' does not satisfy}}483};484 485zip_view<int> test_v;486static_assert(!__zip_all_random_access<int>);487 488void test() {489 test_v.f(); // expected-error {{invalid reference to function 'f'}}490}491 492}493 494}495