// RUN: %clang_cc1 -std=c++2a -x c++ %s -verify static_assert(requires { { 0 }; }); static_assert(requires { { "aaaa" }; }); static_assert(requires { { (0).da }; }); // expected-error{{member reference base type 'int' is not a structure or union}} void foo() {} static_assert(requires { { foo() }; }); // Substitution failure in expression struct A {}; struct B { B operator+(const B &other) const { return other; } }; struct C { C operator+(C &other) const { return other; } }; template requires requires (T a, const T& b) { { a + b }; } // expected-note{{because 'a + b' would be invalid: invalid operands to binary expression ('A' and 'const A')}} expected-note{{because 'a + b' would be invalid: invalid operands to binary expression ('C' and 'const C')}} struct r1 {}; using r1i1 = r1; using r1i2 = r1; // expected-error{{constraints not satisfied for class template 'r1' [with T = A]}} using r1i3 = r1; using r1i4 = r1; // expected-error{{constraints not satisfied for class template 'r1' [with T = C]}} struct D { void foo() {} }; template requires requires (T a) { { a.foo() }; } // expected-note{{because 'a.foo()' would be invalid: no member named 'foo' in 'A'}} expected-note{{because 'a.foo()' would be invalid: member reference base type 'int' is not a structure or union}} expected-note{{because 'a.foo()' would be invalid: 'this' argument to member function 'foo' has type 'const D', but function is not marked const}} struct r2 {}; using r2i1 = r2; // expected-error{{constraints not satisfied for class template 'r2' [with T = int]}} using r2i2 = r2; // expected-error{{constraints not satisfied for class template 'r2' [with T = A]}} using r2i3 = r2; using r2i4 = r2; // expected-error{{constraints not satisfied for class template 'r2' [with T = const D]}} template requires requires { { sizeof(T) }; } // expected-note{{because 'sizeof(T)' would be invalid: invalid application of 'sizeof' to an incomplete type 'void'}} expected-note{{because 'sizeof(T)' would be invalid: invalid application of 'sizeof' to an incomplete type 'nonexistent'}} struct r3 {}; using r3i1 = r3; using r3i2 = r3; using r3i3 = r3; using r3i4 = r3; // expected-error{{constraints not satisfied for class template 'r3' [with T = void]}} using r3i4 = r3; // expected-error{{constraints not satisfied for class template 'r3' [with T = nonexistent]}} // Non-dependent expressions template requires requires (T t) { { 0 }; { "a" }; { (void)'a' }; } struct r4 {}; using r4i1 = r4; using r4i2 = r4; using r4i3 = r4; // Noexcept requirement void maythrow() { } static_assert(!requires { { maythrow() } noexcept; }); static_assert(requires { { 1 } noexcept; }); struct E { void operator++(int) noexcept; }; struct F { void operator++(int); }; template requires requires (T t) { { t++ } noexcept; } // expected-note{{because 't ++' may throw an exception}} struct r5 {}; using r5i1 = r5; using r5i2 = r5; using r5i2 = r5; // expected-error{{constraints not satisfied for class template 'r5' [with T = F]}} template requires requires (T t) { { t.foo() } noexcept; } // expected-note{{because 't.foo()' would be invalid: no member named 'foo' in 'E'}} struct r6 {}; using r6i = r6; // expected-error{{constraints not satisfied for class template 'r6' [with T = E]}} template constexpr bool is_same_v = false; template constexpr bool is_same_v = true; template concept Same = is_same_v; template concept Large = sizeof(T) >= 4; // expected-note{{because 'sizeof(short) >= 4' (2 >= 4) evaluated to false}} template requires requires (T t) { { t } -> Large; } // expected-note{{because 'decltype(t)' (aka 'short') does not satisfy 'Large':}} struct r7 {}; using r7i1 = r7; using r7i2 = r7; // expected-error{{constraints not satisfied for class template 'r7' [with T = short]}} template requires requires (T t) { { t } -> Same; } struct r8 {}; using r8i1 = r8; using r8i2 = r8; // Substitution failure in type constraint template requires requires (T t) { { t } -> Same; } // expected-note{{because 'Same' would be invalid: type 'int' cannot be used prior to '::' because it has no members}} struct r9 {}; struct M { using type = M; }; using r9i1 = r9; using r9i2 = r9; // expected-error{{constraints not satisfied for class template 'r9' [with T = int]}} // Substitution failure in both expression and return type requirement template requires requires (T t) { { t.foo() } -> Same; } // expected-note{{because 't.foo()' would be invalid: member reference base type 'int' is not a structure or union}} struct r10 {}; using r10i = r10; // expected-error{{constraints not satisfied for class template 'r10' [with T = int]}} // Non-type concept in type constraint template concept IsEven = (T % 2) == 0; template requires requires (T t) { { t } -> IsEven; } // expected-error{{concept named in type constraint is not a type concept}} struct r11 {}; // C++ [expr.prim.req.compound] Example namespace std_example { template concept C1 = requires(T x) { {x++}; }; template constexpr bool is_same_v = false; template constexpr bool is_same_v = true; template concept same_as = is_same_v; // expected-note@-1 {{because 'is_same_v' evaluated to false}} static_assert(C1); static_assert(C1); template struct C1_check {}; using c1c1 = C1_check; using c1c2 = C1_check; template concept C2 = requires(T x) { {*x} -> same_as; // expected-note@-1{{because type constraint 'same_as' was not satisfied:}} // expected-note@-2{{because '*x' would be invalid: indirection requires pointer operand ('int' invalid)}} }; struct T1 { using inner = int; inner operator *() { return 0; } }; struct T2 { using inner = int *; int operator *() { return 0; } }; static_assert(C2); template struct C2_check {}; // expected-note{{because 'int' does not satisfy 'C2'}} expected-note{{because 'std_example::T2' does not satisfy 'C2'}} using c2c1 = C2_check; // expected-error{{constraints not satisfied for class template 'C2_check' [with T = int]}} using c2c2 = C2_check; // expected-error{{constraints not satisfied for class template 'C2_check' [with T = std_example::T2]}} template void g(T t) noexcept(sizeof(T) == 1) {} template concept C5 = requires(T x) { {g(x)} noexcept; // expected-note{{because 'g(x)' may throw an exception}} }; static_assert(C5); template struct C5_check {}; // expected-note{{because 'short' does not satisfy 'C5'}} using c5 = C5_check; // expected-error{{constraints not satisfied for class template 'C5_check' [with T = short]}} }