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.rs268
1 files changed, 268 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..0d9a35ce0
--- /dev/null
+++ b/crates/ra_hir_ty/src/tests/macros.rs
@@ -0,0 +1,268 @@
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_macro_with_dollar_crate_is_correct_in_expr() {
187 let (db, pos) = TestDB::with_position(
188 r#"
189//- /main.rs crate:main deps:foo
190fn test() {
191 let x = (foo::foo!(1), foo::foo!(2));
192 x<|>;
193}
194
195//- /lib.rs crate:foo
196#[macro_export]
197macro_rules! foo {
198 (1) => { $crate::bar!() };
199 (2) => { 1 + $crate::baz() };
200}
201
202#[macro_export]
203macro_rules! bar {
204 () => { 42 }
205}
206
207pub fn baz() -> usize { 31usize }
208"#,
209 );
210 assert_eq!("(i32, usize)", type_at_pos(&db, pos));
211}
212
213#[test]
214fn infer_builtin_macros_line() {
215 assert_snapshot!(
216 infer(r#"
217#[rustc_builtin_macro]
218macro_rules! line {() => {}}
219
220fn main() {
221 let x = line!();
222}
223"#),
224 @r###"
225 ![0; 1) '6': i32
226 [64; 88) '{ ...!(); }': ()
227 [74; 75) 'x': i32
228 "###
229 );
230}
231
232#[test]
233fn infer_builtin_macros_file() {
234 assert_snapshot!(
235 infer(r#"
236#[rustc_builtin_macro]
237macro_rules! file {() => {}}
238
239fn main() {
240 let x = file!();
241}
242"#),
243 @r###"
244 ![0; 2) '""': &str
245 [64; 88) '{ ...!(); }': ()
246 [74; 75) 'x': &str
247 "###
248 );
249}
250
251#[test]
252fn infer_builtin_macros_column() {
253 assert_snapshot!(
254 infer(r#"
255#[rustc_builtin_macro]
256macro_rules! column {() => {}}
257
258fn main() {
259 let x = column!();
260}
261"#),
262 @r###"
263 ![0; 2) '13': i32
264 [66; 92) '{ ...!(); }': ()
265 [76; 77) 'x': i32
266 "###
267 );
268}