// RUN: %clang_cc1 -std=c++2a -x c++ %s -verify static_assert(requires { requires true; }); template requires requires { requires false; } // expected-note{{because 'false' evaluated to false}} struct r1 {}; using r1i = r1; // expected-error{{constraints not satisfied for class template 'r1' [with T = int]}} template requires requires { requires sizeof(T) == 0; } // expected-note{{because 'sizeof(int) == 0' (4 == 0) evaluated to false}} struct r2 {}; using r2i = r2; // expected-error{{constraints not satisfied for class template 'r2' [with T = int]}} template requires requires (T t) { requires sizeof(t) == 0; } // expected-note{{because 'sizeof (t) == 0' (4 == 0) evaluated to false}} struct r3 {}; using r3i = r3; // expected-error{{constraints not satisfied for class template 'r3' [with T = int]}} template struct X { template requires requires (U u) { requires sizeof(u) == sizeof(T); } // expected-note{{because 'sizeof (u) == sizeof(T)' would be invalid: invalid application of 'sizeof' to an incomplete type 'void'}} struct r4 {}; }; using r4i = X::r4; // expected-error{{constraints not satisfied for class template 'r4' [with U = int]}} // C++ [expr.prim.req.nested] Examples namespace std_example { template concept C1 = sizeof(U) == 1; // expected-note{{because 'sizeof(int) == 1' (4 == 1) evaluated to false}} template concept D = requires (T t) { requires C1; // expected-note{{because 'decltype(+t)' (aka 'int') does not satisfy 'C1'}} }; struct T1 { char operator+() { return 'a'; } }; static_assert(D); template struct D_check {}; // expected-note{{because 'short' does not satisfy 'D'}} using dc1 = D_check; // expected-error{{constraints not satisfied for class template 'D_check' [with T = short]}} template concept C2 = requires (T a) { requires sizeof(a) == 4; // OK requires a == 0; // expected-note{{because 'a == 0' would be invalid: constraint variable 'a' cannot be used in an evaluated context}} }; static_assert(C2); // expected-note{{because 'int' does not satisfy 'C2'}} expected-error{{static assertion failed}} } template concept K = requires (T::Type X) { X.next(); }; namespace SubstitutionFailureNestedRequires { template concept True = true; template concept False = false; struct S { double value; }; template concept Pipes = requires (T x) { requires True || True || False; requires False || True || True; }; template concept Amps1 = requires (T x) { requires True && True && !False; // #Amps1 }; template concept Amps2 = requires (T x) { requires True && True; }; static_assert(Pipes); static_assert(Pipes); static_assert(Amps1); static_assert(!Amps1); static_assert(Amps2); static_assert(!Amps2); template void foo1() requires requires (T x) { // #foo1 requires True // #foo1Value && True; } {} template void fooPipes() requires Pipes {} template void fooAmps1() requires Amps1 {} // #fooAmps1 void foo() { foo1(); foo1(); // expected-error {{no matching function for call to 'foo1'}} // expected-note@#foo1Value {{because 'True && True' would be invalid: member reference base type 'int' is not a structure or union}} // expected-note@#foo1 {{candidate template ignored: constraints not satisfied [with T = int]}} fooPipes(); fooPipes(); fooAmps1(); fooAmps1(); // expected-error {{no matching function for call to 'fooAmps1'}} // expected-note@#fooAmps1 {{candidate template ignored: constraints not satisfied [with T = int]}} // expected-note@#fooAmps1 {{because 'int' does not satisfy 'Amps1'}} // expected-note@#Amps1 {{because 'True && True && !False' would be invalid: member reference base type 'int' is not a structure or union}} } template concept HasNoValue = requires (T x) { requires !True && True; }; // FIXME: 'int' does not satisfy 'HasNoValue' currently since `!True` is an invalid expression. // But, in principle, it should be constant-evaluated to true. // This happens also for requires expression and is not restricted to nested requirement. static_assert(!HasNoValue); static_assert(!HasNoValue); template constexpr bool NotAConceptTrue = true; template concept SFinNestedRequires = requires (T x) { // SF in a non-concept specialisation should also be evaluated to false. requires NotAConceptTrue || NotAConceptTrue; }; static_assert(SFinNestedRequires); static_assert(SFinNestedRequires); template void foo() requires SFinNestedRequires {} void bar() { foo(); foo(); } namespace ErrorExpressions_NotSF { template struct X { static constexpr bool value = T::value; }; // #X_Value struct True { static constexpr bool value = true; }; struct False { static constexpr bool value = false; }; template concept C = true; template concept F = false; template requires requires(T) { requires C || X::value; } void foo(); template requires requires(T) { requires C && X::value; } void bar(); // #bar template requires requires(T) { requires F || (X::value && C); } void baz(); void func() { foo(); foo(); foo(); bar(); bar(); // expected-error@-1 {{no matching function for call to 'bar'}} // expected-note@#bar {{while substituting template arguments into constraint expression here}} // expected-note@#bar {{while checking the satisfaction of nested requirement requested here}} // expected-note@#bar {{candidate template ignored: constraints not satisfied [with T = False]}} // expected-note@#bar {{because 'X::value' evaluated to false}} bar(); // expected-note@-1 {{while checking constraint satisfaction for template 'bar' required here}} \ // expected-note@-1 {{in instantiation of function template specialization}} // expected-note@#bar {{in instantiation of static data member}} // expected-note@#bar {{in instantiation of requirement here}} // expected-note@#bar {{while checking the satisfaction of nested requirement requested here}} // expected-note@#bar {{while substituting template arguments into constraint expression here}} // expected-error@#X_Value {{type 'int' cannot be used prior to '::' because it has no members}} } } } namespace no_crash_D138914 { // https://reviews.llvm.org/D138914 template struct b; template using d = b; template using f = d<__is_same(a, e)>; template concept g = f::h; template concept i = g; template class j { template requires requires { requires i; } j(); }; template <> j(); // expected-error {{deduction guide declaration without trailing return type}} }