llvm-project/clang/test/SemaTemplate/concepts.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

54 lines
2.9 KiB
C++
Raw Normal View History

// RUN: %clang_cc1 -std=c++20 -verify %s
namespace PR47043 {
template<typename T> concept True = true;
template<typename ...T> concept AllTrue1 = True<T>; // expected-error {{expression contains unexpanded parameter pack 'T'}}
template<typename ...T> concept AllTrue2 = (True<T> && ...);
static_assert(AllTrue2<int, float, char>);
}
namespace PR47025 {
template<typename ...T> concept AllAddable1 = requires(T ...t) { (void(t + 1), ...); };
template<typename ...T> concept AllAddable2 = (requires(T ...t) { (t + 1); } && ...); // expected-error {{requirement contains unexpanded parameter pack 't'}}
template<typename ...T> concept AllAddable3 = (requires(T t) { (t + 1); } && ...);
template<typename ...T> concept AllAddable4 = requires(T t) { (t + 1); }; // expected-error {{expression contains unexpanded parameter pack 'T'}}
template<typename ...T> concept AllAddable5 = requires(T t) { (void(t + 1), ...); }; // expected-error {{does not contain any unexpanded}}
template<typename ...T> concept AllAddable6 = (requires { (T() + 1); } && ...);
template<typename ...T> concept AllAddable7 = requires { (T() + 1); }; // expected-error {{expression contains unexpanded parameter pack 'T'}}
static_assert(AllAddable1<int, float>);
static_assert(AllAddable3<int, float>);
static_assert(AllAddable6<int, float>);
static_assert(!AllAddable1<int, void>);
static_assert(!AllAddable3<int, void>);
static_assert(!AllAddable6<int, void>);
}
namespace PR45699 {
template<class> concept C = true; // expected-note 2{{here}}
template<class ...Ts> void f1a() requires C<Ts>; // expected-error {{requires clause contains unexpanded parameter pack 'Ts'}}
template<class ...Ts> requires C<Ts> void f1b(); // expected-error {{requires clause contains unexpanded parameter pack 'Ts'}}
template<class ...Ts> void f2a() requires (C<Ts> && ...);
template<class ...Ts> requires (C<Ts> && ...) void f2b();
template<class ...Ts> void f3a() requires C<Ts...>; // expected-error {{pack expansion used as argument for non-pack parameter of concept}}
template<class ...Ts> requires C<Ts...> void f3b(); // expected-error {{pack expansion used as argument for non-pack parameter of concept}}
template<class ...Ts> void f4() {
([] () requires C<Ts> {} ()); // expected-error {{expression contains unexpanded parameter pack 'Ts'}}
([]<int = 0> requires C<Ts> () {} ()); // FIXME: expected-error {{lambda requires '()' before 'requires' clause}} expected-error 0+{{}}
}
template<class ...Ts> void f5() {
([] () requires C<Ts> {} (), ...);
([]<int = 0> requires C<Ts> () {} (), ...); // FIXME: expected-error {{lambda requires '()' before 'requires' clause}} expected-error 0+{{}}
}
void g() {
f1a();
f1b(); // FIXME: Bad error recovery. expected-error {{undeclared identifier}}
f2a();
f2b();
f3a();
f3b(); // FIXME: Bad error recovery. expected-error {{undeclared identifier}}
f4();
f5();
}
}