brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.0 KiB · 70a96be Raw
186 lines · cpp
1// RUN: %clang_cc1 -std=c++2a -x c++ %s -verify2 3static_assert(requires { requires true; });4 5template<typename T> requires requires { requires false; } // expected-note{{because 'false' evaluated to false}}6struct r1 {};7 8using r1i = r1<int>; // expected-error{{constraints not satisfied for class template 'r1' [with T = int]}}9 10template<typename T> requires requires { requires sizeof(T) == 0; } // expected-note{{because 'sizeof(int) == 0' (4 == 0) evaluated to false}}11struct r2 {};12 13using r2i = r2<int>; // expected-error{{constraints not satisfied for class template 'r2' [with T = int]}}14 15template<typename T> requires requires (T t) { requires sizeof(t) == 0; } // expected-note{{because 'sizeof (t) == 0' (4 == 0) evaluated to false}}16struct r3 {};17 18using r3i = r3<int>; // expected-error{{constraints not satisfied for class template 'r3' [with T = int]}}19 20template<typename T>21struct X {22    template<typename U> 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'}}23    struct r4 {};24};25 26using r4i = X<void>::r4<int>; // expected-error{{constraints not satisfied for class template 'r4' [with U = int]}}27 28// C++ [expr.prim.req.nested] Examples29namespace std_example {30  template<typename U> concept C1 = sizeof(U) == 1; // expected-note{{because 'sizeof(int) == 1' (4 == 1) evaluated to false}}31  template<typename T> concept D =32    requires (T t) {33      requires C1<decltype (+t)>; // expected-note{{because 'decltype(+t)' (aka 'int') does not satisfy 'C1'}}34  };35 36  struct T1 { char operator+() { return 'a'; } };37  static_assert(D<T1>);38  template<D T> struct D_check {}; // expected-note{{because 'short' does not satisfy 'D'}}39  using dc1 = D_check<short>; // expected-error{{constraints not satisfied for class template 'D_check' [with T = short]}}40 41  template<typename T>42  concept C2 = requires (T a) {43      requires sizeof(a) == 4; // OK44      requires a == 0; // expected-error{{substitution into constraint expression resulted in a non-constant expression}}45      // expected-note@-1{{while checking the satisfaction of nested requirement requested here}}46      // expected-note@-2{{while checking the satisfaction of nested requirement requested here}}47      // expected-note@-5{{while substituting template arguments into constraint expression here}}48      // expected-note@-4{{function parameter 'a' with unknown value cannot be used in a constant expression}}49      // expected-note@-7{{declared here}}50    };51    static_assert(C2<int>); // expected-error{{static assertion failed}}52    // expected-note@-1{{while checking the satisfaction of concept 'C2<int>' requested here}}53    // expected-note@-2{{because 'int' does not satisfy 'C2'}}54}55 56template<typename T>57concept K = requires (T::Type X) {58  X.next();59};60 61namespace SubstitutionFailureNestedRequires {62template<class T>  concept True = true;63template<class T>  concept False = false;64 65struct S { double value; };66 67template <class T>68concept Pipes = requires (T x) {69   requires True<decltype(x.value)> || True<T> || False<T>;70   requires False<T> || True<T> || True<decltype(x.value)>;71};72 73template <class T>74concept Amps1 = requires (T x) {75   requires True<decltype(x.value)> && True<T> && !False<T>; // #Amps176};77template <class T>78concept Amps2 = requires (T x) {79   requires True<T> && True<decltype(x.value)>;80};81 82static_assert(Pipes<S>);83static_assert(Pipes<double>);84 85static_assert(Amps1<S>);86static_assert(Amps1<double>);87 88static_assert(Amps2<S>);89static_assert(Amps2<double>);90 91template<class T>92void foo1() requires requires (T x) {93  requires94  True<decltype(x.value)>95  && True<T>;96} {}97template<class T> void fooPipes() requires Pipes<T> {}98template<class T> void fooAmps1() requires Amps1<T> {}99void foo() {100  foo1<S>();101  foo1<int>();102  fooPipes<S>();103  fooPipes<int>();104  fooAmps1<S>();105  fooAmps1<int>();106}107 108template<class T>109concept HasNoValue = requires (T x) {110  requires !True<decltype(x.value)> && True<T>;111};112// FIXME: 'int' does not satisfy 'HasNoValue' currently since `!True<decltype(x.value)>` is an invalid expression.113// But, in principle, it should be constant-evaluated to true.114// This happens also for requires expression and is not restricted to nested requirement.115static_assert(!HasNoValue<int>);116static_assert(!HasNoValue<S>);117 118template<class T> constexpr bool NotAConceptTrue = true;119template <class T>120concept SFinNestedRequires = requires (T x) {121    // SF in a non-concept specialisation should also be evaluated to false.122   requires NotAConceptTrue<decltype(x.value)> || NotAConceptTrue<T>;123};124static_assert(SFinNestedRequires<int>);125static_assert(SFinNestedRequires<S>);126template <class T>127void foo() requires SFinNestedRequires<T> {}128void bar() {129  foo<int>();130  foo<S>();131}132namespace ErrorExpressions_NotSF {133template<typename T> struct X { static constexpr bool value = T::value; }; // #X_Value134struct True { static constexpr bool value = true; };135struct False { static constexpr bool value = false; };136template<typename T> concept C = true;137template<typename T> concept F = false;138 139template<typename T> requires requires(T) { requires C<T> || X<T>::value; } void foo();140 141template<typename T> requires requires(T) { requires C<T> && X<T>::value; } void bar(); // #bar142template<typename T> requires requires(T) { requires F<T> || (X<T>::value && C<T>); } void baz();143 144void func() {145  foo<True>();146  foo<False>();147  foo<int>();148 149  bar<True>();150  bar<False>();151  // expected-error@-1 {{no matching function for call to 'bar'}}152  // expected-note@#bar {{while substituting template arguments into constraint expression here}}153  // expected-note@#bar {{while checking the satisfaction of nested requirement requested here}}154  // expected-note@#bar {{candidate template ignored: constraints not satisfied [with T = False]}}155  // expected-note@#bar {{because 'X<False>::value' evaluated to false}}156 157  bar<int>();158  // expected-error@-1 {{no matching function for call to 'bar'}} \159  // expected-note@-1 {{while checking constraint satisfaction for template 'bar<int>' required here}} \160  // expected-note@-1 {{while substituting deduced template arguments into function template 'bar' [with T = int]}} \161  // expected-note@#bar {{in instantiation of static data member}}162  // expected-note@#bar {{while checking the satisfaction of nested requirement requested here}}163  // expected-note@#bar {{while substituting template arguments into constraint expression here}}164  // expected-note@#bar {{candidate template ignored}}165  // expected-error@#X_Value {{type 'int' cannot be used prior to '::' because it has no members}}166}167}168}169 170namespace no_crash_D138914 {171// https://reviews.llvm.org/D138914172template <class a, a> struct b;173template <bool c> using d = b<bool, c>;174template <class a, class e> using f = d<__is_same(a, e)>;175template <class a, class e>176concept g = f<a, e>::h;177template <class a, class e>178concept i = g<e, a>;179template <typename> class j {180  template <typename k>181  requires requires { requires i<j, k>; }182  j();183};184template <> j(); // expected-error {{deduction guide declaration without trailing return type}}185}186