]> git.lizzy.rs Git - rust.git/blob - crates/hir_def/src/nameres/tests.rs
Merge remote-tracking branch 'upstream/master' into 503-hover-doc-links
[rust.git] / crates / hir_def / src / nameres / tests.rs
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_test::{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 }