diff options
author | Seivan Heidari <[email protected]> | 2019-12-23 14:35:31 +0000 |
---|---|---|
committer | Seivan Heidari <[email protected]> | 2019-12-23 14:35:31 +0000 |
commit | b21d9337d9200e2cfdc90b386591c72c302dc03e (patch) | |
tree | f81f5c08f821115cee26fa4d3ceaae88c7807fd5 /crates/ra_hir_ty/src/tests/macros.rs | |
parent | 18a0937585b836ec5ed054b9ae48e0156ab6d9ef (diff) | |
parent | ce07a2daa9e53aa86a769f8641b14c2878444fbc (diff) |
Merge branch 'master' into feature/themes
Diffstat (limited to 'crates/ra_hir_ty/src/tests/macros.rs')
-rw-r--r-- | crates/ra_hir_ty/src/tests/macros.rs | 390 |
1 files changed, 390 insertions, 0 deletions
diff --git a/crates/ra_hir_ty/src/tests/macros.rs b/crates/ra_hir_ty/src/tests/macros.rs new file mode 100644 index 000000000..69c695cc8 --- /dev/null +++ b/crates/ra_hir_ty/src/tests/macros.rs | |||
@@ -0,0 +1,390 @@ | |||
1 | use super::{infer, type_at, type_at_pos}; | ||
2 | use crate::test_db::TestDB; | ||
3 | use insta::assert_snapshot; | ||
4 | use ra_db::fixture::WithFixture; | ||
5 | |||
6 | #[test] | ||
7 | fn cfg_impl_block() { | ||
8 | let (db, pos) = TestDB::with_position( | ||
9 | r#" | ||
10 | //- /main.rs crate:main deps:foo cfg:test | ||
11 | use foo::S as T; | ||
12 | struct S; | ||
13 | |||
14 | #[cfg(test)] | ||
15 | impl S { | ||
16 | fn foo1(&self) -> i32 { 0 } | ||
17 | } | ||
18 | |||
19 | #[cfg(not(test))] | ||
20 | impl S { | ||
21 | fn foo2(&self) -> i32 { 0 } | ||
22 | } | ||
23 | |||
24 | fn test() { | ||
25 | let t = (S.foo1(), S.foo2(), T.foo3(), T.foo4()); | ||
26 | t<|>; | ||
27 | } | ||
28 | |||
29 | //- /foo.rs crate:foo | ||
30 | struct S; | ||
31 | |||
32 | #[cfg(not(test))] | ||
33 | impl S { | ||
34 | fn foo3(&self) -> i32 { 0 } | ||
35 | } | ||
36 | |||
37 | #[cfg(test)] | ||
38 | impl S { | ||
39 | fn foo4(&self) -> i32 { 0 } | ||
40 | } | ||
41 | "#, | ||
42 | ); | ||
43 | assert_eq!("(i32, {unknown}, i32, {unknown})", type_at_pos(&db, pos)); | ||
44 | } | ||
45 | |||
46 | #[test] | ||
47 | fn infer_macros_expanded() { | ||
48 | assert_snapshot!( | ||
49 | infer(r#" | ||
50 | struct Foo(Vec<i32>); | ||
51 | |||
52 | macro_rules! foo { | ||
53 | ($($item:expr),*) => { | ||
54 | { | ||
55 | Foo(vec![$($item,)*]) | ||
56 | } | ||
57 | }; | ||
58 | } | ||
59 | |||
60 | fn main() { | ||
61 | let x = foo!(1,2); | ||
62 | } | ||
63 | "#), | ||
64 | @r###" | ||
65 | ![0; 17) '{Foo(v...,2,])}': Foo | ||
66 | ![1; 4) 'Foo': Foo({unknown}) -> Foo | ||
67 | ![1; 16) 'Foo(vec![1,2,])': Foo | ||
68 | ![5; 15) 'vec![1,2,]': {unknown} | ||
69 | [156; 182) '{ ...,2); }': () | ||
70 | [166; 167) 'x': Foo | ||
71 | "### | ||
72 | ); | ||
73 | } | ||
74 | |||
75 | #[test] | ||
76 | fn infer_legacy_textual_scoped_macros_expanded() { | ||
77 | assert_snapshot!( | ||
78 | infer(r#" | ||
79 | struct Foo(Vec<i32>); | ||
80 | |||
81 | #[macro_use] | ||
82 | mod m { | ||
83 | macro_rules! foo { | ||
84 | ($($item:expr),*) => { | ||
85 | { | ||
86 | Foo(vec![$($item,)*]) | ||
87 | } | ||
88 | }; | ||
89 | } | ||
90 | } | ||
91 | |||
92 | fn main() { | ||
93 | let x = foo!(1,2); | ||
94 | let y = crate::foo!(1,2); | ||
95 | } | ||
96 | "#), | ||
97 | @r###" | ||
98 | ![0; 17) '{Foo(v...,2,])}': Foo | ||
99 | ![1; 4) 'Foo': Foo({unknown}) -> Foo | ||
100 | ![1; 16) 'Foo(vec![1,2,])': Foo | ||
101 | ![5; 15) 'vec![1,2,]': {unknown} | ||
102 | [195; 251) '{ ...,2); }': () | ||
103 | [205; 206) 'x': Foo | ||
104 | [228; 229) 'y': {unknown} | ||
105 | [232; 248) 'crate:...!(1,2)': {unknown} | ||
106 | "### | ||
107 | ); | ||
108 | } | ||
109 | |||
110 | #[test] | ||
111 | fn infer_path_qualified_macros_expanded() { | ||
112 | assert_snapshot!( | ||
113 | infer(r#" | ||
114 | #[macro_export] | ||
115 | macro_rules! foo { | ||
116 | () => { 42i32 } | ||
117 | } | ||
118 | |||
119 | mod m { | ||
120 | pub use super::foo as bar; | ||
121 | } | ||
122 | |||
123 | fn main() { | ||
124 | let x = crate::foo!(); | ||
125 | let y = m::bar!(); | ||
126 | } | ||
127 | "#), | ||
128 | @r###" | ||
129 | ![0; 5) '42i32': i32 | ||
130 | ![0; 5) '42i32': i32 | ||
131 | [111; 164) '{ ...!(); }': () | ||
132 | [121; 122) 'x': i32 | ||
133 | [148; 149) 'y': i32 | ||
134 | "### | ||
135 | ); | ||
136 | } | ||
137 | |||
138 | #[test] | ||
139 | fn infer_type_value_macro_having_same_name() { | ||
140 | assert_snapshot!( | ||
141 | infer(r#" | ||
142 | #[macro_export] | ||
143 | macro_rules! foo { | ||
144 | () => { | ||
145 | mod foo { | ||
146 | pub use super::foo; | ||
147 | } | ||
148 | }; | ||
149 | ($x:tt) => { | ||
150 | $x | ||
151 | }; | ||
152 | } | ||
153 | |||
154 | foo!(); | ||
155 | |||
156 | fn foo() { | ||
157 | let foo = foo::foo!(42i32); | ||
158 | } | ||
159 | "#), | ||
160 | @r###" | ||
161 | ![0; 5) '42i32': i32 | ||
162 | [171; 206) '{ ...32); }': () | ||
163 | [181; 184) 'foo': i32 | ||
164 | "### | ||
165 | ); | ||
166 | } | ||
167 | |||
168 | #[test] | ||
169 | fn processes_impls_generated_by_macros() { | ||
170 | let t = type_at( | ||
171 | r#" | ||
172 | //- /main.rs | ||
173 | macro_rules! m { | ||
174 | ($ident:ident) => (impl Trait for $ident {}) | ||
175 | } | ||
176 | trait Trait { fn foo(self) -> u128 {} } | ||
177 | struct S; | ||
178 | m!(S); | ||
179 | fn test() { S.foo()<|>; } | ||
180 | "#, | ||
181 | ); | ||
182 | assert_eq!(t, "u128"); | ||
183 | } | ||
184 | |||
185 | #[test] | ||
186 | fn infer_impl_items_generated_by_macros() { | ||
187 | let t = type_at( | ||
188 | r#" | ||
189 | //- /main.rs | ||
190 | macro_rules! m { | ||
191 | () => (fn foo(&self) -> u128 {0}) | ||
192 | } | ||
193 | struct S; | ||
194 | impl S { | ||
195 | m!(); | ||
196 | } | ||
197 | |||
198 | fn test() { S.foo()<|>; } | ||
199 | "#, | ||
200 | ); | ||
201 | assert_eq!(t, "u128"); | ||
202 | } | ||
203 | |||
204 | #[test] | ||
205 | fn infer_impl_items_generated_by_macros_chain() { | ||
206 | let t = type_at( | ||
207 | r#" | ||
208 | //- /main.rs | ||
209 | macro_rules! m_inner { | ||
210 | () => {fn foo(&self) -> u128 {0}} | ||
211 | } | ||
212 | macro_rules! m { | ||
213 | () => {m_inner!();} | ||
214 | } | ||
215 | |||
216 | struct S; | ||
217 | impl S { | ||
218 | m!(); | ||
219 | } | ||
220 | |||
221 | fn test() { S.foo()<|>; } | ||
222 | "#, | ||
223 | ); | ||
224 | assert_eq!(t, "u128"); | ||
225 | } | ||
226 | |||
227 | #[test] | ||
228 | fn infer_macro_with_dollar_crate_is_correct_in_expr() { | ||
229 | let (db, pos) = TestDB::with_position( | ||
230 | r#" | ||
231 | //- /main.rs crate:main deps:foo | ||
232 | fn test() { | ||
233 | let x = (foo::foo!(1), foo::foo!(2)); | ||
234 | x<|>; | ||
235 | } | ||
236 | |||
237 | //- /lib.rs crate:foo | ||
238 | #[macro_export] | ||
239 | macro_rules! foo { | ||
240 | (1) => { $crate::bar!() }; | ||
241 | (2) => { 1 + $crate::baz() }; | ||
242 | } | ||
243 | |||
244 | #[macro_export] | ||
245 | macro_rules! bar { | ||
246 | () => { 42 } | ||
247 | } | ||
248 | |||
249 | pub fn baz() -> usize { 31usize } | ||
250 | "#, | ||
251 | ); | ||
252 | assert_eq!("(i32, usize)", type_at_pos(&db, pos)); | ||
253 | } | ||
254 | |||
255 | #[test] | ||
256 | fn infer_type_value_non_legacy_macro_use_as() { | ||
257 | assert_snapshot!( | ||
258 | infer(r#" | ||
259 | mod m { | ||
260 | macro_rules! _foo { | ||
261 | ($x:ident) => { type $x = u64; } | ||
262 | } | ||
263 | pub(crate) use _foo as foo; | ||
264 | } | ||
265 | |||
266 | m::foo!(foo); | ||
267 | use foo as bar; | ||
268 | fn f() -> bar { 0 } | ||
269 | fn main() { | ||
270 | let _a = f(); | ||
271 | } | ||
272 | "#), | ||
273 | @r###" | ||
274 | [159; 164) '{ 0 }': u64 | ||
275 | [161; 162) '0': u64 | ||
276 | [175; 199) '{ ...f(); }': () | ||
277 | [187; 189) '_a': u64 | ||
278 | [193; 194) 'f': fn f() -> u64 | ||
279 | [193; 196) 'f()': u64 | ||
280 | "### | ||
281 | ); | ||
282 | } | ||
283 | |||
284 | #[test] | ||
285 | fn infer_builtin_macros_line() { | ||
286 | assert_snapshot!( | ||
287 | infer(r#" | ||
288 | #[rustc_builtin_macro] | ||
289 | macro_rules! line {() => {}} | ||
290 | |||
291 | fn main() { | ||
292 | let x = line!(); | ||
293 | } | ||
294 | "#), | ||
295 | @r###" | ||
296 | ![0; 1) '6': i32 | ||
297 | [64; 88) '{ ...!(); }': () | ||
298 | [74; 75) 'x': i32 | ||
299 | "### | ||
300 | ); | ||
301 | } | ||
302 | |||
303 | #[test] | ||
304 | fn infer_builtin_macros_file() { | ||
305 | assert_snapshot!( | ||
306 | infer(r#" | ||
307 | #[rustc_builtin_macro] | ||
308 | macro_rules! file {() => {}} | ||
309 | |||
310 | fn main() { | ||
311 | let x = file!(); | ||
312 | } | ||
313 | "#), | ||
314 | @r###" | ||
315 | ![0; 2) '""': &str | ||
316 | [64; 88) '{ ...!(); }': () | ||
317 | [74; 75) 'x': &str | ||
318 | "### | ||
319 | ); | ||
320 | } | ||
321 | |||
322 | #[test] | ||
323 | fn infer_builtin_macros_column() { | ||
324 | assert_snapshot!( | ||
325 | infer(r#" | ||
326 | #[rustc_builtin_macro] | ||
327 | macro_rules! column {() => {}} | ||
328 | |||
329 | fn main() { | ||
330 | let x = column!(); | ||
331 | } | ||
332 | "#), | ||
333 | @r###" | ||
334 | ![0; 2) '13': i32 | ||
335 | [66; 92) '{ ...!(); }': () | ||
336 | [76; 77) 'x': i32 | ||
337 | "### | ||
338 | ); | ||
339 | } | ||
340 | |||
341 | #[test] | ||
342 | fn infer_derive_clone_simple() { | ||
343 | let (db, pos) = TestDB::with_position( | ||
344 | r#" | ||
345 | //- /main.rs crate:main deps:std | ||
346 | #[derive(Clone)] | ||
347 | struct S; | ||
348 | fn test() { | ||
349 | S.clone()<|>; | ||
350 | } | ||
351 | |||
352 | //- /lib.rs crate:std | ||
353 | #[prelude_import] | ||
354 | use clone::*; | ||
355 | mod clone { | ||
356 | trait Clone { | ||
357 | fn clone(&self) -> Self; | ||
358 | } | ||
359 | } | ||
360 | "#, | ||
361 | ); | ||
362 | assert_eq!("S", type_at_pos(&db, pos)); | ||
363 | } | ||
364 | |||
365 | #[test] | ||
366 | fn infer_derive_clone_with_params() { | ||
367 | let (db, pos) = TestDB::with_position( | ||
368 | r#" | ||
369 | //- /main.rs crate:main deps:std | ||
370 | #[derive(Clone)] | ||
371 | struct S; | ||
372 | #[derive(Clone)] | ||
373 | struct Wrapper<T>(T); | ||
374 | struct NonClone; | ||
375 | fn test() { | ||
376 | (Wrapper(S).clone(), Wrapper(NonClone).clone())<|>; | ||
377 | } | ||
378 | |||
379 | //- /lib.rs crate:std | ||
380 | #[prelude_import] | ||
381 | use clone::*; | ||
382 | mod clone { | ||
383 | trait Clone { | ||
384 | fn clone(&self) -> Self; | ||
385 | } | ||
386 | } | ||
387 | "#, | ||
388 | ); | ||
389 | assert_eq!("(Wrapper<S>, {unknown})", type_at_pos(&db, pos)); | ||
390 | } | ||