diff options
Diffstat (limited to 'crates/hir_def/src/nameres/tests.rs')
-rw-r--r-- | crates/hir_def/src/nameres/tests.rs | 690 |
1 files changed, 690 insertions, 0 deletions
diff --git a/crates/hir_def/src/nameres/tests.rs b/crates/hir_def/src/nameres/tests.rs new file mode 100644 index 000000000..b105d56b2 --- /dev/null +++ b/crates/hir_def/src/nameres/tests.rs | |||
@@ -0,0 +1,690 @@ | |||
1 | mod globs; | ||
2 | mod incremental; | ||
3 | mod macros; | ||
4 | mod mod_resolution; | ||
5 | mod primitives; | ||
6 | |||
7 | use std::sync::Arc; | ||
8 | |||
9 | use base_db::{fixture::WithFixture, SourceDatabase}; | ||
10 | use expect::{expect, Expect}; | ||
11 | use test_utils::mark; | ||
12 | |||
13 | use crate::{db::DefDatabase, nameres::*, test_db::TestDB}; | ||
14 | |||
15 | fn compute_crate_def_map(fixture: &str) -> Arc<CrateDefMap> { | ||
16 | let db = TestDB::with_files(fixture); | ||
17 | let krate = db.crate_graph().iter().next().unwrap(); | ||
18 | db.crate_def_map(krate) | ||
19 | } | ||
20 | |||
21 | fn check(ra_fixture: &str, expect: Expect) { | ||
22 | let db = TestDB::with_files(ra_fixture); | ||
23 | let krate = db.crate_graph().iter().next().unwrap(); | ||
24 | let actual = db.crate_def_map(krate).dump(); | ||
25 | expect.assert_eq(&actual); | ||
26 | } | ||
27 | |||
28 | #[test] | ||
29 | fn crate_def_map_smoke_test() { | ||
30 | check( | ||
31 | r#" | ||
32 | //- /lib.rs | ||
33 | mod foo; | ||
34 | struct S; | ||
35 | use crate::foo::bar::E; | ||
36 | use self::E::V; | ||
37 | |||
38 | //- /foo/mod.rs | ||
39 | pub mod bar; | ||
40 | fn f() {} | ||
41 | |||
42 | //- /foo/bar.rs | ||
43 | pub struct Baz; | ||
44 | |||
45 | union U { to_be: bool, not_to_be: u8 } | ||
46 | enum E { V } | ||
47 | |||
48 | extern { | ||
49 | static EXT: u8; | ||
50 | fn ext(); | ||
51 | } | ||
52 | "#, | ||
53 | expect![[r#" | ||
54 | crate | ||
55 | E: t | ||
56 | S: t v | ||
57 | V: t v | ||
58 | foo: t | ||
59 | |||
60 | crate::foo | ||
61 | bar: t | ||
62 | f: v | ||
63 | |||
64 | crate::foo::bar | ||
65 | Baz: t v | ||
66 | E: t | ||
67 | EXT: v | ||
68 | U: t | ||
69 | ext: v | ||
70 | "#]], | ||
71 | ); | ||
72 | } | ||
73 | |||
74 | #[test] | ||
75 | fn crate_def_map_super_super() { | ||
76 | check( | ||
77 | r#" | ||
78 | mod a { | ||
79 | const A: usize = 0; | ||
80 | mod b { | ||
81 | const B: usize = 0; | ||
82 | mod c { | ||
83 | use super::super::*; | ||
84 | } | ||
85 | } | ||
86 | } | ||
87 | "#, | ||
88 | expect![[r#" | ||
89 | crate | ||
90 | a: t | ||
91 | |||
92 | crate::a | ||
93 | A: v | ||
94 | b: t | ||
95 | |||
96 | crate::a::b | ||
97 | B: v | ||
98 | c: t | ||
99 | |||
100 | crate::a::b::c | ||
101 | A: v | ||
102 | b: t | ||
103 | "#]], | ||
104 | ); | ||
105 | } | ||
106 | |||
107 | #[test] | ||
108 | fn crate_def_map_fn_mod_same_name() { | ||
109 | check( | ||
110 | r#" | ||
111 | mod m { | ||
112 | pub mod z {} | ||
113 | pub fn z() {} | ||
114 | } | ||
115 | "#, | ||
116 | expect![[r#" | ||
117 | crate | ||
118 | m: t | ||
119 | |||
120 | crate::m | ||
121 | z: t v | ||
122 | |||
123 | crate::m::z | ||
124 | "#]], | ||
125 | ); | ||
126 | } | ||
127 | |||
128 | #[test] | ||
129 | fn bogus_paths() { | ||
130 | mark::check!(bogus_paths); | ||
131 | check( | ||
132 | r#" | ||
133 | //- /lib.rs | ||
134 | mod foo; | ||
135 | struct S; | ||
136 | use self; | ||
137 | |||
138 | //- /foo/mod.rs | ||
139 | use super; | ||
140 | use crate; | ||
141 | "#, | ||
142 | expect![[r#" | ||
143 | crate | ||
144 | S: t v | ||
145 | foo: t | ||
146 | |||
147 | crate::foo | ||
148 | "#]], | ||
149 | ); | ||
150 | } | ||
151 | |||
152 | #[test] | ||
153 | fn use_as() { | ||
154 | check( | ||
155 | r#" | ||
156 | //- /lib.rs | ||
157 | mod foo; | ||
158 | use crate::foo::Baz as Foo; | ||
159 | |||
160 | //- /foo/mod.rs | ||
161 | pub struct Baz; | ||
162 | "#, | ||
163 | expect![[r#" | ||
164 | crate | ||
165 | Foo: t v | ||
166 | foo: t | ||
167 | |||
168 | crate::foo | ||
169 | Baz: t v | ||
170 | "#]], | ||
171 | ); | ||
172 | } | ||
173 | |||
174 | #[test] | ||
175 | fn use_trees() { | ||
176 | check( | ||
177 | r#" | ||
178 | //- /lib.rs | ||
179 | mod foo; | ||
180 | use crate::foo::bar::{Baz, Quux}; | ||
181 | |||
182 | //- /foo/mod.rs | ||
183 | pub mod bar; | ||
184 | |||
185 | //- /foo/bar.rs | ||
186 | pub struct Baz; | ||
187 | pub enum Quux {}; | ||
188 | "#, | ||
189 | expect![[r#" | ||
190 | crate | ||
191 | Baz: t v | ||
192 | Quux: t | ||
193 | foo: t | ||
194 | |||
195 | crate::foo | ||
196 | bar: t | ||
197 | |||
198 | crate::foo::bar | ||
199 | Baz: t v | ||
200 | Quux: t | ||
201 | "#]], | ||
202 | ); | ||
203 | } | ||
204 | |||
205 | #[test] | ||
206 | fn re_exports() { | ||
207 | check( | ||
208 | r#" | ||
209 | //- /lib.rs | ||
210 | mod foo; | ||
211 | use self::foo::Baz; | ||
212 | |||
213 | //- /foo/mod.rs | ||
214 | pub mod bar; | ||
215 | pub use self::bar::Baz; | ||
216 | |||
217 | //- /foo/bar.rs | ||
218 | pub struct Baz; | ||
219 | "#, | ||
220 | expect![[r#" | ||
221 | crate | ||
222 | Baz: t v | ||
223 | foo: t | ||
224 | |||
225 | crate::foo | ||
226 | Baz: t v | ||
227 | bar: t | ||
228 | |||
229 | crate::foo::bar | ||
230 | Baz: t v | ||
231 | "#]], | ||
232 | ); | ||
233 | } | ||
234 | |||
235 | #[test] | ||
236 | fn std_prelude() { | ||
237 | mark::check!(std_prelude); | ||
238 | check( | ||
239 | r#" | ||
240 | //- /main.rs crate:main deps:test_crate | ||
241 | use Foo::*; | ||
242 | |||
243 | //- /lib.rs crate:test_crate | ||
244 | mod prelude; | ||
245 | #[prelude_import] | ||
246 | use prelude::*; | ||
247 | |||
248 | //- /prelude.rs | ||
249 | pub enum Foo { Bar, Baz }; | ||
250 | "#, | ||
251 | expect![[r#" | ||
252 | crate | ||
253 | Bar: t v | ||
254 | Baz: t v | ||
255 | "#]], | ||
256 | ); | ||
257 | } | ||
258 | |||
259 | #[test] | ||
260 | fn can_import_enum_variant() { | ||
261 | mark::check!(can_import_enum_variant); | ||
262 | check( | ||
263 | r#" | ||
264 | enum E { V } | ||
265 | use self::E::V; | ||
266 | "#, | ||
267 | expect![[r#" | ||
268 | crate | ||
269 | E: t | ||
270 | V: t v | ||
271 | "#]], | ||
272 | ); | ||
273 | } | ||
274 | |||
275 | #[test] | ||
276 | fn edition_2015_imports() { | ||
277 | check( | ||
278 | r#" | ||
279 | //- /main.rs crate:main deps:other_crate edition:2015 | ||
280 | mod foo; | ||
281 | mod bar; | ||
282 | |||
283 | //- /bar.rs | ||
284 | struct Bar; | ||
285 | |||
286 | //- /foo.rs | ||
287 | use bar::Bar; | ||
288 | use other_crate::FromLib; | ||
289 | |||
290 | //- /lib.rs crate:other_crate edition:2018 | ||
291 | struct FromLib; | ||
292 | "#, | ||
293 | expect![[r#" | ||
294 | crate | ||
295 | bar: t | ||
296 | foo: t | ||
297 | |||
298 | crate::bar | ||
299 | Bar: t v | ||
300 | |||
301 | crate::foo | ||
302 | Bar: t v | ||
303 | FromLib: t v | ||
304 | "#]], | ||
305 | ); | ||
306 | } | ||
307 | |||
308 | #[test] | ||
309 | fn item_map_using_self() { | ||
310 | check( | ||
311 | r#" | ||
312 | //- /lib.rs | ||
313 | mod foo; | ||
314 | use crate::foo::bar::Baz::{self}; | ||
315 | |||
316 | //- /foo/mod.rs | ||
317 | pub mod bar; | ||
318 | |||
319 | //- /foo/bar.rs | ||
320 | pub struct Baz; | ||
321 | "#, | ||
322 | expect![[r#" | ||
323 | crate | ||
324 | Baz: t v | ||
325 | foo: t | ||
326 | |||
327 | crate::foo | ||
328 | bar: t | ||
329 | |||
330 | crate::foo::bar | ||
331 | Baz: t v | ||
332 | "#]], | ||
333 | ); | ||
334 | } | ||
335 | |||
336 | #[test] | ||
337 | fn item_map_across_crates() { | ||
338 | check( | ||
339 | r#" | ||
340 | //- /main.rs crate:main deps:test_crate | ||
341 | use test_crate::Baz; | ||
342 | |||
343 | //- /lib.rs crate:test_crate | ||
344 | pub struct Baz; | ||
345 | "#, | ||
346 | expect![[r#" | ||
347 | crate | ||
348 | Baz: t v | ||
349 | "#]], | ||
350 | ); | ||
351 | } | ||
352 | |||
353 | #[test] | ||
354 | fn extern_crate_rename() { | ||
355 | check( | ||
356 | r#" | ||
357 | //- /main.rs crate:main deps:alloc | ||
358 | extern crate alloc as alloc_crate; | ||
359 | mod alloc; | ||
360 | mod sync; | ||
361 | |||
362 | //- /sync.rs | ||
363 | use alloc_crate::Arc; | ||
364 | |||
365 | //- /lib.rs crate:alloc | ||
366 | struct Arc; | ||
367 | "#, | ||
368 | expect![[r#" | ||
369 | crate | ||
370 | alloc_crate: t | ||
371 | sync: t | ||
372 | |||
373 | crate::sync | ||
374 | Arc: t v | ||
375 | "#]], | ||
376 | ); | ||
377 | } | ||
378 | |||
379 | #[test] | ||
380 | fn extern_crate_rename_2015_edition() { | ||
381 | check( | ||
382 | r#" | ||
383 | //- /main.rs crate:main deps:alloc edition:2015 | ||
384 | extern crate alloc as alloc_crate; | ||
385 | mod alloc; | ||
386 | mod sync; | ||
387 | |||
388 | //- /sync.rs | ||
389 | use alloc_crate::Arc; | ||
390 | |||
391 | //- /lib.rs crate:alloc | ||
392 | struct Arc; | ||
393 | "#, | ||
394 | expect![[r#" | ||
395 | crate | ||
396 | alloc_crate: t | ||
397 | sync: t | ||
398 | |||
399 | crate::sync | ||
400 | Arc: t v | ||
401 | "#]], | ||
402 | ); | ||
403 | } | ||
404 | |||
405 | #[test] | ||
406 | fn reexport_across_crates() { | ||
407 | check( | ||
408 | r#" | ||
409 | //- /main.rs crate:main deps:test_crate | ||
410 | use test_crate::Baz; | ||
411 | |||
412 | //- /lib.rs crate:test_crate | ||
413 | pub use foo::Baz; | ||
414 | mod foo; | ||
415 | |||
416 | //- /foo.rs | ||
417 | pub struct Baz; | ||
418 | "#, | ||
419 | expect![[r#" | ||
420 | crate | ||
421 | Baz: t v | ||
422 | "#]], | ||
423 | ); | ||
424 | } | ||
425 | |||
426 | #[test] | ||
427 | fn values_dont_shadow_extern_crates() { | ||
428 | check( | ||
429 | r#" | ||
430 | //- /main.rs crate:main deps:foo | ||
431 | fn foo() {} | ||
432 | use foo::Bar; | ||
433 | |||
434 | //- /foo/lib.rs crate:foo | ||
435 | pub struct Bar; | ||
436 | "#, | ||
437 | expect![[r#" | ||
438 | crate | ||
439 | Bar: t v | ||
440 | foo: v | ||
441 | "#]], | ||
442 | ); | ||
443 | } | ||
444 | |||
445 | #[test] | ||
446 | fn std_prelude_takes_precedence_above_core_prelude() { | ||
447 | check( | ||
448 | r#" | ||
449 | //- /main.rs crate:main deps:core,std | ||
450 | use {Foo, Bar}; | ||
451 | |||
452 | //- /std.rs crate:std deps:core | ||
453 | #[prelude_import] | ||
454 | pub use self::prelude::*; | ||
455 | mod prelude { | ||
456 | pub struct Foo; | ||
457 | pub use core::prelude::Bar; | ||
458 | } | ||
459 | |||
460 | //- /core.rs crate:core | ||
461 | #[prelude_import] | ||
462 | pub use self::prelude::*; | ||
463 | mod prelude { | ||
464 | pub struct Bar; | ||
465 | } | ||
466 | "#, | ||
467 | expect![[r#" | ||
468 | crate | ||
469 | Bar: t v | ||
470 | Foo: t v | ||
471 | "#]], | ||
472 | ); | ||
473 | } | ||
474 | |||
475 | #[test] | ||
476 | fn cfg_not_test() { | ||
477 | check( | ||
478 | r#" | ||
479 | //- /main.rs crate:main deps:std | ||
480 | use {Foo, Bar, Baz}; | ||
481 | |||
482 | //- /lib.rs crate:std | ||
483 | #[prelude_import] | ||
484 | pub use self::prelude::*; | ||
485 | mod prelude { | ||
486 | #[cfg(test)] | ||
487 | pub struct Foo; | ||
488 | #[cfg(not(test))] | ||
489 | pub struct Bar; | ||
490 | #[cfg(all(not(any()), feature = "foo", feature = "bar", opt = "42"))] | ||
491 | pub struct Baz; | ||
492 | } | ||
493 | "#, | ||
494 | expect![[r#" | ||
495 | crate | ||
496 | Bar: t v | ||
497 | Baz: _ | ||
498 | Foo: _ | ||
499 | "#]], | ||
500 | ); | ||
501 | } | ||
502 | |||
503 | #[test] | ||
504 | fn cfg_test() { | ||
505 | check( | ||
506 | r#" | ||
507 | //- /main.rs crate:main deps:std | ||
508 | use {Foo, Bar, Baz}; | ||
509 | |||
510 | //- /lib.rs crate:std cfg:test,feature=foo,feature=bar,opt=42 | ||
511 | #[prelude_import] | ||
512 | pub use self::prelude::*; | ||
513 | mod prelude { | ||
514 | #[cfg(test)] | ||
515 | pub struct Foo; | ||
516 | #[cfg(not(test))] | ||
517 | pub struct Bar; | ||
518 | #[cfg(all(not(any()), feature = "foo", feature = "bar", opt = "42"))] | ||
519 | pub struct Baz; | ||
520 | } | ||
521 | "#, | ||
522 | expect![[r#" | ||
523 | crate | ||
524 | Bar: _ | ||
525 | Baz: t v | ||
526 | Foo: t v | ||
527 | "#]], | ||
528 | ); | ||
529 | } | ||
530 | |||
531 | #[test] | ||
532 | fn infer_multiple_namespace() { | ||
533 | check( | ||
534 | r#" | ||
535 | //- /main.rs | ||
536 | mod a { | ||
537 | pub type T = (); | ||
538 | pub use crate::b::*; | ||
539 | } | ||
540 | |||
541 | use crate::a::T; | ||
542 | |||
543 | mod b { | ||
544 | pub const T: () = (); | ||
545 | } | ||
546 | "#, | ||
547 | expect![[r#" | ||
548 | crate | ||
549 | T: t v | ||
550 | a: t | ||
551 | b: t | ||
552 | |||
553 | crate::b | ||
554 | T: v | ||
555 | |||
556 | crate::a | ||
557 | T: t v | ||
558 | "#]], | ||
559 | ); | ||
560 | } | ||
561 | |||
562 | #[test] | ||
563 | fn underscore_import() { | ||
564 | check( | ||
565 | r#" | ||
566 | //- /main.rs | ||
567 | use tr::Tr as _; | ||
568 | use tr::Tr2 as _; | ||
569 | |||
570 | mod tr { | ||
571 | pub trait Tr {} | ||
572 | pub trait Tr2 {} | ||
573 | } | ||
574 | "#, | ||
575 | expect![[r#" | ||
576 | crate | ||
577 | _: t | ||
578 | _: t | ||
579 | tr: t | ||
580 | |||
581 | crate::tr | ||
582 | Tr: t | ||
583 | Tr2: t | ||
584 | "#]], | ||
585 | ); | ||
586 | } | ||
587 | |||
588 | #[test] | ||
589 | fn underscore_reexport() { | ||
590 | check( | ||
591 | r#" | ||
592 | //- /main.rs | ||
593 | mod tr { | ||
594 | pub trait PubTr {} | ||
595 | pub trait PrivTr {} | ||
596 | } | ||
597 | mod reex { | ||
598 | use crate::tr::PrivTr as _; | ||
599 | pub use crate::tr::PubTr as _; | ||
600 | } | ||
601 | use crate::reex::*; | ||
602 | "#, | ||
603 | expect![[r#" | ||
604 | crate | ||
605 | _: t | ||
606 | reex: t | ||
607 | tr: t | ||
608 | |||
609 | crate::tr | ||
610 | PrivTr: t | ||
611 | PubTr: t | ||
612 | |||
613 | crate::reex | ||
614 | _: t | ||
615 | _: t | ||
616 | "#]], | ||
617 | ); | ||
618 | } | ||
619 | |||
620 | #[test] | ||
621 | fn underscore_pub_crate_reexport() { | ||
622 | mark::check!(upgrade_underscore_visibility); | ||
623 | check( | ||
624 | r#" | ||
625 | //- /main.rs crate:main deps:lib | ||
626 | use lib::*; | ||
627 | |||
628 | //- /lib.rs crate:lib | ||
629 | use tr::Tr as _; | ||
630 | pub use tr::Tr as _; | ||
631 | |||
632 | mod tr { | ||
633 | pub trait Tr {} | ||
634 | } | ||
635 | "#, | ||
636 | expect![[r#" | ||
637 | crate | ||
638 | _: t | ||
639 | "#]], | ||
640 | ); | ||
641 | } | ||
642 | |||
643 | #[test] | ||
644 | fn underscore_nontrait() { | ||
645 | check( | ||
646 | r#" | ||
647 | //- /main.rs | ||
648 | mod m { | ||
649 | pub struct Struct; | ||
650 | pub enum Enum {} | ||
651 | pub const CONST: () = (); | ||
652 | } | ||
653 | use crate::m::{Struct as _, Enum as _, CONST as _}; | ||
654 | "#, | ||
655 | expect![[r#" | ||
656 | crate | ||
657 | m: t | ||
658 | |||
659 | crate::m | ||
660 | CONST: v | ||
661 | Enum: t | ||
662 | Struct: t v | ||
663 | "#]], | ||
664 | ); | ||
665 | } | ||
666 | |||
667 | #[test] | ||
668 | fn underscore_name_conflict() { | ||
669 | check( | ||
670 | r#" | ||
671 | //- /main.rs | ||
672 | struct Tr; | ||
673 | |||
674 | use tr::Tr as _; | ||
675 | |||
676 | mod tr { | ||
677 | pub trait Tr {} | ||
678 | } | ||
679 | "#, | ||
680 | expect![[r#" | ||
681 | crate | ||
682 | _: t | ||
683 | Tr: t v | ||
684 | tr: t | ||
685 | |||
686 | crate::tr | ||
687 | Tr: t | ||
688 | "#]], | ||
689 | ); | ||
690 | } | ||