1 // RUN: %clang_cc1 -std=c++2a -verify %s
3 // Make sure constraint expressions are unevaluated before being substituted
4 // into during satisfaction checking.
6 template<typename T
> constexpr bool f
= T::value
;
7 // expected-error@-1 4{{type}}
9 namespace unevaluated
{
10 template<typename T
> concept Foo
= false && f
<int>;
12 template<typename T
> requires
false && f
<int> struct S
{};
13 // expected-note@-1{{because}}
14 using s
= S
<int>; // expected-error {{constraints not satisfied}}
15 template<typename T
> void foo() requires
false && f
<int> { };
16 // expected-note@-1{{because}} expected-note@-1{{candidate template ignored}}
17 int a
= (foo
<int>(), 0); // expected-error{{no matching function}}
18 template<typename T
> void bar() requires requires
{ requires
false && f
<int>; } { };
19 // expected-note@-1{{because}} expected-note@-1{{candidate template ignored}}
20 int b
= (bar
<int>(), 0); // expected-error{{no matching function}}
21 template<typename T
> struct M
{ static void foo() requires
false && f
<int> { }; };
22 // expected-note@-1{{because}}
23 int c
= (M
<int>::foo(), 0);
24 // expected-error@-1{{invalid reference to function 'foo': constraints not satisfied}}
27 namespace constant_evaluated
{
28 template<typename T
> requires f
<int[0]> struct S
{};
29 // expected-note@-1{{in instantiation of}} expected-note@-1{{while substituting}}
31 // expected-note@-1 {{while checking}}
32 template<typename T
> void foo() requires f
<int[1]> { };
33 // expected-note@-1{{in instantiation}} expected-note@-1{{while substituting}} \
34 expected
-note@
-1{{candidate
template ignored
}}
35 int a
= (foo
<int>(), 0);
36 // expected-note@-1 {{while checking}} expected-error@-1{{no matching function}} \
37 expected
-note@
-1 {{in instantiation
}}
38 template<typename T
> void bar() requires requires
{ requires f
<int[2]>; } { };
39 // expected-note@-1{{in instantiation}} \
40 expected
-note@
-1{{while substituting
}} \
41 expected
-note@
-1 {{while checking the satisfaction of nested requirement
}}
42 int b
= (bar
<int>(), 0);
43 template<typename T
> struct M
{ static void foo() requires f
<int[3]> { }; };
44 // expected-note@-1{{in instantiation}} expected-note@-1{{while substituting}}
45 int c
= (M
<int>::foo(), 0);
46 // expected-note@-1 {{while checking}}