diff options
Diffstat (limited to 'crates/ra_hir_ty/src/tests/macros.rs')
-rw-r--r-- | crates/ra_hir_ty/src/tests/macros.rs | 268 |
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 @@ | |||
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_macro_with_dollar_crate_is_correct_in_expr() { | ||
187 | let (db, pos) = TestDB::with_position( | ||
188 | r#" | ||
189 | //- /main.rs crate:main deps:foo | ||
190 | fn test() { | ||
191 | let x = (foo::foo!(1), foo::foo!(2)); | ||
192 | x<|>; | ||
193 | } | ||
194 | |||
195 | //- /lib.rs crate:foo | ||
196 | #[macro_export] | ||
197 | macro_rules! foo { | ||
198 | (1) => { $crate::bar!() }; | ||
199 | (2) => { 1 + $crate::baz() }; | ||
200 | } | ||
201 | |||
202 | #[macro_export] | ||
203 | macro_rules! bar { | ||
204 | () => { 42 } | ||
205 | } | ||
206 | |||
207 | pub fn baz() -> usize { 31usize } | ||
208 | "#, | ||
209 | ); | ||
210 | assert_eq!("(i32, usize)", type_at_pos(&db, pos)); | ||
211 | } | ||
212 | |||
213 | #[test] | ||
214 | fn infer_builtin_macros_line() { | ||
215 | assert_snapshot!( | ||
216 | infer(r#" | ||
217 | #[rustc_builtin_macro] | ||
218 | macro_rules! line {() => {}} | ||
219 | |||
220 | fn 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] | ||
233 | fn infer_builtin_macros_file() { | ||
234 | assert_snapshot!( | ||
235 | infer(r#" | ||
236 | #[rustc_builtin_macro] | ||
237 | macro_rules! file {() => {}} | ||
238 | |||
239 | fn 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] | ||
252 | fn infer_builtin_macros_column() { | ||
253 | assert_snapshot!( | ||
254 | infer(r#" | ||
255 | #[rustc_builtin_macro] | ||
256 | macro_rules! column {() => {}} | ||
257 | |||
258 | fn 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 | } | ||