Matheus Izvekov b8064374b2
[clang] Instantiate concepts with sugared template arguments
Since we don't unique specializations for concepts, we can just instantiate
them with the sugared template arguments, at negligible cost.

If we don't track their specializations, we can't resugar them later
anyway, and that would be more expensive than just instantiating them
sugared in the first place since it would require an additional pass.

Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>

Differential Revision: https://reviews.llvm.org/D136566
2022-10-27 06:18:53 +02:00

54 lines
2.3 KiB
C++

// RUN: %clang_cc1 -std=c++2a -x c++ %s -verify
static_assert(requires { requires true; });
template<typename T> requires requires { requires false; } // expected-note{{because 'false' evaluated to false}}
struct r1 {};
using r1i = r1<int>; // expected-error{{constraints not satisfied for class template 'r1' [with T = int]}}
template<typename T> requires requires { requires sizeof(T) == 0; } // expected-note{{because 'sizeof(int) == 0' (4 == 0) evaluated to false}}
struct r2 {};
using r2i = r2<int>; // expected-error{{constraints not satisfied for class template 'r2' [with T = int]}}
template<typename T> requires requires (T t) { requires sizeof(t) == 0; } // expected-note{{because 'sizeof (t) == 0' (4 == 0) evaluated to false}}
struct r3 {};
using r3i = r3<int>; // expected-error{{constraints not satisfied for class template 'r3' [with T = int]}}
template<typename T>
struct X {
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'}}
struct r4 {};
};
using r4i = X<void>::r4<int>; // expected-error{{constraints not satisfied for class template 'r4' [with U = int]}}
// C++ [expr.prim.req.nested] Examples
namespace std_example {
template<typename U> concept C1 = sizeof(U) == 1; // expected-note{{because 'sizeof(decltype(+t)) == 1' (4 == 1) evaluated to false}}
template<typename T> concept D =
requires (T t) {
requires C1<decltype (+t)>; // expected-note{{because 'decltype(+t)' (aka 'int') does not satisfy 'C1'}}
};
struct T1 { char operator+() { return 'a'; } };
static_assert(D<T1>);
template<D T> struct D_check {}; // expected-note{{because 'short' does not satisfy 'D'}}
using dc1 = D_check<short>; // expected-error{{constraints not satisfied for class template 'D_check' [with T = short]}}
template<typename T>
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<int>); // expected-note{{because 'int' does not satisfy 'C2'}} expected-error{{static assertion failed}}
}
template<typename T>
concept K = requires (T::Type X) {
X.next();
};