aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/nameres/tests
diff options
context:
space:
mode:
authorZac Pullar-Strecker <[email protected]>2020-08-24 10:19:53 +0100
committerZac Pullar-Strecker <[email protected]>2020-08-24 10:20:13 +0100
commit7bbca7a1b3f9293d2f5cc5745199bc5f8396f2f0 (patch)
treebdb47765991cb973b2cd5481a088fac636bd326c /crates/hir_def/src/nameres/tests
parentca464650eeaca6195891199a93f4f76cf3e7e697 (diff)
parente65d48d1fb3d4d91d9dc1148a7a836ff5c9a3c87 (diff)
Merge remote-tracking branch 'upstream/master' into 503-hover-doc-links
Diffstat (limited to 'crates/hir_def/src/nameres/tests')
-rw-r--r--crates/hir_def/src/nameres/tests/globs.rs338
-rw-r--r--crates/hir_def/src/nameres/tests/incremental.rs101
-rw-r--r--crates/hir_def/src/nameres/tests/macros.rs669
-rw-r--r--crates/hir_def/src/nameres/tests/mod_resolution.rs796
-rw-r--r--crates/hir_def/src/nameres/tests/primitives.rs23
5 files changed, 1927 insertions, 0 deletions
diff --git a/crates/hir_def/src/nameres/tests/globs.rs b/crates/hir_def/src/nameres/tests/globs.rs
new file mode 100644
index 000000000..2ae836e3c
--- /dev/null
+++ b/crates/hir_def/src/nameres/tests/globs.rs
@@ -0,0 +1,338 @@
1use super::*;
2
3#[test]
4fn glob_1() {
5 check(
6 r#"
7//- /lib.rs
8mod foo;
9use foo::*;
10
11//- /foo/mod.rs
12pub mod bar;
13pub use self::bar::Baz;
14pub struct Foo;
15
16//- /foo/bar.rs
17pub struct Baz;
18"#,
19 expect![[r#"
20 crate
21 Baz: t v
22 Foo: t v
23 bar: t
24 foo: t
25
26 crate::foo
27 Baz: t v
28 Foo: t v
29 bar: t
30
31 crate::foo::bar
32 Baz: t v
33 "#]],
34 );
35}
36
37#[test]
38fn glob_2() {
39 check(
40 r#"
41//- /lib.rs
42mod foo;
43use foo::*;
44
45//- /foo/mod.rs
46pub mod bar;
47pub use self::bar::*;
48pub struct Foo;
49
50//- /foo/bar.rs
51pub struct Baz;
52pub use super::*;
53"#,
54 expect![[r#"
55 crate
56 Baz: t v
57 Foo: t v
58 bar: t
59 foo: t
60
61 crate::foo
62 Baz: t v
63 Foo: t v
64 bar: t
65
66 crate::foo::bar
67 Baz: t v
68 Foo: t v
69 bar: t
70 "#]],
71 );
72}
73
74#[test]
75fn glob_privacy_1() {
76 check(
77 r"
78//- /lib.rs
79mod foo;
80use foo::*;
81
82//- /foo/mod.rs
83pub mod bar;
84pub use self::bar::*;
85struct PrivateStructFoo;
86
87//- /foo/bar.rs
88pub struct Baz;
89struct PrivateStructBar;
90pub use super::*;
91",
92 expect![[r#"
93 crate
94 Baz: t v
95 bar: t
96 foo: t
97
98 crate::foo
99 Baz: t v
100 PrivateStructFoo: t v
101 bar: t
102
103 crate::foo::bar
104 Baz: t v
105 PrivateStructBar: t v
106 PrivateStructFoo: t v
107 bar: t
108 "#]],
109 );
110}
111
112#[test]
113fn glob_privacy_2() {
114 check(
115 r"
116//- /lib.rs
117mod foo;
118use foo::*;
119use foo::bar::*;
120
121//- /foo/mod.rs
122mod bar;
123fn Foo() {};
124pub struct Foo {};
125
126//- /foo/bar.rs
127pub(super) struct PrivateBaz;
128struct PrivateBar;
129pub(crate) struct PubCrateStruct;
130",
131 expect![[r#"
132 crate
133 Foo: t
134 PubCrateStruct: t v
135 foo: t
136
137 crate::foo
138 Foo: t v
139 bar: t
140
141 crate::foo::bar
142 PrivateBar: t v
143 PrivateBaz: t v
144 PubCrateStruct: t v
145 "#]],
146 );
147}
148
149#[test]
150fn glob_across_crates() {
151 mark::check!(glob_across_crates);
152 check(
153 r#"
154//- /main.rs crate:main deps:test_crate
155use test_crate::*;
156
157//- /lib.rs crate:test_crate
158pub struct Baz;
159"#,
160 expect![[r#"
161 crate
162 Baz: t v
163 "#]],
164 );
165}
166
167#[test]
168fn glob_privacy_across_crates() {
169 check(
170 r#"
171//- /main.rs crate:main deps:test_crate
172use test_crate::*;
173
174//- /lib.rs crate:test_crate
175pub struct Baz;
176struct Foo;
177"#,
178 expect![[r#"
179 crate
180 Baz: t v
181 "#]],
182 );
183}
184
185#[test]
186fn glob_enum() {
187 mark::check!(glob_enum);
188 check(
189 r#"
190enum Foo { Bar, Baz }
191use self::Foo::*;
192"#,
193 expect![[r#"
194 crate
195 Bar: t v
196 Baz: t v
197 Foo: t
198 "#]],
199 );
200}
201
202#[test]
203fn glob_enum_group() {
204 mark::check!(glob_enum_group);
205 check(
206 r#"
207enum Foo { Bar, Baz }
208use self::Foo::{*};
209"#,
210 expect![[r#"
211 crate
212 Bar: t v
213 Baz: t v
214 Foo: t
215 "#]],
216 );
217}
218
219#[test]
220fn glob_shadowed_def() {
221 mark::check!(import_shadowed);
222 check(
223 r#"
224//- /lib.rs
225mod foo;
226mod bar;
227use foo::*;
228use bar::baz;
229use baz::Bar;
230
231//- /foo.rs
232pub mod baz { pub struct Foo; }
233
234//- /bar.rs
235pub mod baz { pub struct Bar; }
236"#,
237 expect![[r#"
238 crate
239 Bar: t v
240 bar: t
241 baz: t
242 foo: t
243
244 crate::bar
245 baz: t
246
247 crate::bar::baz
248 Bar: t v
249
250 crate::foo
251 baz: t
252
253 crate::foo::baz
254 Foo: t v
255 "#]],
256 );
257}
258
259#[test]
260fn glob_shadowed_def_reversed() {
261 check(
262 r#"
263//- /lib.rs
264mod foo;
265mod bar;
266use bar::baz;
267use foo::*;
268use baz::Bar;
269
270//- /foo.rs
271pub mod baz { pub struct Foo; }
272
273//- /bar.rs
274pub mod baz { pub struct Bar; }
275"#,
276 expect![[r#"
277 crate
278 Bar: t v
279 bar: t
280 baz: t
281 foo: t
282
283 crate::bar
284 baz: t
285
286 crate::bar::baz
287 Bar: t v
288
289 crate::foo
290 baz: t
291
292 crate::foo::baz
293 Foo: t v
294 "#]],
295 );
296}
297
298#[test]
299fn glob_shadowed_def_dependencies() {
300 check(
301 r#"
302mod a { pub mod foo { pub struct X; } }
303mod b { pub use super::a::foo; }
304mod c { pub mod foo { pub struct Y; } }
305mod d {
306 use super::c::foo;
307 use super::b::*;
308 use foo::Y;
309}
310"#,
311 expect![[r#"
312 crate
313 a: t
314 b: t
315 c: t
316 d: t
317
318 crate::d
319 Y: t v
320 foo: t
321
322 crate::c
323 foo: t
324
325 crate::c::foo
326 Y: t v
327
328 crate::b
329 foo: t
330
331 crate::a
332 foo: t
333
334 crate::a::foo
335 X: t v
336 "#]],
337 );
338}
diff --git a/crates/hir_def/src/nameres/tests/incremental.rs b/crates/hir_def/src/nameres/tests/incremental.rs
new file mode 100644
index 000000000..cfbc62cc4
--- /dev/null
+++ b/crates/hir_def/src/nameres/tests/incremental.rs
@@ -0,0 +1,101 @@
1use std::sync::Arc;
2
3use base_db::SourceDatabaseExt;
4
5use super::*;
6
7fn check_def_map_is_not_recomputed(ra_fixture_initial: &str, ra_fixture_change: &str) {
8 let (mut db, pos) = TestDB::with_position(ra_fixture_initial);
9 let krate = db.test_crate();
10 {
11 let events = db.log_executed(|| {
12 db.crate_def_map(krate);
13 });
14 assert!(format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
15 }
16 db.set_file_text(pos.file_id, Arc::new(ra_fixture_change.to_string()));
17
18 {
19 let events = db.log_executed(|| {
20 db.crate_def_map(krate);
21 });
22 assert!(!format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
23 }
24}
25
26#[test]
27fn typing_inside_a_function_should_not_invalidate_def_map() {
28 check_def_map_is_not_recomputed(
29 r"
30 //- /lib.rs
31 mod foo;<|>
32
33 use crate::foo::bar::Baz;
34
35 enum E { A, B }
36 use E::*;
37
38 fn foo() -> i32 {
39 1 + 1
40 }
41 //- /foo/mod.rs
42 pub mod bar;
43
44 //- /foo/bar.rs
45 pub struct Baz;
46 ",
47 r"
48 mod foo;
49
50 use crate::foo::bar::Baz;
51
52 enum E { A, B }
53 use E::*;
54
55 fn foo() -> i32 { 92 }
56 ",
57 );
58}
59
60#[test]
61fn typing_inside_a_macro_should_not_invalidate_def_map() {
62 let (mut db, pos) = TestDB::with_position(
63 r"
64 //- /lib.rs
65 macro_rules! m {
66 ($ident:ident) => {
67 fn f() {
68 $ident + $ident;
69 };
70 }
71 }
72 mod foo;
73
74 //- /foo/mod.rs
75 pub mod bar;
76
77 //- /foo/bar.rs
78 <|>
79 m!(X);
80 ",
81 );
82 let krate = db.test_crate();
83 {
84 let events = db.log_executed(|| {
85 let crate_def_map = db.crate_def_map(krate);
86 let (_, module_data) = crate_def_map.modules.iter().last().unwrap();
87 assert_eq!(module_data.scope.resolutions().count(), 1);
88 });
89 assert!(format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
90 }
91 db.set_file_text(pos.file_id, Arc::new("m!(Y);".to_string()));
92
93 {
94 let events = db.log_executed(|| {
95 let crate_def_map = db.crate_def_map(krate);
96 let (_, module_data) = crate_def_map.modules.iter().last().unwrap();
97 assert_eq!(module_data.scope.resolutions().count(), 1);
98 });
99 assert!(!format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
100 }
101}
diff --git a/crates/hir_def/src/nameres/tests/macros.rs b/crates/hir_def/src/nameres/tests/macros.rs
new file mode 100644
index 000000000..e0fb8bdef
--- /dev/null
+++ b/crates/hir_def/src/nameres/tests/macros.rs
@@ -0,0 +1,669 @@
1use super::*;
2
3#[test]
4fn macro_rules_are_globally_visible() {
5 check(
6 r#"
7//- /lib.rs
8macro_rules! structs {
9 ($($i:ident),*) => {
10 $(struct $i { field: u32 } )*
11 }
12}
13structs!(Foo);
14mod nested;
15
16//- /nested.rs
17structs!(Bar, Baz);
18"#,
19 expect![[r#"
20 crate
21 Foo: t
22 nested: t
23
24 crate::nested
25 Bar: t
26 Baz: t
27 "#]],
28 );
29}
30
31#[test]
32fn macro_rules_can_define_modules() {
33 check(
34 r#"
35//- /lib.rs
36macro_rules! m {
37 ($name:ident) => { mod $name; }
38}
39m!(n1);
40mod m { m!(n3) }
41
42//- /n1.rs
43m!(n2)
44//- /n1/n2.rs
45struct X;
46//- /m/n3.rs
47struct Y;
48"#,
49 expect![[r#"
50 crate
51 m: t
52 n1: t
53
54 crate::m
55 n3: t
56
57 crate::m::n3
58 Y: t v
59
60 crate::n1
61 n2: t
62
63 crate::n1::n2
64 X: t v
65 "#]],
66 );
67}
68
69#[test]
70fn macro_rules_from_other_crates_are_visible() {
71 check(
72 r#"
73//- /main.rs crate:main deps:foo
74foo::structs!(Foo, Bar)
75mod bar;
76
77//- /bar.rs
78use crate::*;
79
80//- /lib.rs crate:foo
81#[macro_export]
82macro_rules! structs {
83 ($($i:ident),*) => {
84 $(struct $i { field: u32 } )*
85 }
86}
87"#,
88 expect![[r#"
89 crate
90 Bar: t
91 Foo: t
92 bar: t
93
94 crate::bar
95 Bar: t
96 Foo: t
97 bar: t
98 "#]],
99 );
100}
101
102#[test]
103fn macro_rules_export_with_local_inner_macros_are_visible() {
104 check(
105 r#"
106//- /main.rs crate:main deps:foo
107foo::structs!(Foo, Bar)
108mod bar;
109
110//- /bar.rs
111use crate::*;
112
113//- /lib.rs crate:foo
114#[macro_export(local_inner_macros)]
115macro_rules! structs {
116 ($($i:ident),*) => {
117 $(struct $i { field: u32 } )*
118 }
119}
120"#,
121 expect![[r#"
122 crate
123 Bar: t
124 Foo: t
125 bar: t
126
127 crate::bar
128 Bar: t
129 Foo: t
130 bar: t
131 "#]],
132 );
133}
134
135#[test]
136fn local_inner_macros_makes_local_macros_usable() {
137 check(
138 r#"
139//- /main.rs crate:main deps:foo
140foo::structs!(Foo, Bar);
141mod bar;
142
143//- /bar.rs
144use crate::*;
145
146//- /lib.rs crate:foo
147#[macro_export(local_inner_macros)]
148macro_rules! structs {
149 ($($i:ident),*) => {
150 inner!($($i),*);
151 }
152}
153#[macro_export]
154macro_rules! inner {
155 ($($i:ident),*) => {
156 $(struct $i { field: u32 } )*
157 }
158}
159"#,
160 expect![[r#"
161 crate
162 Bar: t
163 Foo: t
164 bar: t
165
166 crate::bar
167 Bar: t
168 Foo: t
169 bar: t
170 "#]],
171 );
172}
173
174#[test]
175fn unexpanded_macro_should_expand_by_fixedpoint_loop() {
176 check(
177 r#"
178//- /main.rs crate:main deps:foo
179macro_rules! baz {
180 () => {
181 use foo::bar;
182 }
183}
184foo!();
185bar!();
186baz!();
187
188//- /lib.rs crate:foo
189#[macro_export]
190macro_rules! foo {
191 () => {
192 struct Foo { field: u32 }
193 }
194}
195#[macro_export]
196macro_rules! bar {
197 () => {
198 use foo::foo;
199 }
200}
201"#,
202 expect![[r#"
203 crate
204 Foo: t
205 bar: m
206 foo: m
207 "#]],
208 );
209}
210
211#[test]
212fn macro_rules_from_other_crates_are_visible_with_macro_use() {
213 mark::check!(macro_rules_from_other_crates_are_visible_with_macro_use);
214 check(
215 r#"
216//- /main.rs crate:main deps:foo
217structs!(Foo);
218structs_priv!(Bar);
219structs_not_exported!(MacroNotResolved1);
220crate::structs!(MacroNotResolved2);
221
222mod bar;
223
224#[macro_use]
225extern crate foo;
226
227//- /bar.rs
228structs!(Baz);
229crate::structs!(MacroNotResolved3);
230
231//- /lib.rs crate:foo
232#[macro_export]
233macro_rules! structs {
234 ($i:ident) => { struct $i; }
235}
236
237macro_rules! structs_not_exported {
238 ($i:ident) => { struct $i; }
239}
240
241mod priv_mod {
242 #[macro_export]
243 macro_rules! structs_priv {
244 ($i:ident) => { struct $i; }
245 }
246}
247"#,
248 expect![[r#"
249 crate
250 Bar: t v
251 Foo: t v
252 bar: t
253 foo: t
254
255 crate::bar
256 Baz: t v
257 "#]],
258 );
259}
260
261#[test]
262fn prelude_is_macro_use() {
263 mark::check!(prelude_is_macro_use);
264 check(
265 r#"
266//- /main.rs crate:main deps:foo
267structs!(Foo);
268structs_priv!(Bar);
269structs_outside!(Out);
270crate::structs!(MacroNotResolved2);
271
272mod bar;
273
274//- /bar.rs
275structs!(Baz);
276crate::structs!(MacroNotResolved3);
277
278//- /lib.rs crate:foo
279#[prelude_import]
280use self::prelude::*;
281
282mod prelude {
283 #[macro_export]
284 macro_rules! structs {
285 ($i:ident) => { struct $i; }
286 }
287
288 mod priv_mod {
289 #[macro_export]
290 macro_rules! structs_priv {
291 ($i:ident) => { struct $i; }
292 }
293 }
294}
295
296#[macro_export]
297macro_rules! structs_outside {
298 ($i:ident) => { struct $i; }
299}
300"#,
301 expect![[r#"
302 crate
303 Bar: t v
304 Foo: t v
305 Out: t v
306 bar: t
307
308 crate::bar
309 Baz: t v
310 "#]],
311 );
312}
313
314#[test]
315fn prelude_cycle() {
316 check(
317 r#"
318#[prelude_import]
319use self::prelude::*;
320
321declare_mod!();
322
323mod prelude {
324 macro_rules! declare_mod {
325 () => (mod foo {})
326 }
327}
328"#,
329 expect![[r#"
330 crate
331 prelude: t
332
333 crate::prelude
334 "#]],
335 );
336}
337
338#[test]
339fn plain_macros_are_legacy_textual_scoped() {
340 check(
341 r#"
342//- /main.rs
343mod m1;
344bar!(NotFoundNotMacroUse);
345
346mod m2 { foo!(NotFoundBeforeInside2); }
347
348macro_rules! foo {
349 ($x:ident) => { struct $x; }
350}
351foo!(Ok);
352
353mod m3;
354foo!(OkShadowStop);
355bar!(NotFoundMacroUseStop);
356
357#[macro_use]
358mod m5 {
359 #[macro_use]
360 mod m6 {
361 macro_rules! foo {
362 ($x:ident) => { fn $x() {} }
363 }
364 }
365}
366foo!(ok_double_macro_use_shadow);
367
368baz!(NotFoundBefore);
369#[macro_use]
370mod m7 {
371 macro_rules! baz {
372 ($x:ident) => { struct $x; }
373 }
374}
375baz!(OkAfter);
376
377//- /m1.rs
378foo!(NotFoundBeforeInside1);
379macro_rules! bar {
380 ($x:ident) => { struct $x; }
381}
382
383//- /m3/mod.rs
384foo!(OkAfterInside);
385macro_rules! foo {
386 ($x:ident) => { fn $x() {} }
387}
388foo!(ok_shadow);
389
390#[macro_use]
391mod m4;
392bar!(OkMacroUse);
393
394//- /m3/m4.rs
395foo!(ok_shadow_deep);
396macro_rules! bar {
397 ($x:ident) => { struct $x; }
398}
399"#,
400 expect![[r#"
401 crate
402 Ok: t v
403 OkAfter: t v
404 OkShadowStop: t v
405 m1: t
406 m2: t
407 m3: t
408 m5: t
409 m7: t
410 ok_double_macro_use_shadow: v
411
412 crate::m7
413
414 crate::m1
415
416 crate::m5
417 m6: t
418
419 crate::m5::m6
420
421 crate::m2
422
423 crate::m3
424 OkAfterInside: t v
425 OkMacroUse: t v
426 m4: t
427 ok_shadow: v
428
429 crate::m3::m4
430 ok_shadow_deep: v
431 "#]],
432 );
433}
434
435#[test]
436fn type_value_macro_live_in_different_scopes() {
437 check(
438 r#"
439#[macro_export]
440macro_rules! foo {
441 ($x:ident) => { type $x = (); }
442}
443
444foo!(foo);
445use foo as bar;
446
447use self::foo as baz;
448fn baz() {}
449"#,
450 expect![[r#"
451 crate
452 bar: t m
453 baz: t v m
454 foo: t m
455 "#]],
456 );
457}
458
459#[test]
460fn macro_use_can_be_aliased() {
461 check(
462 r#"
463//- /main.rs crate:main deps:foo
464#[macro_use]
465extern crate foo;
466
467foo!(Direct);
468bar!(Alias);
469
470//- /lib.rs crate:foo
471use crate::foo as bar;
472
473mod m {
474 #[macro_export]
475 macro_rules! foo {
476 ($x:ident) => { struct $x; }
477 }
478}
479"#,
480 expect![[r#"
481 crate
482 Alias: t v
483 Direct: t v
484 foo: t
485 "#]],
486 );
487}
488
489#[test]
490fn path_qualified_macros() {
491 check(
492 r#"
493macro_rules! foo {
494 ($x:ident) => { struct $x; }
495}
496
497crate::foo!(NotResolved);
498
499crate::bar!(OkCrate);
500bar!(OkPlain);
501alias1!(NotHere);
502m::alias1!(OkAliasPlain);
503m::alias2!(OkAliasSuper);
504m::alias3!(OkAliasCrate);
505not_found!(NotFound);
506
507mod m {
508 #[macro_export]
509 macro_rules! bar {
510 ($x:ident) => { struct $x; }
511 }
512 pub use bar as alias1;
513 pub use super::bar as alias2;
514 pub use crate::bar as alias3;
515 pub use self::bar as not_found;
516}
517"#,
518 expect![[r#"
519 crate
520 OkAliasCrate: t v
521 OkAliasPlain: t v
522 OkAliasSuper: t v
523 OkCrate: t v
524 OkPlain: t v
525 bar: m
526 m: t
527
528 crate::m
529 alias1: m
530 alias2: m
531 alias3: m
532 not_found: _
533 "#]],
534 );
535}
536
537#[test]
538fn macro_dollar_crate_is_correct_in_item() {
539 mark::check!(macro_dollar_crate_self);
540 check(
541 r#"
542//- /main.rs crate:main deps:foo
543#[macro_use]
544extern crate foo;
545
546#[macro_use]
547mod m {
548 macro_rules! current {
549 () => {
550 use $crate::Foo as FooSelf;
551 }
552 }
553}
554
555struct Foo;
556
557current!();
558not_current1!();
559foo::not_current2!();
560
561//- /lib.rs crate:foo
562mod m {
563 #[macro_export]
564 macro_rules! not_current1 {
565 () => {
566 use $crate::Bar;
567 }
568 }
569}
570
571#[macro_export]
572macro_rules! not_current2 {
573 () => {
574 use $crate::Baz;
575 }
576}
577
578struct Bar;
579struct Baz;
580"#,
581 expect![[r#"
582 crate
583 Bar: t v
584 Baz: t v
585 Foo: t v
586 FooSelf: t v
587 foo: t
588 m: t
589
590 crate::m
591 "#]],
592 );
593}
594
595#[test]
596fn macro_dollar_crate_is_correct_in_indirect_deps() {
597 mark::check!(macro_dollar_crate_other);
598 // From std
599 check(
600 r#"
601//- /main.rs crate:main deps:std
602foo!();
603
604//- /std.rs crate:std deps:core
605#[prelude_import]
606use self::prelude::*;
607
608pub use core::foo;
609
610mod prelude {}
611
612#[macro_use]
613mod std_macros;
614
615//- /core.rs crate:core
616#[macro_export]
617macro_rules! foo {
618 () => {
619 use $crate::bar;
620 }
621}
622
623pub struct bar;
624"#,
625 expect![[r#"
626 crate
627 bar: t v
628 "#]],
629 );
630}
631
632#[test]
633fn expand_derive() {
634 let map = compute_crate_def_map(
635 "
636 //- /main.rs
637 #[derive(Copy, Clone)]
638 struct Foo;
639 ",
640 );
641 assert_eq!(map.modules[map.root].scope.impls().len(), 2);
642}
643
644#[test]
645fn macro_expansion_overflow() {
646 mark::check!(macro_expansion_overflow);
647 check(
648 r#"
649macro_rules! a {
650 ($e:expr; $($t:tt)*) => {
651 b!($($t)*);
652 };
653 () => {};
654}
655
656macro_rules! b {
657 (static = $e:expr; $($t:tt)*) => {
658 a!($e; $($t)*);
659 };
660 () => {};
661}
662
663b! { static = #[] (); }
664"#,
665 expect![[r#"
666 crate
667 "#]],
668 );
669}
diff --git a/crates/hir_def/src/nameres/tests/mod_resolution.rs b/crates/hir_def/src/nameres/tests/mod_resolution.rs
new file mode 100644
index 000000000..1f619787e
--- /dev/null
+++ b/crates/hir_def/src/nameres/tests/mod_resolution.rs
@@ -0,0 +1,796 @@
1use super::*;
2
3#[test]
4fn name_res_works_for_broken_modules() {
5 mark::check!(name_res_works_for_broken_modules);
6 check(
7 r"
8//- /lib.rs
9mod foo // no `;`, no body
10use self::foo::Baz;
11
12//- /foo/mod.rs
13pub mod bar;
14pub use self::bar::Baz;
15
16//- /foo/bar.rs
17pub struct Baz;
18",
19 expect![[r#"
20 crate
21 Baz: _
22 foo: t
23
24 crate::foo
25 "#]],
26 );
27}
28
29#[test]
30fn nested_module_resolution() {
31 check(
32 r#"
33//- /lib.rs
34mod n1;
35
36//- /n1.rs
37mod n2;
38
39//- /n1/n2.rs
40struct X;
41"#,
42 expect![[r#"
43 crate
44 n1: t
45
46 crate::n1
47 n2: t
48
49 crate::n1::n2
50 X: t v
51 "#]],
52 );
53}
54
55#[test]
56fn nested_module_resolution_2() {
57 check(
58 r#"
59//- /lib.rs
60mod prelude;
61mod iter;
62
63//- /prelude.rs
64pub use crate::iter::Iterator;
65
66//- /iter.rs
67pub use self::traits::Iterator;
68mod traits;
69
70//- /iter/traits.rs
71pub use self::iterator::Iterator;
72mod iterator;
73
74//- /iter/traits/iterator.rs
75pub trait Iterator;
76"#,
77 expect![[r#"
78 crate
79 iter: t
80 prelude: t
81
82 crate::iter
83 Iterator: t
84 traits: t
85
86 crate::iter::traits
87 Iterator: t
88 iterator: t
89
90 crate::iter::traits::iterator
91 Iterator: t
92
93 crate::prelude
94 Iterator: t
95 "#]],
96 );
97}
98
99#[test]
100fn module_resolution_works_for_non_standard_filenames() {
101 check(
102 r#"
103//- /my_library.rs crate:my_library
104mod foo;
105use self::foo::Bar;
106
107//- /foo/mod.rs
108pub struct Bar;
109"#,
110 expect![[r#"
111 crate
112 Bar: t v
113 foo: t
114
115 crate::foo
116 Bar: t v
117 "#]],
118 );
119}
120
121#[test]
122fn module_resolution_works_for_raw_modules() {
123 check(
124 r#"
125//- /lib.rs
126mod r#async;
127use self::r#async::Bar;
128
129//- /async.rs
130pub struct Bar;
131"#,
132 expect![[r#"
133 crate
134 Bar: t v
135 async: t
136
137 crate::async
138 Bar: t v
139 "#]],
140 );
141}
142
143#[test]
144fn module_resolution_decl_path() {
145 check(
146 r#"
147//- /lib.rs
148#[path = "bar/baz/foo.rs"]
149mod foo;
150use self::foo::Bar;
151
152//- /bar/baz/foo.rs
153pub struct Bar;
154"#,
155 expect![[r#"
156 crate
157 Bar: t v
158 foo: t
159
160 crate::foo
161 Bar: t v
162 "#]],
163 );
164}
165
166#[test]
167fn module_resolution_module_with_path_in_mod_rs() {
168 check(
169 r#"
170//- /main.rs
171mod foo;
172
173//- /foo/mod.rs
174#[path = "baz.rs"]
175pub mod bar;
176use self::bar::Baz;
177
178//- /foo/baz.rs
179pub struct Baz;
180"#,
181 expect![[r#"
182 crate
183 foo: t
184
185 crate::foo
186 Baz: t v
187 bar: t
188
189 crate::foo::bar
190 Baz: t v
191 "#]],
192 );
193}
194
195#[test]
196fn module_resolution_module_with_path_non_crate_root() {
197 check(
198 r#"
199//- /main.rs
200mod foo;
201
202//- /foo.rs
203#[path = "baz.rs"]
204pub mod bar;
205use self::bar::Baz;
206
207//- /baz.rs
208pub struct Baz;
209"#,
210 expect![[r#"
211 crate
212 foo: t
213
214 crate::foo
215 Baz: t v
216 bar: t
217
218 crate::foo::bar
219 Baz: t v
220 "#]],
221 );
222}
223
224#[test]
225fn module_resolution_module_decl_path_super() {
226 check(
227 r#"
228//- /main.rs
229#[path = "bar/baz/module.rs"]
230mod foo;
231pub struct Baz;
232
233//- /bar/baz/module.rs
234use super::Baz;
235"#,
236 expect![[r#"
237 crate
238 Baz: t v
239 foo: t
240
241 crate::foo
242 Baz: t v
243 "#]],
244 );
245}
246
247#[test]
248fn module_resolution_explicit_path_mod_rs() {
249 check(
250 r#"
251//- /main.rs
252#[path = "module/mod.rs"]
253mod foo;
254
255//- /module/mod.rs
256pub struct Baz;
257"#,
258 expect![[r#"
259 crate
260 foo: t
261
262 crate::foo
263 Baz: t v
264 "#]],
265 );
266}
267
268#[test]
269fn module_resolution_relative_path() {
270 check(
271 r#"
272//- /main.rs
273mod foo;
274
275//- /foo.rs
276#[path = "./sub.rs"]
277pub mod foo_bar;
278
279//- /sub.rs
280pub struct Baz;
281"#,
282 expect![[r#"
283 crate
284 foo: t
285
286 crate::foo
287 foo_bar: t
288
289 crate::foo::foo_bar
290 Baz: t v
291 "#]],
292 );
293}
294
295#[test]
296fn module_resolution_relative_path_2() {
297 check(
298 r#"
299//- /main.rs
300mod foo;
301
302//- /foo/mod.rs
303#[path="../sub.rs"]
304pub mod foo_bar;
305
306//- /sub.rs
307pub struct Baz;
308"#,
309 expect![[r#"
310 crate
311 foo: t
312
313 crate::foo
314 foo_bar: t
315
316 crate::foo::foo_bar
317 Baz: t v
318 "#]],
319 );
320}
321
322#[test]
323fn module_resolution_relative_path_outside_root() {
324 check(
325 r#"
326//- /main.rs
327#[path="../../../../../outside.rs"]
328mod foo;
329"#,
330 expect![[r#"
331 crate
332 "#]],
333 );
334}
335
336#[test]
337fn module_resolution_explicit_path_mod_rs_2() {
338 check(
339 r#"
340//- /main.rs
341#[path = "module/bar/mod.rs"]
342mod foo;
343
344//- /module/bar/mod.rs
345pub struct Baz;
346"#,
347 expect![[r#"
348 crate
349 foo: t
350
351 crate::foo
352 Baz: t v
353 "#]],
354 );
355}
356
357#[test]
358fn module_resolution_explicit_path_mod_rs_with_win_separator() {
359 check(
360 r#"
361//- /main.rs
362#[path = "module\bar\mod.rs"]
363mod foo;
364
365//- /module/bar/mod.rs
366pub struct Baz;
367"#,
368 expect![[r#"
369 crate
370 foo: t
371
372 crate::foo
373 Baz: t v
374 "#]],
375 );
376}
377
378#[test]
379fn module_resolution_decl_inside_inline_module_with_path_attribute() {
380 check(
381 r#"
382//- /main.rs
383#[path = "models"]
384mod foo { mod bar; }
385
386//- /models/bar.rs
387pub struct Baz;
388"#,
389 expect![[r#"
390 crate
391 foo: t
392
393 crate::foo
394 bar: t
395
396 crate::foo::bar
397 Baz: t v
398 "#]],
399 );
400}
401
402#[test]
403fn module_resolution_decl_inside_inline_module() {
404 check(
405 r#"
406//- /main.rs
407mod foo { mod bar; }
408
409//- /foo/bar.rs
410pub struct Baz;
411"#,
412 expect![[r#"
413 crate
414 foo: t
415
416 crate::foo
417 bar: t
418
419 crate::foo::bar
420 Baz: t v
421 "#]],
422 );
423}
424
425#[test]
426fn module_resolution_decl_inside_inline_module_2_with_path_attribute() {
427 check(
428 r#"
429//- /main.rs
430#[path = "models/db"]
431mod foo { mod bar; }
432
433//- /models/db/bar.rs
434pub struct Baz;
435"#,
436 expect![[r#"
437 crate
438 foo: t
439
440 crate::foo
441 bar: t
442
443 crate::foo::bar
444 Baz: t v
445 "#]],
446 );
447}
448
449#[test]
450fn module_resolution_decl_inside_inline_module_3() {
451 check(
452 r#"
453//- /main.rs
454#[path = "models/db"]
455mod foo {
456 #[path = "users.rs"]
457 mod bar;
458}
459
460//- /models/db/users.rs
461pub struct Baz;
462"#,
463 expect![[r#"
464 crate
465 foo: t
466
467 crate::foo
468 bar: t
469
470 crate::foo::bar
471 Baz: t v
472 "#]],
473 );
474}
475
476#[test]
477fn module_resolution_decl_inside_inline_module_empty_path() {
478 check(
479 r#"
480//- /main.rs
481#[path = ""]
482mod foo {
483 #[path = "users.rs"]
484 mod bar;
485}
486
487//- /users.rs
488pub struct Baz;
489"#,
490 expect![[r#"
491 crate
492 foo: t
493
494 crate::foo
495 bar: t
496
497 crate::foo::bar
498 Baz: t v
499 "#]],
500 );
501}
502
503#[test]
504fn module_resolution_decl_empty_path() {
505 check(
506 r#"
507//- /main.rs
508#[path = ""] // Should try to read `/` (a directory)
509mod foo;
510
511//- /foo.rs
512pub struct Baz;
513"#,
514 expect![[r#"
515 crate
516 "#]],
517 );
518}
519
520#[test]
521fn module_resolution_decl_inside_inline_module_relative_path() {
522 check(
523 r#"
524//- /main.rs
525#[path = "./models"]
526mod foo { mod bar; }
527
528//- /models/bar.rs
529pub struct Baz;
530"#,
531 expect![[r#"
532 crate
533 foo: t
534
535 crate::foo
536 bar: t
537
538 crate::foo::bar
539 Baz: t v
540 "#]],
541 );
542}
543
544#[test]
545fn module_resolution_decl_inside_inline_module_in_crate_root() {
546 check(
547 r#"
548//- /main.rs
549mod foo {
550 #[path = "baz.rs"]
551 mod bar;
552}
553use self::foo::bar::Baz;
554
555//- /foo/baz.rs
556pub struct Baz;
557"#,
558 expect![[r#"
559 crate
560 Baz: t v
561 foo: t
562
563 crate::foo
564 bar: t
565
566 crate::foo::bar
567 Baz: t v
568 "#]],
569 );
570}
571
572#[test]
573fn module_resolution_decl_inside_inline_module_in_mod_rs() {
574 check(
575 r#"
576//- /main.rs
577mod foo;
578
579//- /foo/mod.rs
580mod bar {
581 #[path = "qwe.rs"]
582 pub mod baz;
583}
584use self::bar::baz::Baz;
585
586//- /foo/bar/qwe.rs
587pub struct Baz;
588"#,
589 expect![[r#"
590 crate
591 foo: t
592
593 crate::foo
594 Baz: t v
595 bar: t
596
597 crate::foo::bar
598 baz: t
599
600 crate::foo::bar::baz
601 Baz: t v
602 "#]],
603 );
604}
605
606#[test]
607fn module_resolution_decl_inside_inline_module_in_non_crate_root() {
608 check(
609 r#"
610//- /main.rs
611mod foo;
612
613//- /foo.rs
614mod bar {
615 #[path = "qwe.rs"]
616 pub mod baz;
617}
618use self::bar::baz::Baz;
619
620//- /foo/bar/qwe.rs
621pub struct Baz;
622"#,
623 expect![[r#"
624 crate
625 foo: t
626
627 crate::foo
628 Baz: t v
629 bar: t
630
631 crate::foo::bar
632 baz: t
633
634 crate::foo::bar::baz
635 Baz: t v
636 "#]],
637 );
638}
639
640#[test]
641fn module_resolution_decl_inside_inline_module_in_non_crate_root_2() {
642 check(
643 r#"
644//- /main.rs
645mod foo;
646
647//- /foo.rs
648#[path = "bar"]
649mod bar {
650 pub mod baz;
651}
652use self::bar::baz::Baz;
653
654//- /bar/baz.rs
655pub struct Baz;
656"#,
657 expect![[r#"
658 crate
659 foo: t
660
661 crate::foo
662 Baz: t v
663 bar: t
664
665 crate::foo::bar
666 baz: t
667
668 crate::foo::bar::baz
669 Baz: t v
670 "#]],
671 );
672}
673
674#[test]
675fn unresolved_module_diagnostics() {
676 let db = TestDB::with_files(
677 r"
678 //- /lib.rs
679 mod foo;
680 mod bar;
681 mod baz {}
682 //- /foo.rs
683 ",
684 );
685 let krate = db.test_crate();
686
687 let crate_def_map = db.crate_def_map(krate);
688
689 expect![[r#"
690 [
691 UnresolvedModule {
692 module: Idx::<ModuleData>(0),
693 declaration: InFile {
694 file_id: HirFileId(
695 FileId(
696 FileId(
697 0,
698 ),
699 ),
700 ),
701 value: FileAstId::<syntax::ast::generated::nodes::Module>(1),
702 },
703 candidate: "bar.rs",
704 },
705 ]
706 "#]]
707 .assert_debug_eq(&crate_def_map.diagnostics);
708}
709
710#[test]
711fn module_resolution_decl_inside_module_in_non_crate_root_2() {
712 check(
713 r#"
714//- /main.rs
715#[path="module/m2.rs"]
716mod module;
717
718//- /module/m2.rs
719pub mod submod;
720
721//- /module/submod.rs
722pub struct Baz;
723"#,
724 expect![[r#"
725 crate
726 module: t
727
728 crate::module
729 submod: t
730
731 crate::module::submod
732 Baz: t v
733 "#]],
734 );
735}
736
737#[test]
738fn nested_out_of_line_module() {
739 check(
740 r#"
741//- /lib.rs
742mod a {
743 mod b {
744 mod c;
745 }
746}
747
748//- /a/b/c.rs
749struct X;
750"#,
751 expect![[r#"
752 crate
753 a: t
754
755 crate::a
756 b: t
757
758 crate::a::b
759 c: t
760
761 crate::a::b::c
762 X: t v
763 "#]],
764 );
765}
766
767#[test]
768fn nested_out_of_line_module_with_path() {
769 check(
770 r#"
771//- /lib.rs
772mod a {
773 #[path = "d/e"]
774 mod b {
775 mod c;
776 }
777}
778
779//- /a/d/e/c.rs
780struct X;
781"#,
782 expect![[r#"
783 crate
784 a: t
785
786 crate::a
787 b: t
788
789 crate::a::b
790 c: t
791
792 crate::a::b::c
793 X: t v
794 "#]],
795 );
796}
diff --git a/crates/hir_def/src/nameres/tests/primitives.rs b/crates/hir_def/src/nameres/tests/primitives.rs
new file mode 100644
index 000000000..215e8952d
--- /dev/null
+++ b/crates/hir_def/src/nameres/tests/primitives.rs
@@ -0,0 +1,23 @@
1use super::*;
2
3#[test]
4fn primitive_reexport() {
5 check(
6 r#"
7//- /lib.rs
8mod foo;
9use foo::int;
10
11//- /foo.rs
12pub use i32 as int;
13"#,
14 expect![[r#"
15 crate
16 foo: t
17 int: t
18
19 crate::foo
20 int: t
21 "#]],
22 );
23}