xref: /llvm-project/clang/test/CXX/expr/expr.prim/expr.prim.req/equivalence.cpp (revision 67c608a9695496cfc9d3fdf9d0b12b554ac6b4df)
1*67c608a9SSaar Raz // RUN: %clang_cc1 -std=c++2a -x c++ %s -verify
2a0f50d73SSaar Raz 
3a0f50d73SSaar Raz template<typename T, typename U> constexpr bool is_same_v = false;
4a0f50d73SSaar Raz template<typename T> constexpr bool is_same_v<T, T> = true;
5a0f50d73SSaar Raz 
6a0f50d73SSaar Raz template<typename T> struct identity { using type = T; };
7a0f50d73SSaar Raz template<typename T> using identity_t = T;
8a0f50d73SSaar Raz 
9a0f50d73SSaar Raz // Type requirements
10a0f50d73SSaar Raz template<typename T> requires requires { typename identity_t<T>; }
11a0f50d73SSaar Raz struct r1;
12a0f50d73SSaar Raz template<typename U> requires requires { typename identity_t<U>; } // expected-note{{previous template declaration is here}}
13a0f50d73SSaar Raz struct r1;
14a0f50d73SSaar Raz template<typename T> requires requires { typename identity_t<T*>; } // expected-error{{requires clause differs in template redeclaration}}
15a0f50d73SSaar Raz struct r1;
16a0f50d73SSaar Raz template<typename T> requires requires { typename ::identity_t<T>; }
17a0f50d73SSaar Raz struct r1;
18a0f50d73SSaar Raz 
19a0f50d73SSaar Raz template<typename Y> requires requires { typename identity<Y>::type; }
20a0f50d73SSaar Raz struct r2;
21a0f50d73SSaar Raz template<typename U> requires requires { typename identity<U>::type; }
22a0f50d73SSaar Raz struct r2;
23a0f50d73SSaar Raz template<typename T> requires requires { typename ::identity<T>::type; } // expected-note 2{{previous template declaration is here}}
24a0f50d73SSaar Raz struct r2;
25a0f50d73SSaar Raz template<typename T> requires requires { typename identity<T>::typr; } // expected-error{{requires clause differs in template redeclaration}}
26a0f50d73SSaar Raz struct r2;
27a0f50d73SSaar Raz namespace ns {
28a0f50d73SSaar Raz   template<typename T> struct identity { using type = T; };
29a0f50d73SSaar Raz }
30a0f50d73SSaar Raz template<typename T> requires requires { typename ns::identity<T>::type; } // expected-error{{requires clause differs in template redeclaration}}
31a0f50d73SSaar Raz struct r2;
32a0f50d73SSaar Raz 
33a0f50d73SSaar Raz template<typename T> requires requires { typename T::template identity<T>::type; }
34a0f50d73SSaar Raz struct r3;
35a0f50d73SSaar Raz template<typename U> requires requires { typename U::template identity<U>::type; } // expected-note{{previous template declaration is here}}
36a0f50d73SSaar Raz struct r3;
37a0f50d73SSaar Raz template<typename T> requires requires { typename T::template identitr<T>::type; } // expected-error{{requires clause differs in template redeclaration}}
38a0f50d73SSaar Raz struct r3;
39a0f50d73SSaar Raz 
40a0f50d73SSaar Raz template<typename T> requires requires { typename T::template temp<>; }
41a0f50d73SSaar Raz struct r4;
42a0f50d73SSaar Raz template<typename U> requires requires { typename U::template temp<>; }
43a0f50d73SSaar Raz struct r4;
44a0f50d73SSaar Raz 
45a0f50d73SSaar Raz // Expr requirements
46a0f50d73SSaar Raz template<typename T> requires requires { 0; } // expected-note{{previous template declaration is here}}
47a0f50d73SSaar Raz struct r5;
48a0f50d73SSaar Raz template<typename T> requires requires { 1; } // expected-error{{requires clause differs in template redeclaration}}
49a0f50d73SSaar Raz struct r5;
50a0f50d73SSaar Raz 
51a0f50d73SSaar Raz template<typename T>
52a0f50d73SSaar Raz concept C1 = true;
53a0f50d73SSaar Raz 
54a0f50d73SSaar Raz template<typename T> requires requires { sizeof(T); }
55a0f50d73SSaar Raz struct r6;
56a0f50d73SSaar Raz template<typename U> requires requires { sizeof(U); } // expected-note{{previous template declaration is here}}
57a0f50d73SSaar Raz struct r6;
58a0f50d73SSaar Raz template<typename U> requires requires { sizeof(U) - 1; } // expected-error{{requires clause differs in template redeclaration}}
59a0f50d73SSaar Raz struct r6;
60a0f50d73SSaar Raz template<typename T> requires requires { { sizeof(T) }; } // expected-note 2{{previous template declaration is here}}
61a0f50d73SSaar Raz struct r6;
62a0f50d73SSaar Raz template<typename T> requires requires { { sizeof(T) } noexcept; } // expected-error{{requires clause differs in template redeclaration}}
63a0f50d73SSaar Raz struct r6;
64a0f50d73SSaar Raz template<typename T> requires requires { { sizeof(T) } -> C1; } // expected-error{{requires clause differs in template redeclaration}}
65a0f50d73SSaar Raz struct r6;
66a0f50d73SSaar Raz 
67a0f50d73SSaar Raz template<typename T> requires requires { { sizeof(T) } -> C1; }
68a0f50d73SSaar Raz struct r7;
69a0f50d73SSaar Raz template<typename U> requires requires { { sizeof(U) } -> C1; }
70a0f50d73SSaar Raz struct r7;
71a0f50d73SSaar Raz template<typename T> requires requires { { sizeof(T) } -> C1<>; } // expected-note {{previous template declaration is here}}
72a0f50d73SSaar Raz struct r7;
73a0f50d73SSaar Raz template<typename U> requires requires { { sizeof(U) }; } // expected-error{{requires clause differs in template redeclaration}}
74a0f50d73SSaar Raz struct r7;
75a0f50d73SSaar Raz 
76a0f50d73SSaar Raz template<typename T, typename U>
77a0f50d73SSaar Raz concept C2 = true;
78a0f50d73SSaar Raz 
79a0f50d73SSaar Raz template<typename T> requires requires { { sizeof(T) } -> C2<T>; }
80a0f50d73SSaar Raz struct r8;
81a0f50d73SSaar Raz template<typename U> requires requires { { sizeof(U) } -> C2<U>; } // expected-note{{previous template declaration is here}}
82a0f50d73SSaar Raz struct r8;
83a0f50d73SSaar Raz template<typename T> requires requires { { sizeof(T) } -> C2<T*>; } // expected-error{{requires clause differs in template redeclaration}}
84a0f50d73SSaar Raz struct r8;
85a0f50d73SSaar Raz 
86a0f50d73SSaar Raz // Nested requirements
87a0f50d73SSaar Raz template<typename T> requires requires { requires sizeof(T) == 0; }
88a0f50d73SSaar Raz struct r9;
89a0f50d73SSaar Raz template<typename U> requires requires { requires sizeof(U) == 0; } // expected-note{{previous template declaration is here}}
90a0f50d73SSaar Raz struct r9;
91a0f50d73SSaar Raz template<typename T> requires requires { requires sizeof(T) == 1; } // expected-error{{requires clause differs in template redeclaration}}
92a0f50d73SSaar Raz struct r9;
93a0f50d73SSaar Raz 
94a0f50d73SSaar Raz // Parameter list
95a0f50d73SSaar Raz template<typename T> requires requires { requires true; }
96a0f50d73SSaar Raz struct r10;
97a0f50d73SSaar Raz template<typename T> requires requires() { requires true; } // expected-note{{previous template declaration is here}}
98a0f50d73SSaar Raz struct r10;
99a0f50d73SSaar Raz template<typename T> requires requires(T i) { requires true; } // expected-error{{requires clause differs in template redeclaration}}
100a0f50d73SSaar Raz struct r10;
101a0f50d73SSaar Raz 
102a0f50d73SSaar Raz template<typename T> requires requires(T i, T *j) { requires true; } // expected-note 2{{previous template declaration is here}}
103a0f50d73SSaar Raz struct r11;
104a0f50d73SSaar Raz template<typename T> requires requires(T i) { requires true; } // expected-error{{requires clause differs in template redeclaration}}
105a0f50d73SSaar Raz struct r11;
106a0f50d73SSaar Raz template<typename T> requires requires(T i, T *j, T &k) { requires true; } // expected-error{{requires clause differs in template redeclaration}}
107a0f50d73SSaar Raz struct r11;
108a0f50d73SSaar Raz 
109a0f50d73SSaar Raz // Parameter names
110a0f50d73SSaar Raz template<typename T> requires requires(int i) { requires sizeof(i) == 1; }
111a0f50d73SSaar Raz struct r12;
112a0f50d73SSaar Raz template<typename T> requires requires(int j) { requires sizeof(j) == 1; } // expected-note 2{{previous template declaration is here}}
113a0f50d73SSaar Raz struct r12;
114a0f50d73SSaar Raz template<typename T> requires requires(int k) { requires sizeof(k) == 2; } // expected-error{{requires clause differs in template redeclaration}}
115a0f50d73SSaar Raz struct r12;
116a0f50d73SSaar Raz template<typename T> requires requires(const int k) { requires sizeof(k) == 1; } // expected-error{{requires clause differs in template redeclaration}}
117a0f50d73SSaar Raz struct r12;
118a0f50d73SSaar Raz 
119a0f50d73SSaar Raz // Order of requirements
120a0f50d73SSaar Raz template<typename T> requires requires { requires true; 0; }
121a0f50d73SSaar Raz struct r13;
122a0f50d73SSaar Raz template<typename T> requires requires { requires true; 0; } // expected-note{{previous template declaration is here}}
123a0f50d73SSaar Raz struct r13;
124a0f50d73SSaar Raz template<typename T> requires requires { 0; requires true; } // expected-error{{requires clause differs in template redeclaration}}
125a0f50d73SSaar Raz struct r13;
126