aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/tests/macros.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/tests/macros.rs')
-rw-r--r--crates/ra_hir_ty/src/tests/macros.rs390
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 @@
1use super::{infer, type_at, type_at_pos};
2use crate::test_db::TestDB;
3use insta::assert_snapshot;
4use ra_db::fixture::WithFixture;
5
6#[test]
7fn cfg_impl_block() {
8 let (db, pos) = TestDB::with_position(
9 r#"
10//- /main.rs crate:main deps:foo cfg:test
11use foo::S as T;
12struct S;
13
14#[cfg(test)]
15impl S {
16 fn foo1(&self) -> i32 { 0 }
17}
18
19#[cfg(not(test))]
20impl S {
21 fn foo2(&self) -> i32 { 0 }
22}
23
24fn test() {
25 let t = (S.foo1(), S.foo2(), T.foo3(), T.foo4());
26 t<|>;
27}
28
29//- /foo.rs crate:foo
30struct S;
31
32#[cfg(not(test))]
33impl S {
34 fn foo3(&self) -> i32 { 0 }
35}
36
37#[cfg(test)]
38impl 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]
47fn infer_macros_expanded() {
48 assert_snapshot!(
49 infer(r#"
50struct Foo(Vec<i32>);
51
52macro_rules! foo {
53 ($($item:expr),*) => {
54 {
55 Foo(vec![$($item,)*])
56 }
57 };
58}
59
60fn 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]
76fn infer_legacy_textual_scoped_macros_expanded() {
77 assert_snapshot!(
78 infer(r#"
79struct Foo(Vec<i32>);
80
81#[macro_use]
82mod m {
83 macro_rules! foo {
84 ($($item:expr),*) => {
85 {
86 Foo(vec![$($item,)*])
87 }
88 };
89 }
90}
91
92fn 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]
111fn infer_path_qualified_macros_expanded() {
112 assert_snapshot!(
113 infer(r#"
114#[macro_export]
115macro_rules! foo {
116 () => { 42i32 }
117}
118
119mod m {
120 pub use super::foo as bar;
121}
122
123fn 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]
139fn infer_type_value_macro_having_same_name() {
140 assert_snapshot!(
141 infer(r#"
142#[macro_export]
143macro_rules! foo {
144 () => {
145 mod foo {
146 pub use super::foo;
147 }
148 };
149 ($x:tt) => {
150 $x
151 };
152}
153
154foo!();
155
156fn 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]
169fn processes_impls_generated_by_macros() {
170 let t = type_at(
171 r#"
172//- /main.rs
173macro_rules! m {
174 ($ident:ident) => (impl Trait for $ident {})
175}
176trait Trait { fn foo(self) -> u128 {} }
177struct S;
178m!(S);
179fn test() { S.foo()<|>; }
180"#,
181 );
182 assert_eq!(t, "u128");
183}
184
185#[test]
186fn infer_impl_items_generated_by_macros() {
187 let t = type_at(
188 r#"
189//- /main.rs
190macro_rules! m {
191 () => (fn foo(&self) -> u128 {0})
192}
193struct S;
194impl S {
195 m!();
196}
197
198fn test() { S.foo()<|>; }
199"#,
200 );
201 assert_eq!(t, "u128");
202}
203
204#[test]
205fn infer_impl_items_generated_by_macros_chain() {
206 let t = type_at(
207 r#"
208//- /main.rs
209macro_rules! m_inner {
210 () => {fn foo(&self) -> u128 {0}}
211}
212macro_rules! m {
213 () => {m_inner!();}
214}
215
216struct S;
217impl S {
218 m!();
219}
220
221fn test() { S.foo()<|>; }
222"#,
223 );
224 assert_eq!(t, "u128");
225}
226
227#[test]
228fn 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
232fn test() {
233 let x = (foo::foo!(1), foo::foo!(2));
234 x<|>;
235}
236
237//- /lib.rs crate:foo
238#[macro_export]
239macro_rules! foo {
240 (1) => { $crate::bar!() };
241 (2) => { 1 + $crate::baz() };
242}
243
244#[macro_export]
245macro_rules! bar {
246 () => { 42 }
247}
248
249pub fn baz() -> usize { 31usize }
250"#,
251 );
252 assert_eq!("(i32, usize)", type_at_pos(&db, pos));
253}
254
255#[test]
256fn infer_type_value_non_legacy_macro_use_as() {
257 assert_snapshot!(
258 infer(r#"
259mod m {
260 macro_rules! _foo {
261 ($x:ident) => { type $x = u64; }
262 }
263 pub(crate) use _foo as foo;
264}
265
266m::foo!(foo);
267use foo as bar;
268fn f() -> bar { 0 }
269fn 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]
285fn infer_builtin_macros_line() {
286 assert_snapshot!(
287 infer(r#"
288#[rustc_builtin_macro]
289macro_rules! line {() => {}}
290
291fn 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]
304fn infer_builtin_macros_file() {
305 assert_snapshot!(
306 infer(r#"
307#[rustc_builtin_macro]
308macro_rules! file {() => {}}
309
310fn 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]
323fn infer_builtin_macros_column() {
324 assert_snapshot!(
325 infer(r#"
326#[rustc_builtin_macro]
327macro_rules! column {() => {}}
328
329fn 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]
342fn infer_derive_clone_simple() {
343 let (db, pos) = TestDB::with_position(
344 r#"
345//- /main.rs crate:main deps:std
346#[derive(Clone)]
347struct S;
348fn test() {
349 S.clone()<|>;
350}
351
352//- /lib.rs crate:std
353#[prelude_import]
354use clone::*;
355mod 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]
366fn infer_derive_clone_with_params() {
367 let (db, pos) = TestDB::with_position(
368 r#"
369//- /main.rs crate:main deps:std
370#[derive(Clone)]
371struct S;
372#[derive(Clone)]
373struct Wrapper<T>(T);
374struct NonClone;
375fn test() {
376 (Wrapper(S).clone(), Wrapper(NonClone).clone())<|>;
377}
378
379//- /lib.rs crate:std
380#[prelude_import]
381use clone::*;
382mod 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}