437 lines · cpp
1// RUN: %clang_cc1 -std=c++2c -verify %s2 3namespace Errors {4 5template <template<typename T> auto>6struct S1;7template <template<auto T> auto>8struct S2;9template <template<typename T> concept>10struct S3;11template <template<auto T> concept>12struct S4;13int a;14 15template <typename T>16concept C = true; // expected-note 2{{template argument refers to a concept 'C', here}}17template <typename T>18auto Var = 0; // expected-note 2{{template argument refers to a variable template 'Var', here}}19 20S1<1> t1; // expected-error {{template argument for template template parameter must be a variable template}}21S1<a> t2; // expected-error {{template argument for template template parameter must be a variable template}}22S1<int> t3; // expected-error {{template argument for template template parameter must be a variable template}}23S1<C> t4; // expected-error {{template argument does not refer to a variable template, or template template parameter}}24S2<1> t5; // expected-error {{template argument for template template parameter must be a variable template}}25S2<a> t6; // expected-error {{template argument for template template parameter must be a variable template}}26S2<int> t7; // expected-error {{template argument for template template parameter must be a variable template}}27S2<C> t8; // expected-error {{template argument does not refer to a variable template, or template template parameter}}28S3<1> t9; // expected-error {{template argument for template template parameter must be a concept}}29S3<a> t10; // expected-error {{template argument for template template parameter must be a concept}}30S3<int> t11; // expected-error {{template argument for template template parameter must be a concept}}31S3<Var> t12; // expected-error {{template argument does not refer to a concept, or template template parameter}}32S4<1> t13; // expected-error {{template argument for template template parameter must be a concept}}33S4<a> t14; // expected-error {{template argument for template template parameter must be a concept}}34S4<int> t15; // expected-error {{template argument for template template parameter must be a concept}}35S4<Var> t16; // expected-error {{template argument does not refer to a concept, or template template parameter}}36 37}38 39template <template<typename T> auto V> // expected-note {{previous template template parameter is here}} \40 // expected-error{{template argument for non-type template parameter must be an expression}}41struct S1 {42 static_assert(V<int> == 42);43 static_assert(V<const int> == 84);44 static_assert(V<double> == 0);45};46template <template<auto T> auto V> // expected-error {{template argument for template type parameter must be a type}} \47 // expected-note {{previous template template parameter is here}}48struct S2 {49 static_assert(V<0> == 1);50 static_assert(V<1> == 0);51};52template <template<typename T> concept C > // expected-error {{template argument for non-type template parameter must be an expression}} \53 // expected-note {{previous template template parameter is here}}54struct S3 {55 static_assert(C<int>);56};57template <template<auto> concept C> // expected-error {{template argument for template type parameter must be a type}} \58 // expected-note {{previous template template parameter is here}}59struct S4 {60 static_assert(C<0>);61};62 63template <typename T> // expected-note {{template parameter is declared here}}64concept C = true;65 66template <auto I> // expected-note {{template parameter is declared here}}67concept CI = true;68 69template <typename T> // expected-note {{template parameter is declared here}}70constexpr auto Var = 42;71template <typename T>72constexpr auto Var<const T> = 84;73template <>74constexpr auto Var<double> = 0;75 76template <auto N> // expected-note {{template parameter is declared here}}77constexpr auto Var2 = 0;78template <auto N>79requires (N%2 == 0)80constexpr auto Var2<N> = 1;81 82void test () {83 S1<Var2> sE; // expected-note {{template template argument has different template parameters than its corresponding template template parameter}}84 S2<Var> sE; // expected-note {{template template argument has different template parameters than its corresponding template template parameter}}85 S1<Var> s1;86 S2<Var2> s2;87 S3<C> s3;88 S4<C> sE; // expected-note {{template template argument has different template parameters than its corresponding template template parameter}}89 S4<CI> s4;90 S3<CI> sE; // expected-note {{template template argument has different template parameters than its corresponding template template parameter}}91}92 93 94namespace template_type_constraints {95 96 97template <typename T>98concept Unary = true;99template <typename T, typename = int>100concept BinaryDefaulted = true;101 102template <typename T>103concept UnaryFalse = false; // expected-note 3{{because 'false' evaluated to false}}104template <typename T, typename = int>105concept BinaryDefaultedFalse = false;106 107template <template <typename...> concept C, typename T>108struct S {109 template <C TT> // expected-note 2{{because 'int' does not satisfy 'UnaryFalse'}}110 void f(TT); // expected-note {{ignored}}111 void g(C auto); // expected-note {{ignored}} \112 // expected-note {{because 'int' does not satisfy 'UnaryFalse'}}113 114 auto h() -> C auto { // expected-error {{deduced type 'int' does not satisfy 'UnaryFalse'}}115 return 0;116 };117 118 void test() {119 C auto a = 0;120 }121};122 123template <template <typename...> concept C, typename T>124struct SArg {125 template <C<int> TT>126 void f(TT);127 void g(C<int> auto);128 129 auto h() -> C<int> auto {130 return 0;131 };132 void test() {133 C<int> auto a = 0;134 }135};136 137void test() {138 S<Unary, int> s;139 s.f(0);140 s.g(0);141 s.h();142 S<BinaryDefaulted, int> s2;143 s2.f(0);144 s2.g(0);145 s2.h();146 147 SArg<BinaryDefaulted, int> s3;148 s3.f(0);149 s3.g(0);150 s3.h();151}152 153void test_errors() {154 S<UnaryFalse, int> s;155 s.f(0); // expected-error {{no matching member function for call to 'f'}}156 s.g(0); // expected-error {{no matching member function for call to 'g'}}157 s.h(); // expected-note {{in instantiation of member function 'template_type_constraints::S<template_type_constraints::UnaryFalse, int>::h'}}158}159 160}161 162template <typename T>163concept Unary = true;164template <typename T, typename = int>165concept BinaryDefaulted = true;166 167template <typename T>168concept UnaryFalse = false; // expected-note 3{{because 'false' evaluated to false}}169template <typename T, typename = int>170concept BinaryDefaultedFalse = false;171 172template <template <typename...> concept C, typename T>173struct S {174 template <C TT> // expected-note 2{{because 'int' does not satisfy 'UnaryFalse'}}175 void f(TT); // expected-note {{ignored}}176 void g(C auto); // expected-note {{ignored}} \177 // expected-note {{because 'int' does not satisfy 'UnaryFalse'}}178 179 auto h() -> C auto { // expected-error {{deduced type 'int' does not satisfy 'UnaryFalse'}}180 return 0;181 };182 183 void test() {184 C auto a = 0;185 }186};187 188template <template <typename...> concept C, typename T>189struct SArg {190 template <C<int> TT>191 void f(TT);192 void g(C<int> auto);193 194 auto h() -> C<int> auto {195 return 0;196 };197 void test() {198 C<int> auto a = 0;199 }200};201 202void test_args() {203 S<Unary, int> s;204 s.f(0);205 s.g(0);206 s.h();207 S<BinaryDefaulted, int> s2;208 s2.f(0);209 s2.g(0);210 s2.h();211 212 SArg<BinaryDefaulted, int> s3;213 s3.f(0);214 s3.g(0);215 s3.h();216}217 218void test_errors() {219 S<UnaryFalse, int> s;220 s.f(0); // expected-error {{no matching member function for call to 'f'}}221 s.g(0); // expected-error {{no matching member function for call to 'g'}}222 s.h(); // expected-note {{in instantiation of member function 'S<UnaryFalse, int>::h'}}223}224 225namespace non_type {226 227template <auto>228concept Unary = true;229 230template <template <auto> concept C>231struct S {232 template <C Foo> // expected-error {{concept named in type constraint is not a type concept}}233 void f();234 // FIXME, bad diagnostic235 void g(C auto); // expected-error{{concept named in type constraint is not a type concept}}236 auto h() -> C auto { // expected-error{{concept named in type constraint is not a type concept}}237 }238 void i() {239 C auto a = 0; // expected-error{{concept named in type constraint is not a type concept}}240 }241};242 243}244 245namespace default_args {246 247template <typename T>248concept Concept = false; // expected-note 2{{template argument refers to a concept 'Concept', here}} \249 // expected-note 2{{because 'false' evaluated to false}}250 251template <typename T>252constexpr auto Var = false; // expected-note 2{{template argument refers to a variable template 'Var', here}}253 254template <typename T>255struct Type; // expected-note 2{{template argument refers to a class template 'Type', here}}256 257 258template <template <typename> auto = Concept> // expected-error {{template argument does not refer to a variable template, or template template parameter}}259struct E1;260 261template <template <typename> auto = Type> // expected-error {{template argument does not refer to a variable template, or template template parameter}}262struct E2;263 264template <template <typename> typename = Concept> // expected-error {{template argument does not refer to a class or alias template, or template template parameter}}265struct E3;266 267template <template <typename> typename = Var> // expected-error {{template argument does not refer to a class or alias template, or template template parameter}}268struct E4;269 270template <template <typename> concept = Var> // expected-error {{template argument does not refer to a concept, or template template parameter}}271struct E4;272 273template <template <typename> concept = Type> // expected-error {{template argument does not refer to a concept, or template template parameter}}274struct E4;275 276template <277 template <typename> concept TConcept, // expected-note 2{{template argument refers to a concept 'TConcept', here}}278 template <typename> auto TVar, // expected-note 2{{template argument refers to a variable template 'TVar', here}}279 template <typename> typename TType // expected-note 2{{template argument refers to a class template 'TType', here}}280>281struct Nested {282 template <template <typename> auto = TConcept> // expected-error {{template argument does not refer to a variable template, or template template parameter}}283 struct E1;284 285 template <template <typename> auto = TType> // expected-error {{template argument does not refer to a variable template, or template template parameter}}286 struct E2;287 288 template <template <typename> typename = TConcept> // expected-error {{template argument does not refer to a class or alias template, or template template parameter}}289 struct E3;290 291 template <template <typename> typename = TVar> // expected-error {{template argument does not refer to a class or alias template, or template template parameter}}292 struct E4;293 294 template <template <typename> concept = TVar> // expected-error {{template argument does not refer to a concept, or template template parameter}}295 struct E4;296 297 template <template <typename> concept = TType> // expected-error {{template argument does not refer to a concept, or template template parameter}}298 struct E4;299};300 301 302template <template <typename> concept C = Concept>303struct TestDefaultConcept {304 template <template <typename> concept CC = C>305 void f() {306 static_assert(C<int>); // expected-error {{static assertion failed}} \307 // expected-note {{because 'int' does not satisfy 'Concept'}}308 static_assert(CC<int>); // expected-error {{static assertion failed}} \309 // expected-note {{because 'int' does not satisfy 'Concept'}}310 }311};312void do_test_concept() {313 TestDefaultConcept<>{}.f(); // expected-note {{in instantiation}}314}315 316template <template <typename> auto V = Var>317struct TestDefaultVar {318 template <template <typename> auto VV = V>319 void f() {320 static_assert(V<int>); // expected-error {{static assertion failed}}321 static_assert(VV<int>); // expected-error {{static assertion failed}}322 }323};324void do_test_var() {325 TestDefaultVar<>{}.f(); // expected-note {{in instantiation}}326}327 328}329 330namespace TTPDependence {331template <template <typename... > concept C>332concept A = C<>;333template <template <typename... > concept C>334concept B = C<int>;335 336template <template <typename... > auto Var>337concept C = Var<>;338template <template <typename... > auto Var>339concept D = Var<int>;340 341}342 343namespace InvalidName {344template <typename T, template <typename> concept C>345concept A = C<T>; // expected-note {{here}}346 347template <A<concept missing<int>> T> // expected-error {{expected expression}} \348 // expected-error {{too few template arguments for concept 'A'}} \349 // expected-error {{unknown type name 'T'}} \350 // expected-error {{expected unqualified-id}}351auto f();352}353 354namespace concept_arg_normalization {355 356template <typename T,357 template <typename...> concept C1>358concept one = (C1<T>); // #concept-arg-one359 360template <typename T>361concept A = true; // #concept-arg-A362 363template <typename T>364concept BetterA = A<T> && true;365 366template <typename T>367concept B = true; // #concept-arg-B368 369template <typename T>370concept False = false; // #concept-arg-False371 372template <typename T>373requires one<T, A>374void f1(T){} // #concept-arg-f1-1375 376template <typename T>377requires one<T, B>378void f1(T){} // #concept-arg-f1-2379 380template <typename T>381requires one<T, A>382void f2(T){}383 384template <typename T>385requires one<T, BetterA>386void f2(T){}387 388 389template <template <typename> concept CT>390requires one<int, A>391void f3(){} // #concept-arg-f3-1392 393template <template <typename> concept CT>394requires one<int, CT>395void f3(){} // #concept-arg-f3-2396 397template <typename T>398requires one<T, False> void f4(T){} // #concept-arg-f4399 400 401void test() {402 f1(0);403 // expected-error@-1 {{call to 'f1' is ambiguous}}404 // expected-note@#concept-arg-f1-1{{candidate function [with T = int]}}405 // expected-note@#concept-arg-f1-2{{candidate function [with T = int]}}406 // expected-note@#concept-arg-A {{similar constraint expressions not considered equivalent}}407 // expected-note@#concept-arg-B {{similar constraint expression here}}408 f2(0);409 410 f3<BetterA>();411 // expected-error@-1 {{call to 'f3' is ambiguous}}412 // expected-note@#concept-arg-f3-1 {{candidate function [with CT = concept_arg_normalization::BetterA]}}413 // expected-note@#concept-arg-f3-2 {{candidate function [with CT = concept_arg_normalization::BetterA]}}414 415static_assert(one<int, A>);416static_assert(one<int, False>);417// expected-error@-1 {{static assertion failed}} \418// expected-note@-1 {{because 'one<int, False>' evaluated to false}}419// expected-note@#concept-arg-one {{because 'int' does not satisfy 'False'}}420// expected-note@#concept-arg-False {{because 'false' evaluated to false}}421 422f4(0);423// expected-error@-1 {{no matching function for call to 'f4'}}424// expected-note@#concept-arg-f4 {{candidate template ignored: constraints not satisfied [with T = int]}}425// expected-note@#concept-arg-f4 {{because 'one<int, False>'}}426// expected-note@#concept-arg-one {{because 'int' does not satisfy 'False'}}427// expected-note@#concept-arg-False {{because 'false' evaluated to false}}428 429}430 431template <typename T, template <typename...> concept C1>432concept TestBinary = T::a || C1<T>;433static_assert(TestBinary<int, A>);434 435 436}437