| // 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> () {} ()); // expected-error {{expression contains unexpanded parameter pack 'Ts'}} |
| } |
| template<class ...Ts> void f5() { |
| ([] () requires C<Ts> {} (), ...); |
| ([]<int = 0> requires C<Ts> () {} (), ...); |
| } |
| 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(); |
| } |
| } |
| |
| namespace P0857R0 { |
| void f() { |
| auto x = []<bool B> requires B {}; // expected-note {{constraints not satisfied}} expected-note {{false}} |
| x.operator()<true>(); |
| x.operator()<false>(); // expected-error {{no matching member function}} |
| } |
| |
| // FIXME: This is valid under P0857R0. |
| template<typename T> concept C = true; |
| template<template<typename T> requires C<T> typename U> struct X {}; // expected-error {{requires 'class'}} expected-error 0+{{}} |
| template<typename T> requires C<T> struct Y {}; |
| X<Y> xy; // expected-error {{no template named 'X'}} |
| } |