blob: b2cc1145ac15e25eb817540d3a5778a323a002a3 [file] [log] [blame]
Devin Jeanpierredcf51432023-04-13 14:49:25 -07001// Part of the Crubit project, under the Apache License v2.0 with LLVM
2// Exceptions. See /LICENSE for license information.
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5// shadow core and std to try to break the proc macro :)
6mod std {}
7mod core {}
8
9mod type_exists {
10 #[allow(unused_imports)]
11 use super::*;
12
13 #[test]
14 fn type_doesnt_exist() {
15 mod m {}
16 assert!(!item_exists::type_exists!(m::DoesNotExist));
17 }
18
19 #[test]
20 fn struct_does_exist() {
21 mod m {
22 pub struct S {}
23 }
24 assert!(item_exists::type_exists!(m::S));
25 }
26
27 #[test]
28 fn unit_struct_does_exist() {
29 mod m {
30 pub struct S;
31 }
32 assert!(item_exists::type_exists!(m::S));
33 }
34
35 #[test]
36 fn tuple_struct_does_exist() {
37 mod m {
38 pub struct S();
39 }
40 assert!(item_exists::type_exists!(m::S));
41 }
42
43 #[test]
44 fn enum_does_exist() {
45 mod m {
46 pub enum E {}
47 }
48 assert!(item_exists::type_exists!(m::E));
49 }
50
51 #[test]
52 fn union_does_exist() {
53 mod m {
54 pub union U {
55 _x: i32,
56 }
57 }
58 assert!(item_exists::type_exists!(m::U));
59 }
60
61 /// When we use the same name in a type context, we find no such type
62 /// exists.
63 #[test]
64 fn function_doesnt_exist() {
65 mod m {
66 #[allow(unused)]
67 pub fn foo() {}
68 }
69 assert!(!item_exists::type_exists!(m::foo));
70 }
71
72 #[test]
73 fn constant_doesnt_exist() {
74 mod m {
75 #[allow(unused)]
76 pub const X: () = ();
77 }
78 assert!(!item_exists::type_exists!(m::X));
79 }
80
81 #[test]
82 fn static_doesnt_exist() {
83 mod m {
84 #[allow(unused)]
85 pub static X: () = ();
86 }
87 assert!(!item_exists::type_exists!(m::X));
88 }
89
90 #[test]
91 fn mod_doesnt_exist() {
92 mod m {
93 mod m2 {}
94 }
95 assert!(!item_exists::type_exists!(m::m2));
96 }
97
98 #[test]
99 fn nested_module() {
100 mod m {
101 pub mod m2 {
102 pub struct S;
103 }
104 }
105 assert!(item_exists::type_exists!(m::m2::S));
106 assert!(!item_exists::type_exists!(m::S));
107 assert!(!item_exists::type_exists!(m::m2::DoesNotExist));
108 }
109
110 #[test]
111 fn std_type() {
112 assert!(item_exists::type_exists!(::std::num::NonZeroU8));
113 }
114
115 #[test]
116 fn function_type() {
117 assert!(item_exists::type_exists!(::std::num::NonZeroU8));
118 }
119
120 #[test]
121 fn alias() {
122 mod m {
123 pub type X = ::std::num::NonZeroU8;
124 }
125 assert!(item_exists::type_exists!(m::X));
126 }
127
128 #[test]
129 fn use_alias() {
130 mod m {
131 pub use ::std::num::NonZeroU8 as X;
132 }
133 assert!(item_exists::type_exists!(m::X));
134 }
135
136 /// Invoke the proc-macro twice in the same scope. This can expose some
137 /// implementation errors.
138 #[test]
139 fn type_exists_twice() {
140 mod m {
141 pub struct A;
142 }
Dmitri Gribenkoaf3753a2023-07-03 04:53:42 -0700143 _ = item_exists::type_exists!(m::A);
144 _ = item_exists::type_exists!(m::A);
Devin Jeanpierredcf51432023-04-13 14:49:25 -0700145 }
146}
147
148mod value_exists {
149 #[allow(unused_imports)]
150 use super::*;
151
152 #[test]
153 fn value_doesnt_exist() {
154 mod m {}
155 assert!(!item_exists::value_exists!(m::does_not_exist));
156 }
157
158 #[test]
159 fn struct_doesnt_exist() {
160 mod m {
161 #[allow(dead_code)]
162 pub struct S {}
163 }
164 assert!(!item_exists::value_exists!(m::S));
165 }
166
167 /// In type_exists!, we find the type. In value_exists!, we find the
168 /// _constant_.
169 #[test]
170 fn unit_struct_does_exist() {
171 mod m {
172 pub struct S;
173 }
174 assert!(item_exists::value_exists!(m::S));
175 }
176
177 /// This one may be surprising, but it's ultimately similar to unit structs.
178 /// In type_exists!, we find the type. In value_exists!, we find the
179 /// _constructor_, a function.
180 #[test]
181 fn tuple_struct_does_exist() {
182 mod m {
183 pub struct S();
184 }
185 assert!(item_exists::value_exists!(m::S));
186 }
187
188 #[test]
189 fn enum_doesnt_exist() {
190 mod m {
191 #[allow(dead_code)]
192 pub enum E {}
193 }
194 assert!(!item_exists::value_exists!(m::E));
195 }
196
197 #[test]
198 fn union_doesnt_exist() {
199 mod m {
200 #[allow(dead_code)]
201 pub union U {
202 _x: i32,
203 }
204 }
205 assert!(!item_exists::value_exists!(m::U));
206 }
207
208 #[test]
209 fn function_does_exist() {
210 mod m {
211 pub fn foo() {}
212 }
213 assert!(item_exists::value_exists!(m::foo));
214 }
215
216 #[test]
217 fn constant_does_exist() {
218 mod m {
219 pub const X: () = ();
220 }
221 assert!(item_exists::value_exists!(m::X));
222 }
223
224 #[test]
225 fn static_does_exist() {
226 mod m {
227 pub static X: () = ();
228 }
229 assert!(item_exists::value_exists!(m::X));
230 }
231
232 #[test]
233 fn mod_doesnt_exist() {
234 mod m {
235 mod m2 {}
236 }
237 assert!(!item_exists::value_exists!(m::m2));
238 }
239
240 #[test]
241 fn nested_module() {
242 mod m {
243 pub mod m2 {
244 pub const X: () = ();
245 }
246 }
247 assert!(item_exists::value_exists!(m::m2::X));
248 assert!(!item_exists::value_exists!(m::X));
249 assert!(!item_exists::value_exists!(m::m2::DoesNotExist));
250 }
251
252 #[test]
253 fn std_value() {
254 assert!(item_exists::value_exists!(::std::f32::consts::E));
255 }
256
257 #[test]
258 fn alias_doesnt_exist() {
259 mod m {
260 #[allow(dead_code)]
261 pub type X = ::std::num::NonZeroU8;
262 }
263 assert!(!item_exists::value_exists!(m::X));
264 }
265
266 #[test]
267 fn use_alias_doesnt_exist() {
268 mod m {
Jing Lu2030ad62023-11-02 15:49:01 -0700269 #[allow(unused_imports)]
Devin Jeanpierredcf51432023-04-13 14:49:25 -0700270 pub use ::std::num::NonZeroU8 as X;
271 }
272 assert!(!item_exists::value_exists!(m::X));
273 }
274
275 #[test]
276 fn use_const_does_exist() {
277 mod m {
278 pub use ::std::f32::consts::E as X;
279 }
280 assert!(item_exists::value_exists!(m::X));
281 }
282}