aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def')
-rw-r--r--crates/ra_hir_def/Cargo.toml4
-rw-r--r--crates/ra_hir_def/src/nameres.rs3
-rw-r--r--crates/ra_hir_def/src/nameres/tests.rs522
-rw-r--r--crates/ra_hir_def/src/nameres/tests/globs.rs114
-rw-r--r--crates/ra_hir_def/src/nameres/tests/incremental.rs133
-rw-r--r--crates/ra_hir_def/src/nameres/tests/macros.rs602
-rw-r--r--crates/ra_hir_def/src/nameres/tests/mod_resolution.rs782
-rw-r--r--crates/ra_hir_def/src/nameres/tests/primitives.rs24
-rw-r--r--crates/ra_hir_def/src/test_db.rs36
9 files changed, 2219 insertions, 1 deletions
diff --git a/crates/ra_hir_def/Cargo.toml b/crates/ra_hir_def/Cargo.toml
index 746c907e8..15055db64 100644
--- a/crates/ra_hir_def/Cargo.toml
+++ b/crates/ra_hir_def/Cargo.toml
@@ -19,3 +19,7 @@ test_utils = { path = "../test_utils" }
19mbe = { path = "../ra_mbe", package = "ra_mbe" } 19mbe = { path = "../ra_mbe", package = "ra_mbe" }
20ra_cfg = { path = "../ra_cfg" } 20ra_cfg = { path = "../ra_cfg" }
21tt = { path = "../ra_tt", package = "ra_tt" } 21tt = { path = "../ra_tt", package = "ra_tt" }
22
23[dev-dependencies]
24insta = "0.12.0"
25
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs
index db59344aa..b3640da3d 100644
--- a/crates/ra_hir_def/src/nameres.rs
+++ b/crates/ra_hir_def/src/nameres.rs
@@ -6,6 +6,9 @@ pub mod per_ns;
6pub mod collector; 6pub mod collector;
7pub mod mod_resolution; 7pub mod mod_resolution;
8 8
9#[cfg(test)]
10mod tests;
11
9use std::sync::Arc; 12use std::sync::Arc;
10 13
11use hir_expand::{diagnostics::DiagnosticSink, name::Name, MacroDefId}; 14use hir_expand::{diagnostics::DiagnosticSink, name::Name, MacroDefId};
diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs
new file mode 100644
index 000000000..f9a8edd43
--- /dev/null
+++ b/crates/ra_hir_def/src/nameres/tests.rs
@@ -0,0 +1,522 @@
1mod globs;
2mod incremental;
3mod macros;
4mod mod_resolution;
5mod primitives;
6
7use std::sync::Arc;
8
9use insta::assert_snapshot;
10use ra_db::{fixture::WithFixture, SourceDatabase};
11// use test_utils::covers;
12
13use crate::{db::DefDatabase2, nameres::*, test_db::TestDB, CrateModuleId};
14
15fn def_map(fixtute: &str) -> String {
16 let dm = compute_crate_def_map(fixtute);
17 render_crate_def_map(&dm)
18}
19
20fn compute_crate_def_map(fixture: &str) -> Arc<CrateDefMap> {
21 let db = TestDB::with_files(fixture);
22 let krate = db.crate_graph().iter().next().unwrap();
23 db.crate_def_map(krate)
24}
25
26fn render_crate_def_map(map: &CrateDefMap) -> String {
27 let mut buf = String::new();
28 go(&mut buf, map, "\ncrate", map.root());
29 return buf.trim().to_string();
30
31 fn go(buf: &mut String, map: &CrateDefMap, path: &str, module: CrateModuleId) {
32 *buf += path;
33 *buf += "\n";
34
35 let mut entries = map.modules[module]
36 .scope
37 .items
38 .iter()
39 .map(|(name, res)| (name, res.def))
40 .collect::<Vec<_>>();
41 entries.sort_by_key(|(name, _)| *name);
42
43 for (name, res) in entries {
44 *buf += &format!("{}:", name);
45
46 if res.types.is_some() {
47 *buf += " t";
48 }
49 if res.values.is_some() {
50 *buf += " v";
51 }
52 if res.macros.is_some() {
53 *buf += " m";
54 }
55 if res.is_none() {
56 *buf += " _";
57 }
58
59 *buf += "\n";
60 }
61
62 for (name, child) in map.modules[module].children.iter() {
63 let path = path.to_string() + &format!("::{}", name);
64 go(buf, map, &path, *child);
65 }
66 }
67}
68
69#[test]
70fn crate_def_map_smoke_test() {
71 let map = def_map(
72 "
73 //- /lib.rs
74 mod foo;
75 struct S;
76 use crate::foo::bar::E;
77 use self::E::V;
78
79 //- /foo/mod.rs
80 pub mod bar;
81 fn f() {}
82
83 //- /foo/bar.rs
84 pub struct Baz;
85 enum E { V }
86 ",
87 );
88 assert_snapshot!(map, @r###"
89 ⋮crate
90 ⋮E: t
91 ⋮S: t v
92 ⋮V: t v
93 ⋮foo: t
94
95 ⋮crate::foo
96 ⋮bar: t
97 ⋮f: v
98
99 ⋮crate::foo::bar
100 ⋮Baz: t v
101 ⋮E: t
102 "###)
103}
104
105#[test]
106fn bogus_paths() {
107 // covers!(bogus_paths);
108 let map = def_map(
109 "
110 //- /lib.rs
111 mod foo;
112 struct S;
113 use self;
114
115 //- /foo/mod.rs
116 use super;
117 use crate;
118
119 ",
120 );
121 assert_snapshot!(map, @r###"
122 ⋮crate
123 ⋮S: t v
124 ⋮foo: t
125
126 ⋮crate::foo
127 "###
128 )
129}
130
131#[test]
132fn use_as() {
133 let map = def_map(
134 "
135 //- /lib.rs
136 mod foo;
137
138 use crate::foo::Baz as Foo;
139
140 //- /foo/mod.rs
141 pub struct Baz;
142 ",
143 );
144 assert_snapshot!(map,
145 @r###"
146 ⋮crate
147 ⋮Foo: t v
148 ⋮foo: t
149
150 ⋮crate::foo
151 ⋮Baz: t v
152 "###
153 );
154}
155
156#[test]
157fn use_trees() {
158 let map = def_map(
159 "
160 //- /lib.rs
161 mod foo;
162
163 use crate::foo::bar::{Baz, Quux};
164
165 //- /foo/mod.rs
166 pub mod bar;
167
168 //- /foo/bar.rs
169 pub struct Baz;
170 pub enum Quux {};
171 ",
172 );
173 assert_snapshot!(map, @r###"
174 ⋮crate
175 ⋮Baz: t v
176 ⋮Quux: t
177 ⋮foo: t
178
179 ⋮crate::foo
180 ⋮bar: t
181
182 ⋮crate::foo::bar
183 ⋮Baz: t v
184 ⋮Quux: t
185 "###);
186}
187
188#[test]
189fn re_exports() {
190 let map = def_map(
191 "
192 //- /lib.rs
193 mod foo;
194
195 use self::foo::Baz;
196
197 //- /foo/mod.rs
198 pub mod bar;
199
200 pub use self::bar::Baz;
201
202 //- /foo/bar.rs
203 pub struct Baz;
204 ",
205 );
206 assert_snapshot!(map, @r###"
207 ⋮crate
208 ⋮Baz: t v
209 ⋮foo: t
210
211 ⋮crate::foo
212 ⋮Baz: t v
213 ⋮bar: t
214
215 ⋮crate::foo::bar
216 ⋮Baz: t v
217 "###);
218}
219
220#[test]
221fn std_prelude() {
222 // covers!(std_prelude);
223 let map = def_map(
224 "
225 //- /main.rs crate:main deps:test_crate
226 use Foo::*;
227
228 //- /lib.rs crate:test_crate
229 mod prelude;
230 #[prelude_import]
231 use prelude::*;
232
233 //- /prelude.rs
234 pub enum Foo { Bar, Baz };
235 ",
236 );
237 assert_snapshot!(map, @r###"
238 ⋮crate
239 ⋮Bar: t v
240 ⋮Baz: t v
241 "###);
242}
243
244#[test]
245fn can_import_enum_variant() {
246 // covers!(can_import_enum_variant);
247 let map = def_map(
248 "
249 //- /lib.rs
250 enum E { V }
251 use self::E::V;
252 ",
253 );
254 assert_snapshot!(map, @r###"
255 ⋮crate
256 ⋮E: t
257 ⋮V: t v
258 "###
259 );
260}
261
262#[test]
263fn edition_2015_imports() {
264 let map = def_map(
265 "
266 //- /main.rs crate:main deps:other_crate edition:2015
267 mod foo;
268 mod bar;
269
270 //- /bar.rs
271 struct Bar;
272
273 //- /foo.rs
274 use bar::Bar;
275 use other_crate::FromLib;
276
277 //- /lib.rs crate:other_crate edition:2018
278 struct FromLib;
279 ",
280 );
281
282 assert_snapshot!(map, @r###"
283 ⋮crate
284 ⋮bar: t
285 ⋮foo: t
286
287 ⋮crate::bar
288 ⋮Bar: t v
289
290 ⋮crate::foo
291 ⋮Bar: t v
292 ⋮FromLib: t v
293 "###);
294}
295
296#[test]
297fn item_map_using_self() {
298 let map = def_map(
299 "
300 //- /lib.rs
301 mod foo;
302 use crate::foo::bar::Baz::{self};
303 //- /foo/mod.rs
304 pub mod bar;
305 //- /foo/bar.rs
306 pub struct Baz;
307 ",
308 );
309 assert_snapshot!(map, @r###"
310 ⋮crate
311 ⋮Baz: t v
312 ⋮foo: t
313
314 ⋮crate::foo
315 ⋮bar: t
316
317 ⋮crate::foo::bar
318 ⋮Baz: t v
319 "###);
320}
321
322#[test]
323fn item_map_across_crates() {
324 let map = def_map(
325 "
326 //- /main.rs crate:main deps:test_crate
327 use test_crate::Baz;
328
329 //- /lib.rs crate:test_crate
330 pub struct Baz;
331 ",
332 );
333
334 assert_snapshot!(map, @r###"
335 ⋮crate
336 ⋮Baz: t v
337 "###);
338}
339
340#[test]
341fn extern_crate_rename() {
342 let map = def_map(
343 "
344 //- /main.rs crate:main deps:alloc
345 extern crate alloc as alloc_crate;
346
347 mod alloc;
348 mod sync;
349
350 //- /sync.rs
351 use alloc_crate::Arc;
352
353 //- /lib.rs crate:alloc
354 struct Arc;
355 ",
356 );
357
358 assert_snapshot!(map, @r###"
359 ⋮crate
360 ⋮alloc_crate: t
361 ⋮sync: t
362
363 ⋮crate::sync
364 ⋮Arc: t v
365 "###);
366}
367
368#[test]
369fn extern_crate_rename_2015_edition() {
370 let map = def_map(
371 "
372 //- /main.rs crate:main deps:alloc edition:2015
373 extern crate alloc as alloc_crate;
374
375 mod alloc;
376 mod sync;
377
378 //- /sync.rs
379 use alloc_crate::Arc;
380
381 //- /lib.rs crate:alloc
382 struct Arc;
383 ",
384 );
385
386 assert_snapshot!(map,
387 @r###"
388 ⋮crate
389 ⋮alloc_crate: t
390 ⋮sync: t
391
392 ⋮crate::sync
393 ⋮Arc: t v
394 "###
395 );
396}
397
398#[test]
399fn import_across_source_roots() {
400 let map = def_map(
401 "
402 //- /main.rs crate:main deps:test_crate
403 use test_crate::a::b::C;
404
405 //- root /test_crate/
406
407 //- /test_crate/lib.rs crate:test_crate
408 pub mod a {
409 pub mod b {
410 pub struct C;
411 }
412 }
413
414 ",
415 );
416
417 assert_snapshot!(map, @r###"
418 ⋮crate
419 ⋮C: t v
420 "###);
421}
422
423#[test]
424fn reexport_across_crates() {
425 let map = def_map(
426 "
427 //- /main.rs crate:main deps:test_crate
428 use test_crate::Baz;
429
430 //- /lib.rs crate:test_crate
431 pub use foo::Baz;
432
433 mod foo;
434
435 //- /foo.rs
436 pub struct Baz;
437 ",
438 );
439
440 assert_snapshot!(map, @r###"
441 ⋮crate
442 ⋮Baz: t v
443 "###);
444}
445
446#[test]
447fn values_dont_shadow_extern_crates() {
448 let map = def_map(
449 "
450 //- /main.rs crate:main deps:foo
451 fn foo() {}
452 use foo::Bar;
453
454 //- /foo/lib.rs crate:foo
455 pub struct Bar;
456 ",
457 );
458
459 assert_snapshot!(map, @r###"
460 ⋮crate
461 ⋮Bar: t v
462 ⋮foo: v
463 "###);
464}
465
466#[test]
467fn cfg_not_test() {
468 let map = def_map(
469 r#"
470 //- /main.rs crate:main deps:std
471 use {Foo, Bar, Baz};
472
473 //- /lib.rs crate:std
474 #[prelude_import]
475 pub use self::prelude::*;
476 mod prelude {
477 #[cfg(test)]
478 pub struct Foo;
479 #[cfg(not(test))]
480 pub struct Bar;
481 #[cfg(all(not(any()), feature = "foo", feature = "bar", opt = "42"))]
482 pub struct Baz;
483 }
484 "#,
485 );
486
487 assert_snapshot!(map, @r###"
488 ⋮crate
489 ⋮Bar: t v
490 ⋮Baz: _
491 ⋮Foo: _
492 "###);
493}
494
495#[test]
496fn cfg_test() {
497 let map = def_map(
498 r#"
499 //- /main.rs crate:main deps:std
500 use {Foo, Bar, Baz};
501
502 //- /lib.rs crate:std cfg:test,feature=foo,feature=bar,opt=42
503 #[prelude_import]
504 pub use self::prelude::*;
505 mod prelude {
506 #[cfg(test)]
507 pub struct Foo;
508 #[cfg(not(test))]
509 pub struct Bar;
510 #[cfg(all(not(any()), feature = "foo", feature = "bar", opt = "42"))]
511 pub struct Baz;
512 }
513 "#,
514 );
515
516 assert_snapshot!(map, @r###"
517 ⋮crate
518 ⋮Bar: _
519 ⋮Baz: t v
520 ⋮Foo: t v
521 "###);
522}
diff --git a/crates/ra_hir_def/src/nameres/tests/globs.rs b/crates/ra_hir_def/src/nameres/tests/globs.rs
new file mode 100644
index 000000000..cf4a2a851
--- /dev/null
+++ b/crates/ra_hir_def/src/nameres/tests/globs.rs
@@ -0,0 +1,114 @@
1use super::*;
2
3#[test]
4fn glob_1() {
5 let map = def_map(
6 "
7 //- /lib.rs
8 mod foo;
9 use foo::*;
10
11 //- /foo/mod.rs
12 pub mod bar;
13 pub use self::bar::Baz;
14 pub struct Foo;
15
16 //- /foo/bar.rs
17 pub struct Baz;
18 ",
19 );
20 assert_snapshot!(map, @r###"
21 ⋮crate
22 ⋮Baz: t v
23 ⋮Foo: t v
24 ⋮bar: t
25 ⋮foo: t
26
27 ⋮crate::foo
28 ⋮Baz: t v
29 ⋮Foo: t v
30 ⋮bar: t
31
32 ⋮crate::foo::bar
33 ⋮Baz: t v
34 "###
35 );
36}
37
38#[test]
39fn glob_2() {
40 let map = def_map(
41 "
42 //- /lib.rs
43 mod foo;
44 use foo::*;
45
46 //- /foo/mod.rs
47 pub mod bar;
48 pub use self::bar::*;
49 pub struct Foo;
50
51 //- /foo/bar.rs
52 pub struct Baz;
53 pub use super::*;
54 ",
55 );
56 assert_snapshot!(map, @r###"
57 ⋮crate
58 ⋮Baz: t v
59 ⋮Foo: t v
60 ⋮bar: t
61 ⋮foo: t
62
63 ⋮crate::foo
64 ⋮Baz: t v
65 ⋮Foo: t v
66 ⋮bar: t
67
68 ⋮crate::foo::bar
69 ⋮Baz: t v
70 ⋮Foo: t v
71 ⋮bar: t
72 "###
73 );
74}
75
76#[test]
77fn glob_across_crates() {
78 // covers!(glob_across_crates);
79 let map = def_map(
80 "
81 //- /main.rs crate:main deps:test_crate
82 use test_crate::*;
83
84 //- /lib.rs crate:test_crate
85 pub struct Baz;
86 ",
87 );
88 assert_snapshot!(map, @r###"
89 ⋮crate
90 ⋮Baz: t v
91 "###
92 );
93}
94
95#[test]
96fn glob_enum() {
97 // covers!(glob_enum);
98 let map = def_map(
99 "
100 //- /lib.rs
101 enum Foo {
102 Bar, Baz
103 }
104 use self::Foo::*;
105 ",
106 );
107 assert_snapshot!(map, @r###"
108 ⋮crate
109 ⋮Bar: t v
110 ⋮Baz: t v
111 ⋮Foo: t
112 "###
113 );
114}
diff --git a/crates/ra_hir_def/src/nameres/tests/incremental.rs b/crates/ra_hir_def/src/nameres/tests/incremental.rs
new file mode 100644
index 000000000..80dcec62f
--- /dev/null
+++ b/crates/ra_hir_def/src/nameres/tests/incremental.rs
@@ -0,0 +1,133 @@
1use std::sync::Arc;
2
3use ra_db::{SourceDatabase, SourceDatabaseExt};
4
5use super::*;
6
7fn check_def_map_is_not_recomputed(initial: &str, file_change: &str) {
8 let (mut db, pos) = TestDB::with_position(initial);
9 let krate = db.crate_graph().iter().next().unwrap();
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(file_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 "
30 //- /lib.rs
31 mod foo;<|>
32
33 use crate::foo::bar::Baz;
34
35 fn foo() -> i32 {
36 1 + 1
37 }
38 //- /foo/mod.rs
39 pub mod bar;
40
41 //- /foo/bar.rs
42 pub struct Baz;
43 ",
44 "
45 mod foo;
46
47 use crate::foo::bar::Baz;
48
49 fn foo() -> i32 { 92 }
50 ",
51 );
52}
53
54#[test]
55fn adding_inner_items_should_not_invalidate_def_map() {
56 check_def_map_is_not_recomputed(
57 "
58 //- /lib.rs
59 struct S { a: i32}
60 enum E { A }
61 trait T {
62 fn a() {}
63 }
64 mod foo;<|>
65 impl S {
66 fn a() {}
67 }
68 use crate::foo::bar::Baz;
69 //- /foo/mod.rs
70 pub mod bar;
71
72 //- /foo/bar.rs
73 pub struct Baz;
74 ",
75 "
76 struct S { a: i32, b: () }
77 enum E { A, B }
78 trait T {
79 fn a() {}
80 fn b() {}
81 }
82 mod foo;<|>
83 impl S {
84 fn a() {}
85 fn b() {}
86 }
87 use crate::foo::bar::Baz;
88 ",
89 );
90}
91
92#[test]
93fn typing_inside_a_macro_should_not_invalidate_def_map() {
94 let (mut db, pos) = TestDB::with_position(
95 "
96 //- /lib.rs
97 macro_rules! m {
98 ($ident:ident) => {
99 fn f() {
100 $ident + $ident;
101 };
102 }
103 }
104 mod foo;
105
106 //- /foo/mod.rs
107 pub mod bar;
108
109 //- /foo/bar.rs
110 <|>
111 m!(X);
112 ",
113 );
114 let krate = db.crate_graph().iter().next().unwrap();
115 {
116 let events = db.log_executed(|| {
117 let crate_def_map = db.crate_def_map(krate);
118 let (_, module_data) = crate_def_map.modules.iter().last().unwrap();
119 assert_eq!(module_data.scope.items.len(), 1);
120 });
121 assert!(format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
122 }
123 db.set_file_text(pos.file_id, Arc::new("m!(Y);".to_string()));
124
125 {
126 let events = db.log_executed(|| {
127 let crate_def_map = db.crate_def_map(krate);
128 let (_, module_data) = crate_def_map.modules.iter().last().unwrap();
129 assert_eq!(module_data.scope.items.len(), 1);
130 });
131 assert!(!format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
132 }
133}
diff --git a/crates/ra_hir_def/src/nameres/tests/macros.rs b/crates/ra_hir_def/src/nameres/tests/macros.rs
new file mode 100644
index 000000000..9bb3895ad
--- /dev/null
+++ b/crates/ra_hir_def/src/nameres/tests/macros.rs
@@ -0,0 +1,602 @@
1use super::*;
2
3#[test]
4fn macro_rules_are_globally_visible() {
5 let map = def_map(
6 "
7 //- /lib.rs
8 macro_rules! structs {
9 ($($i:ident),*) => {
10 $(struct $i { field: u32 } )*
11 }
12 }
13 structs!(Foo);
14 mod nested;
15
16 //- /nested.rs
17 structs!(Bar, Baz);
18 ",
19 );
20 assert_snapshot!(map, @r###"
21 ⋮crate
22 ⋮Foo: t v
23 ⋮nested: t
24
25 ⋮crate::nested
26 ⋮Bar: t v
27 ⋮Baz: t v
28 "###);
29}
30
31#[test]
32fn macro_rules_can_define_modules() {
33 let map = def_map(
34 "
35 //- /lib.rs
36 macro_rules! m {
37 ($name:ident) => { mod $name; }
38 }
39 m!(n1);
40
41 mod m {
42 m!(n3)
43 }
44
45 //- /n1.rs
46 m!(n2)
47 //- /n1/n2.rs
48 struct X;
49 //- /m/n3.rs
50 struct Y;
51 ",
52 );
53 assert_snapshot!(map, @r###"
54 crate
55 m: t
56 n1: t
57
58 crate::m
59 n3: t
60
61 crate::m::n3
62 Y: t v
63
64 crate::n1
65 n2: t
66
67 crate::n1::n2
68 X: t v
69 "###);
70}
71
72#[test]
73fn macro_rules_from_other_crates_are_visible() {
74 let map = def_map(
75 "
76 //- /main.rs crate:main deps:foo
77 foo::structs!(Foo, Bar)
78 mod bar;
79
80 //- /bar.rs
81 use crate::*;
82
83 //- /lib.rs crate:foo
84 #[macro_export]
85 macro_rules! structs {
86 ($($i:ident),*) => {
87 $(struct $i { field: u32 } )*
88 }
89 }
90 ",
91 );
92 assert_snapshot!(map, @r###"
93 ⋮crate
94 ⋮Bar: t v
95 ⋮Foo: t v
96 ⋮bar: t
97
98 ⋮crate::bar
99 ⋮Bar: t v
100 ⋮Foo: t v
101 ⋮bar: t
102 "###);
103}
104
105#[test]
106fn macro_rules_export_with_local_inner_macros_are_visible() {
107 let map = def_map(
108 "
109 //- /main.rs crate:main deps:foo
110 foo::structs!(Foo, Bar)
111 mod bar;
112
113 //- /bar.rs
114 use crate::*;
115
116 //- /lib.rs crate:foo
117 #[macro_export(local_inner_macros)]
118 macro_rules! structs {
119 ($($i:ident),*) => {
120 $(struct $i { field: u32 } )*
121 }
122 }
123 ",
124 );
125 assert_snapshot!(map, @r###"
126 ⋮crate
127 ⋮Bar: t v
128 ⋮Foo: t v
129 ⋮bar: t
130
131 ⋮crate::bar
132 ⋮Bar: t v
133 ⋮Foo: t v
134 ⋮bar: t
135 "###);
136}
137
138#[test]
139fn unexpanded_macro_should_expand_by_fixedpoint_loop() {
140 let map = def_map(
141 "
142 //- /main.rs crate:main deps:foo
143 macro_rules! baz {
144 () => {
145 use foo::bar;
146 }
147 }
148
149 foo!();
150 bar!();
151 baz!();
152
153 //- /lib.rs crate:foo
154 #[macro_export]
155 macro_rules! foo {
156 () => {
157 struct Foo { field: u32 }
158 }
159 }
160 #[macro_export]
161 macro_rules! bar {
162 () => {
163 use foo::foo;
164 }
165 }
166 ",
167 );
168 assert_snapshot!(map, @r###"
169 ⋮crate
170 ⋮Foo: t v
171 ⋮bar: m
172 ⋮foo: m
173 "###);
174}
175
176#[test]
177fn macro_rules_from_other_crates_are_visible_with_macro_use() {
178 // covers!(macro_rules_from_other_crates_are_visible_with_macro_use);
179 let map = def_map(
180 "
181 //- /main.rs crate:main deps:foo
182 structs!(Foo);
183 structs_priv!(Bar);
184 structs_not_exported!(MacroNotResolved1);
185 crate::structs!(MacroNotResolved2);
186
187 mod bar;
188
189 #[macro_use]
190 extern crate foo;
191
192 //- /bar.rs
193 structs!(Baz);
194 crate::structs!(MacroNotResolved3);
195
196 //- /lib.rs crate:foo
197 #[macro_export]
198 macro_rules! structs {
199 ($i:ident) => { struct $i; }
200 }
201
202 macro_rules! structs_not_exported {
203 ($i:ident) => { struct $i; }
204 }
205
206 mod priv_mod {
207 #[macro_export]
208 macro_rules! structs_priv {
209 ($i:ident) => { struct $i; }
210 }
211 }
212 ",
213 );
214 assert_snapshot!(map, @r###"
215 ⋮crate
216 ⋮Bar: t v
217 ⋮Foo: t v
218 ⋮bar: t
219 ⋮foo: t
220
221 ⋮crate::bar
222 ⋮Baz: t v
223 "###);
224}
225
226#[test]
227fn prelude_is_macro_use() {
228 // covers!(prelude_is_macro_use);
229 let map = def_map(
230 "
231 //- /main.rs crate:main deps:foo
232 structs!(Foo);
233 structs_priv!(Bar);
234 structs_outside!(Out);
235 crate::structs!(MacroNotResolved2);
236
237 mod bar;
238
239 //- /bar.rs
240 structs!(Baz);
241 crate::structs!(MacroNotResolved3);
242
243 //- /lib.rs crate:foo
244 #[prelude_import]
245 use self::prelude::*;
246
247 mod prelude {
248 #[macro_export]
249 macro_rules! structs {
250 ($i:ident) => { struct $i; }
251 }
252
253 mod priv_mod {
254 #[macro_export]
255 macro_rules! structs_priv {
256 ($i:ident) => { struct $i; }
257 }
258 }
259 }
260
261 #[macro_export]
262 macro_rules! structs_outside {
263 ($i:ident) => { struct $i; }
264 }
265 ",
266 );
267 assert_snapshot!(map, @r###"
268 ⋮crate
269 ⋮Bar: t v
270 ⋮Foo: t v
271 ⋮Out: t v
272 ⋮bar: t
273
274 ⋮crate::bar
275 ⋮Baz: t v
276 "###);
277}
278
279#[test]
280fn prelude_cycle() {
281 let map = def_map(
282 "
283 //- /lib.rs
284 #[prelude_import]
285 use self::prelude::*;
286
287 declare_mod!();
288
289 mod prelude {
290 macro_rules! declare_mod {
291 () => (mod foo {})
292 }
293 }
294 ",
295 );
296 assert_snapshot!(map, @r###"
297 ⋮crate
298 ⋮prelude: t
299
300 ⋮crate::prelude
301 "###);
302}
303
304#[test]
305fn plain_macros_are_legacy_textual_scoped() {
306 let map = def_map(
307 r#"
308 //- /main.rs
309 mod m1;
310 bar!(NotFoundNotMacroUse);
311
312 mod m2 {
313 foo!(NotFoundBeforeInside2);
314 }
315
316 macro_rules! foo {
317 ($x:ident) => { struct $x; }
318 }
319 foo!(Ok);
320
321 mod m3;
322 foo!(OkShadowStop);
323 bar!(NotFoundMacroUseStop);
324
325 #[macro_use]
326 mod m5 {
327 #[macro_use]
328 mod m6 {
329 macro_rules! foo {
330 ($x:ident) => { fn $x() {} }
331 }
332 }
333 }
334 foo!(ok_double_macro_use_shadow);
335
336 baz!(NotFoundBefore);
337 #[macro_use]
338 mod m7 {
339 macro_rules! baz {
340 ($x:ident) => { struct $x; }
341 }
342 }
343 baz!(OkAfter);
344
345 //- /m1.rs
346 foo!(NotFoundBeforeInside1);
347 macro_rules! bar {
348 ($x:ident) => { struct $x; }
349 }
350
351 //- /m3/mod.rs
352 foo!(OkAfterInside);
353 macro_rules! foo {
354 ($x:ident) => { fn $x() {} }
355 }
356 foo!(ok_shadow);
357
358 #[macro_use]
359 mod m4;
360 bar!(OkMacroUse);
361
362 //- /m3/m4.rs
363 foo!(ok_shadow_deep);
364 macro_rules! bar {
365 ($x:ident) => { struct $x; }
366 }
367 "#,
368 );
369 assert_snapshot!(map, @r###"
370 ⋮crate
371 ⋮Ok: t v
372 ⋮OkAfter: t v
373 ⋮OkShadowStop: t v
374 ⋮m1: t
375 ⋮m2: t
376 ⋮m3: t
377 ⋮m5: t
378 ⋮m7: t
379 ⋮ok_double_macro_use_shadow: v
380
381 ⋮crate::m7
382
383 ⋮crate::m1
384
385 ⋮crate::m5
386 ⋮m6: t
387
388 ⋮crate::m5::m6
389
390 ⋮crate::m2
391
392 ⋮crate::m3
393 ⋮OkAfterInside: t v
394 ⋮OkMacroUse: t v
395 ⋮m4: t
396 ⋮ok_shadow: v
397
398 ⋮crate::m3::m4
399 ⋮ok_shadow_deep: v
400 "###);
401}
402
403#[test]
404fn type_value_macro_live_in_different_scopes() {
405 let map = def_map(
406 "
407 //- /main.rs
408 #[macro_export]
409 macro_rules! foo {
410 ($x:ident) => { type $x = (); }
411 }
412
413 foo!(foo);
414 use foo as bar;
415
416 use self::foo as baz;
417 fn baz() {}
418 ",
419 );
420 assert_snapshot!(map, @r###"
421 ⋮crate
422 ⋮bar: t m
423 ⋮baz: t v m
424 ⋮foo: t m
425 "###);
426}
427
428#[test]
429fn macro_use_can_be_aliased() {
430 let map = def_map(
431 "
432 //- /main.rs crate:main deps:foo
433 #[macro_use]
434 extern crate foo;
435
436 foo!(Direct);
437 bar!(Alias);
438
439 //- /lib.rs crate:foo
440 use crate::foo as bar;
441
442 mod m {
443 #[macro_export]
444 macro_rules! foo {
445 ($x:ident) => { struct $x; }
446 }
447 }
448 ",
449 );
450 assert_snapshot!(map, @r###"
451 ⋮crate
452 ⋮Alias: t v
453 ⋮Direct: t v
454 ⋮foo: t
455 "###);
456}
457
458#[test]
459fn path_qualified_macros() {
460 let map = def_map(
461 "
462 //- /main.rs
463 macro_rules! foo {
464 ($x:ident) => { struct $x; }
465 }
466
467 crate::foo!(NotResolved);
468
469 crate::bar!(OkCrate);
470 bar!(OkPlain);
471 alias1!(NotHere);
472 m::alias1!(OkAliasPlain);
473 m::alias2!(OkAliasSuper);
474 m::alias3!(OkAliasCrate);
475 not_found!(NotFound);
476
477 mod m {
478 #[macro_export]
479 macro_rules! bar {
480 ($x:ident) => { struct $x; }
481 }
482
483 pub use bar as alias1;
484 pub use super::bar as alias2;
485 pub use crate::bar as alias3;
486 pub use self::bar as not_found;
487 }
488 ",
489 );
490 assert_snapshot!(map, @r###"
491 ⋮crate
492 ⋮OkAliasCrate: t v
493 ⋮OkAliasPlain: t v
494 ⋮OkAliasSuper: t v
495 ⋮OkCrate: t v
496 ⋮OkPlain: t v
497 ⋮bar: m
498 ⋮m: t
499
500 ⋮crate::m
501 ⋮alias1: m
502 ⋮alias2: m
503 ⋮alias3: m
504 ⋮not_found: _
505 "###);
506}
507
508#[test]
509fn macro_dollar_crate_is_correct_in_item() {
510 // covers!(macro_dollar_crate_self);
511 // covers!(macro_dollar_crate_other);
512 let map = def_map(
513 "
514 //- /main.rs crate:main deps:foo
515 #[macro_use]
516 extern crate foo;
517
518 #[macro_use]
519 mod m {
520 macro_rules! current {
521 () => {
522 use $crate::Foo as FooSelf;
523 }
524 }
525 }
526
527 struct Foo;
528
529 current!();
530 not_current1!();
531 foo::not_current2!();
532
533 //- /lib.rs crate:foo
534 mod m {
535 #[macro_export]
536 macro_rules! not_current1 {
537 () => {
538 use $crate::Bar;
539 }
540 }
541 }
542
543 #[macro_export]
544 macro_rules! not_current2 {
545 () => {
546 use $crate::Baz;
547 }
548 }
549
550 struct Bar;
551 struct Baz;
552 ",
553 );
554 assert_snapshot!(map, @r###"
555 ⋮crate
556 ⋮Bar: t v
557 ⋮Baz: t v
558 ⋮Foo: t v
559 ⋮FooSelf: t v
560 ⋮foo: t
561 ⋮m: t
562
563 ⋮crate::m
564 "###);
565}
566
567#[test]
568fn macro_dollar_crate_is_correct_in_indirect_deps() {
569 // covers!(macro_dollar_crate_other);
570 // From std
571 let map = def_map(
572 r#"
573 //- /main.rs crate:main deps:std
574 foo!();
575
576 //- /std.rs crate:std deps:core
577 #[prelude_import]
578 use self::prelude::*;
579
580 pub use core::foo;
581
582 mod prelude {}
583
584 #[macro_use]
585 mod std_macros;
586
587 //- /core.rs crate:core
588 #[macro_export]
589 macro_rules! foo {
590 () => {
591 use $crate::bar;
592 }
593 }
594
595 pub struct bar;
596 "#,
597 );
598 assert_snapshot!(map, @r###"
599 ⋮crate
600 ⋮bar: t v
601 "###);
602}
diff --git a/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs b/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs
new file mode 100644
index 000000000..8d804a63e
--- /dev/null
+++ b/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs
@@ -0,0 +1,782 @@
1use super::*;
2
3#[test]
4fn name_res_works_for_broken_modules() {
5 // covers!(name_res_works_for_broken_modules);
6 let map = def_map(
7 "
8 //- /lib.rs
9 mod foo // no `;`, no body
10
11 use self::foo::Baz;
12
13 //- /foo/mod.rs
14 pub mod bar;
15
16 pub use self::bar::Baz;
17
18 //- /foo/bar.rs
19 pub struct Baz;
20 ",
21 );
22 assert_snapshot!(map, @r###"
23 ⋮crate
24 ⋮Baz: _
25 "###);
26}
27
28#[test]
29fn nested_module_resolution() {
30 let map = def_map(
31 "
32 //- /lib.rs
33 mod n1;
34
35 //- /n1.rs
36 mod n2;
37
38 //- /n1/n2.rs
39 struct X;
40 ",
41 );
42
43 assert_snapshot!(map, @r###"
44 ⋮crate
45 ⋮n1: t
46
47 ⋮crate::n1
48 ⋮n2: t
49
50 ⋮crate::n1::n2
51 ⋮X: t v
52 "###);
53}
54
55#[test]
56fn module_resolution_works_for_non_standard_filenames() {
57 let map = def_map(
58 "
59 //- /my_library.rs crate:my_library
60 mod foo;
61 use self::foo::Bar;
62
63 //- /foo/mod.rs
64 pub struct Bar;
65 ",
66 );
67
68 assert_snapshot!(map, @r###"
69 ⋮crate
70 ⋮Bar: t v
71 ⋮foo: t
72
73 ⋮crate::foo
74 ⋮Bar: t v
75 "###);
76}
77
78#[test]
79fn module_resolution_works_for_raw_modules() {
80 let map = def_map(
81 "
82 //- /lib.rs
83 mod r#async;
84 use self::r#async::Bar;
85
86 //- /async.rs
87 pub struct Bar;
88 ",
89 );
90
91 assert_snapshot!(map, @r###"
92 ⋮crate
93 ⋮Bar: t v
94 ⋮async: t
95
96 ⋮crate::async
97 ⋮Bar: t v
98 "###);
99}
100
101#[test]
102fn module_resolution_decl_path() {
103 let map = def_map(
104 r###"
105 //- /lib.rs
106 #[path = "bar/baz/foo.rs"]
107 mod foo;
108 use self::foo::Bar;
109
110 //- /bar/baz/foo.rs
111 pub struct Bar;
112 "###,
113 );
114
115 assert_snapshot!(map, @r###"
116 ⋮crate
117 ⋮Bar: t v
118 ⋮foo: t
119
120 ⋮crate::foo
121 ⋮Bar: t v
122 "###);
123}
124
125#[test]
126fn module_resolution_module_with_path_in_mod_rs() {
127 let map = def_map(
128 r###"
129 //- /main.rs
130 mod foo;
131
132 //- /foo/mod.rs
133 #[path = "baz.rs"]
134 pub mod bar;
135
136 use self::bar::Baz;
137
138 //- /foo/baz.rs
139 pub struct Baz;
140 "###,
141 );
142
143 assert_snapshot!(map, @r###"
144 ⋮crate
145 ⋮foo: t
146
147 ⋮crate::foo
148 ⋮Baz: t v
149 ⋮bar: t
150
151 ⋮crate::foo::bar
152 ⋮Baz: t v
153 "###);
154}
155
156#[test]
157fn module_resolution_module_with_path_non_crate_root() {
158 let map = def_map(
159 r###"
160 //- /main.rs
161 mod foo;
162
163 //- /foo.rs
164 #[path = "baz.rs"]
165 pub mod bar;
166
167 use self::bar::Baz;
168
169 //- /baz.rs
170 pub struct Baz;
171 "###,
172 );
173
174 assert_snapshot!(map, @r###"
175 ⋮crate
176 ⋮foo: t
177
178 ⋮crate::foo
179 ⋮Baz: t v
180 ⋮bar: t
181
182 ⋮crate::foo::bar
183 ⋮Baz: t v
184 "###);
185}
186
187#[test]
188fn module_resolution_module_decl_path_super() {
189 let map = def_map(
190 r###"
191 //- /main.rs
192 #[path = "bar/baz/module.rs"]
193 mod foo;
194 pub struct Baz;
195
196 //- /bar/baz/module.rs
197 use super::Baz;
198 "###,
199 );
200
201 assert_snapshot!(map, @r###"
202 ⋮crate
203 ⋮Baz: t v
204 ⋮foo: t
205
206 ⋮crate::foo
207 ⋮Baz: t v
208 "###);
209}
210
211#[test]
212fn module_resolution_explicit_path_mod_rs() {
213 let map = def_map(
214 r###"
215 //- /main.rs
216 #[path = "module/mod.rs"]
217 mod foo;
218
219 //- /module/mod.rs
220 pub struct Baz;
221 "###,
222 );
223
224 assert_snapshot!(map, @r###"
225 ⋮crate
226 ⋮foo: t
227
228 ⋮crate::foo
229 ⋮Baz: t v
230 "###);
231}
232
233#[test]
234fn module_resolution_relative_path() {
235 let map = def_map(
236 r###"
237 //- /main.rs
238 mod foo;
239
240 //- /foo.rs
241 #[path = "./sub.rs"]
242 pub mod foo_bar;
243
244 //- /sub.rs
245 pub struct Baz;
246 "###,
247 );
248
249 assert_snapshot!(map, @r###"
250 ⋮crate
251 ⋮foo: t
252
253 ⋮crate::foo
254 ⋮foo_bar: t
255
256 ⋮crate::foo::foo_bar
257 ⋮Baz: t v
258 "###);
259}
260
261#[test]
262fn module_resolution_relative_path_2() {
263 let map = def_map(
264 r###"
265 //- /main.rs
266 mod foo;
267
268 //- /foo/mod.rs
269 #[path="../sub.rs"]
270 pub mod foo_bar;
271
272 //- /sub.rs
273 pub struct Baz;
274 "###,
275 );
276
277 assert_snapshot!(map, @r###"
278 ⋮crate
279 ⋮foo: t
280
281 ⋮crate::foo
282 ⋮foo_bar: t
283
284 ⋮crate::foo::foo_bar
285 ⋮Baz: t v
286 "###);
287}
288
289#[test]
290fn module_resolution_explicit_path_mod_rs_2() {
291 let map = def_map(
292 r###"
293 //- /main.rs
294 #[path = "module/bar/mod.rs"]
295 mod foo;
296
297 //- /module/bar/mod.rs
298 pub struct Baz;
299 "###,
300 );
301
302 assert_snapshot!(map, @r###"
303 ⋮crate
304 ⋮foo: t
305
306 ⋮crate::foo
307 ⋮Baz: t v
308 "###);
309}
310
311#[test]
312fn module_resolution_explicit_path_mod_rs_with_win_separator() {
313 let map = def_map(
314 r###"
315 //- /main.rs
316 #[path = "module\bar\mod.rs"]
317 mod foo;
318
319 //- /module/bar/mod.rs
320 pub struct Baz;
321 "###,
322 );
323
324 assert_snapshot!(map, @r###"
325 ⋮crate
326 ⋮foo: t
327
328 ⋮crate::foo
329 ⋮Baz: t v
330 "###);
331}
332
333#[test]
334fn module_resolution_decl_inside_inline_module_with_path_attribute() {
335 let map = def_map(
336 r###"
337 //- /main.rs
338 #[path = "models"]
339 mod foo {
340 mod bar;
341 }
342
343 //- /models/bar.rs
344 pub struct Baz;
345 "###,
346 );
347
348 assert_snapshot!(map, @r###"
349 ⋮crate
350 ⋮foo: t
351
352 ⋮crate::foo
353 ⋮bar: t
354
355 ⋮crate::foo::bar
356 ⋮Baz: t v
357 "###);
358}
359
360#[test]
361fn module_resolution_decl_inside_inline_module() {
362 let map = def_map(
363 r###"
364 //- /main.rs
365 mod foo {
366 mod bar;
367 }
368
369 //- /foo/bar.rs
370 pub struct Baz;
371 "###,
372 );
373
374 assert_snapshot!(map, @r###"
375 ⋮crate
376 ⋮foo: t
377
378 ⋮crate::foo
379 ⋮bar: t
380
381 ⋮crate::foo::bar
382 ⋮Baz: t v
383 "###);
384}
385
386#[test]
387fn module_resolution_decl_inside_inline_module_2_with_path_attribute() {
388 let map = def_map(
389 r###"
390 //- /main.rs
391 #[path = "models/db"]
392 mod foo {
393 mod bar;
394 }
395
396 //- /models/db/bar.rs
397 pub struct Baz;
398 "###,
399 );
400
401 assert_snapshot!(map, @r###"
402 ⋮crate
403 ⋮foo: t
404
405 ⋮crate::foo
406 ⋮bar: t
407
408 ⋮crate::foo::bar
409 ⋮Baz: t v
410 "###);
411}
412
413#[test]
414fn module_resolution_decl_inside_inline_module_3() {
415 let map = def_map(
416 r###"
417 //- /main.rs
418 #[path = "models/db"]
419 mod foo {
420 #[path = "users.rs"]
421 mod bar;
422 }
423
424 //- /models/db/users.rs
425 pub struct Baz;
426 "###,
427 );
428
429 assert_snapshot!(map, @r###"
430 ⋮crate
431 ⋮foo: t
432
433 ⋮crate::foo
434 ⋮bar: t
435
436 ⋮crate::foo::bar
437 ⋮Baz: t v
438 "###);
439}
440
441#[test]
442fn module_resolution_decl_inside_inline_module_empty_path() {
443 let map = def_map(
444 r###"
445 //- /main.rs
446 #[path = ""]
447 mod foo {
448 #[path = "users.rs"]
449 mod bar;
450 }
451
452 //- /users.rs
453 pub struct Baz;
454 "###,
455 );
456
457 assert_snapshot!(map, @r###"
458 ⋮crate
459 ⋮foo: t
460
461 ⋮crate::foo
462 ⋮bar: t
463
464 ⋮crate::foo::bar
465 ⋮Baz: t v
466 "###);
467}
468
469#[test]
470fn module_resolution_decl_empty_path() {
471 let map = def_map(
472 r###"
473 //- /main.rs
474 #[path = ""] // Should try to read `/` (a directory)
475 mod foo;
476
477 //- /foo.rs
478 pub struct Baz;
479 "###,
480 );
481
482 assert_snapshot!(map, @r###"
483 ⋮crate
484 "###);
485}
486
487#[test]
488fn module_resolution_decl_inside_inline_module_relative_path() {
489 let map = def_map(
490 r###"
491 //- /main.rs
492 #[path = "./models"]
493 mod foo {
494 mod bar;
495 }
496
497 //- /models/bar.rs
498 pub struct Baz;
499 "###,
500 );
501
502 assert_snapshot!(map, @r###"
503 ⋮crate
504 ⋮foo: t
505
506 ⋮crate::foo
507 ⋮bar: t
508
509 ⋮crate::foo::bar
510 ⋮Baz: t v
511 "###);
512}
513
514#[test]
515fn module_resolution_decl_inside_inline_module_in_crate_root() {
516 let map = def_map(
517 r###"
518 //- /main.rs
519 mod foo {
520 #[path = "baz.rs"]
521 mod bar;
522 }
523 use self::foo::bar::Baz;
524
525 //- /foo/baz.rs
526 pub struct Baz;
527 "###,
528 );
529
530 assert_snapshot!(map, @r###"
531 ⋮crate
532 ⋮Baz: t v
533 ⋮foo: t
534
535 ⋮crate::foo
536 ⋮bar: t
537
538 ⋮crate::foo::bar
539 ⋮Baz: t v
540 "###);
541}
542
543#[test]
544fn module_resolution_decl_inside_inline_module_in_mod_rs() {
545 let map = def_map(
546 r###"
547 //- /main.rs
548 mod foo;
549
550 //- /foo/mod.rs
551 mod bar {
552 #[path = "qwe.rs"]
553 pub mod baz;
554 }
555 use self::bar::baz::Baz;
556
557 //- /foo/bar/qwe.rs
558 pub struct Baz;
559 "###,
560 );
561
562 assert_snapshot!(map, @r###"
563 ⋮crate
564 ⋮foo: t
565
566 ⋮crate::foo
567 ⋮Baz: t v
568 ⋮bar: t
569
570 ⋮crate::foo::bar
571 ⋮baz: t
572
573 ⋮crate::foo::bar::baz
574 ⋮Baz: t v
575 "###);
576}
577
578#[test]
579fn module_resolution_decl_inside_inline_module_in_non_crate_root() {
580 let map = def_map(
581 r###"
582 //- /main.rs
583 mod foo;
584
585 //- /foo.rs
586 mod bar {
587 #[path = "qwe.rs"]
588 pub mod baz;
589 }
590 use self::bar::baz::Baz;
591
592 //- /foo/bar/qwe.rs
593 pub struct Baz;
594 "###,
595 );
596
597 assert_snapshot!(map, @r###"
598 ⋮crate
599 ⋮foo: t
600
601 ⋮crate::foo
602 ⋮Baz: t v
603 ⋮bar: t
604
605 ⋮crate::foo::bar
606 ⋮baz: t
607
608 ⋮crate::foo::bar::baz
609 ⋮Baz: t v
610 "###);
611}
612
613#[test]
614fn module_resolution_decl_inside_inline_module_in_non_crate_root_2() {
615 let map = def_map(
616 r###"
617 //- /main.rs
618 mod foo;
619
620 //- /foo.rs
621 #[path = "bar"]
622 mod bar {
623 pub mod baz;
624 }
625 use self::bar::baz::Baz;
626
627 //- /bar/baz.rs
628 pub struct Baz;
629 "###,
630 );
631
632 assert_snapshot!(map, @r###"
633 ⋮crate
634 ⋮foo: t
635
636 ⋮crate::foo
637 ⋮Baz: t v
638 ⋮bar: t
639
640 ⋮crate::foo::bar
641 ⋮baz: t
642
643 ⋮crate::foo::bar::baz
644 ⋮Baz: t v
645 "###);
646}
647
648#[test]
649fn unresolved_module_diagnostics() {
650 let db = TestDB::with_files(
651 r"
652 //- /lib.rs
653 mod foo;
654 mod bar;
655 mod baz {}
656 //- /foo.rs
657 ",
658 );
659 let krate = db.crate_graph().iter().next().unwrap();
660
661 let crate_def_map = db.crate_def_map(krate);
662
663 insta::assert_debug_snapshot!(
664 crate_def_map.diagnostics,
665 @r###"
666 [
667 UnresolvedModule {
668 module: CrateModuleId(
669 0,
670 ),
671 declaration: AstId {
672 file_id: HirFileId(
673 FileId(
674 FileId(
675 0,
676 ),
677 ),
678 ),
679 file_ast_id: FileAstId {
680 raw: ErasedFileAstId(
681 1,
682 ),
683 _ty: PhantomData,
684 },
685 },
686 candidate: "bar.rs",
687 },
688 ]
689 "###
690 );
691}
692
693#[test]
694fn module_resolution_decl_inside_module_in_non_crate_root_2() {
695 let map = def_map(
696 r###"
697 //- /main.rs
698 #[path="module/m2.rs"]
699 mod module;
700
701 //- /module/m2.rs
702 pub mod submod;
703
704 //- /module/submod.rs
705 pub struct Baz;
706 "###,
707 );
708
709 assert_snapshot!(map, @r###"
710 ⋮crate
711 ⋮module: t
712
713 ⋮crate::module
714 ⋮submod: t
715
716 ⋮crate::module::submod
717 ⋮Baz: t v
718 "###);
719}
720
721#[test]
722fn nested_out_of_line_module() {
723 let map = def_map(
724 r###"
725 //- /lib.rs
726 mod a {
727 mod b {
728 mod c;
729 }
730 }
731
732 //- /a/b/c.rs
733 struct X;
734 "###,
735 );
736
737 assert_snapshot!(map, @r###"
738 crate
739 a: t
740
741 crate::a
742 b: t
743
744 crate::a::b
745 c: t
746
747 crate::a::b::c
748 X: t v
749 "###);
750}
751
752#[test]
753fn nested_out_of_line_module_with_path() {
754 let map = def_map(
755 r###"
756 //- /lib.rs
757 mod a {
758 #[path = "d/e"]
759 mod b {
760 mod c;
761 }
762 }
763
764 //- /a/d/e/c.rs
765 struct X;
766 "###,
767 );
768
769 assert_snapshot!(map, @r###"
770 crate
771 a: t
772
773 crate::a
774 b: t
775
776 crate::a::b
777 c: t
778
779 crate::a::b::c
780 X: t v
781 "###);
782}
diff --git a/crates/ra_hir_def/src/nameres/tests/primitives.rs b/crates/ra_hir_def/src/nameres/tests/primitives.rs
new file mode 100644
index 000000000..0e2708658
--- /dev/null
+++ b/crates/ra_hir_def/src/nameres/tests/primitives.rs
@@ -0,0 +1,24 @@
1use super::*;
2
3#[test]
4fn primitive_reexport() {
5 let map = def_map(
6 "
7 //- /lib.rs
8 mod foo;
9 use foo::int;
10
11 //- /foo.rs
12 pub use i32 as int;
13 ",
14 );
15 assert_snapshot!(map, @r###"
16 ⋮crate
17 ⋮foo: t
18 ⋮int: t
19
20 ⋮crate::foo
21 ⋮int: t
22 "###
23 );
24}
diff --git a/crates/ra_hir_def/src/test_db.rs b/crates/ra_hir_def/src/test_db.rs
index 67714c68e..05018f8e4 100644
--- a/crates/ra_hir_def/src/test_db.rs
+++ b/crates/ra_hir_def/src/test_db.rs
@@ -1,4 +1,7 @@
1use std::{panic, sync::Arc}; 1use std::{
2 panic,
3 sync::{Arc, Mutex},
4};
2 5
3use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate}; 6use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate};
4use relative_path::RelativePath; 7use relative_path::RelativePath;
@@ -13,12 +16,20 @@ use relative_path::RelativePath;
13#[derive(Debug, Default)] 16#[derive(Debug, Default)]
14pub struct TestDB { 17pub struct TestDB {
15 runtime: salsa::Runtime<TestDB>, 18 runtime: salsa::Runtime<TestDB>,
19 events: Mutex<Option<Vec<salsa::Event<TestDB>>>>,
16} 20}
17 21
18impl salsa::Database for TestDB { 22impl salsa::Database for TestDB {
19 fn salsa_runtime(&self) -> &salsa::Runtime<Self> { 23 fn salsa_runtime(&self) -> &salsa::Runtime<Self> {
20 &self.runtime 24 &self.runtime
21 } 25 }
26
27 fn salsa_event(&self, event: impl Fn() -> salsa::Event<TestDB>) {
28 let mut events = self.events.lock().unwrap();
29 if let Some(events) = &mut *events {
30 events.push(event());
31 }
32 }
22} 33}
23 34
24impl panic::RefUnwindSafe for TestDB {} 35impl panic::RefUnwindSafe for TestDB {}
@@ -38,3 +49,26 @@ impl FileLoader for TestDB {
38 FileLoaderDelegate(self).relevant_crates(file_id) 49 FileLoaderDelegate(self).relevant_crates(file_id)
39 } 50 }
40} 51}
52
53impl TestDB {
54 pub fn log(&self, f: impl FnOnce()) -> Vec<salsa::Event<TestDB>> {
55 *self.events.lock().unwrap() = Some(Vec::new());
56 f();
57 self.events.lock().unwrap().take().unwrap()
58 }
59
60 pub fn log_executed(&self, f: impl FnOnce()) -> Vec<String> {
61 let events = self.log(f);
62 events
63 .into_iter()
64 .filter_map(|e| match e.kind {
65 // This pretty horrible, but `Debug` is the only way to inspect
66 // QueryDescriptor at the moment.
67 salsa::EventKind::WillExecute { database_key } => {
68 Some(format!("{:?}", database_key))
69 }
70 _ => None,
71 })
72 .collect()
73 }
74}