• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use super::*;
2 use itertools::Itertools;
3 
4 #[test]
macro_rules_are_globally_visible()5 fn macro_rules_are_globally_visible() {
6     check(
7         r#"
8 //- /lib.rs
9 macro_rules! structs {
10     ($($i:ident),*) => {
11         $(struct $i { field: u32 } )*
12     }
13 }
14 structs!(Foo);
15 mod nested;
16 
17 //- /nested.rs
18 structs!(Bar, Baz);
19 "#,
20         expect![[r#"
21             crate
22             Foo: t
23             nested: t
24 
25             crate::nested
26             Bar: t
27             Baz: t
28         "#]],
29     );
30 }
31 
32 #[test]
macro_rules_can_define_modules()33 fn macro_rules_can_define_modules() {
34     check(
35         r#"
36 //- /lib.rs
37 macro_rules! m {
38     ($name:ident) => { mod $name;  }
39 }
40 m!(n1);
41 mod m { m!(n3) }
42 
43 //- /n1.rs
44 m!(n2)
45 //- /n1/n2.rs
46 struct X;
47 //- /m/n3.rs
48 struct Y;
49 "#,
50         expect![[r#"
51             crate
52             m: t
53             n1: t
54 
55             crate::m
56             n3: t
57 
58             crate::m::n3
59             Y: t v
60 
61             crate::n1
62             n2: t
63 
64             crate::n1::n2
65             X: t v
66         "#]],
67     );
68 }
69 
70 #[test]
macro_rules_from_other_crates_are_visible()71 fn macro_rules_from_other_crates_are_visible() {
72     check(
73         r#"
74 //- /main.rs crate:main deps:foo
75 foo::structs!(Foo, Bar)
76 mod bar;
77 
78 //- /bar.rs
79 use crate::*;
80 
81 //- /lib.rs crate:foo
82 #[macro_export]
83 macro_rules! structs {
84     ($($i:ident),*) => {
85         $(struct $i { field: u32 } )*
86     }
87 }
88 "#,
89         expect![[r#"
90             crate
91             Bar: t
92             Foo: t
93             bar: t
94 
95             crate::bar
96             Bar: t
97             Foo: t
98             bar: t
99         "#]],
100     );
101 }
102 
103 #[test]
macro_rules_export_with_local_inner_macros_are_visible()104 fn macro_rules_export_with_local_inner_macros_are_visible() {
105     check(
106         r#"
107 //- /main.rs crate:main deps:foo
108 foo::structs!(Foo, Bar)
109 mod bar;
110 
111 //- /bar.rs
112 use crate::*;
113 
114 //- /lib.rs crate:foo
115 #[macro_export(local_inner_macros)]
116 macro_rules! structs {
117     ($($i:ident),*) => {
118         $(struct $i { field: u32 } )*
119     }
120 }
121 "#,
122         expect![[r#"
123             crate
124             Bar: t
125             Foo: t
126             bar: t
127 
128             crate::bar
129             Bar: t
130             Foo: t
131             bar: t
132         "#]],
133     );
134 }
135 
136 #[test]
local_inner_macros_makes_local_macros_usable()137 fn local_inner_macros_makes_local_macros_usable() {
138     check(
139         r#"
140 //- /main.rs crate:main deps:foo
141 foo::structs!(Foo, Bar);
142 mod bar;
143 
144 //- /bar.rs
145 use crate::*;
146 
147 //- /lib.rs crate:foo
148 #[macro_export(local_inner_macros)]
149 macro_rules! structs {
150     ($($i:ident),*) => {
151         inner!($($i),*);
152     }
153 }
154 #[macro_export]
155 macro_rules! inner {
156     ($($i:ident),*) => {
157         $(struct $i { field: u32 } )*
158     }
159 }
160 "#,
161         expect![[r#"
162             crate
163             Bar: t
164             Foo: t
165             bar: t
166 
167             crate::bar
168             Bar: t
169             Foo: t
170             bar: t
171         "#]],
172     );
173 }
174 
175 #[test]
unexpanded_macro_should_expand_by_fixedpoint_loop()176 fn unexpanded_macro_should_expand_by_fixedpoint_loop() {
177     check(
178         r#"
179 //- /main.rs crate:main deps:foo
180 macro_rules! baz {
181     () => {
182         use foo::bar;
183     }
184 }
185 foo!();
186 bar!();
187 baz!();
188 
189 //- /lib.rs crate:foo
190 #[macro_export]
191 macro_rules! foo {
192     () => {
193         struct Foo { field: u32 }
194     }
195 }
196 #[macro_export]
197 macro_rules! bar {
198     () => {
199         use foo::foo;
200     }
201 }
202 "#,
203         expect![[r#"
204             crate
205             Foo: t
206             bar: m
207             foo: m
208         "#]],
209     );
210 }
211 
212 #[test]
macro_rules_from_other_crates_are_visible_with_macro_use()213 fn macro_rules_from_other_crates_are_visible_with_macro_use() {
214     cov_mark::check!(macro_rules_from_other_crates_are_visible_with_macro_use);
215     check(
216         r#"
217 //- /main.rs crate:main deps:foo
218 structs!(Foo);
219 structs_priv!(Bar);
220 structs_not_exported!(MacroNotResolved1);
221 crate::structs!(MacroNotResolved2);
222 
223 mod bar;
224 
225 #[macro_use]
226 extern crate foo;
227 
228 //- /bar.rs
229 structs!(Baz);
230 crate::structs!(MacroNotResolved3);
231 
232 //- /lib.rs crate:foo
233 #[macro_export]
234 macro_rules! structs {
235     ($i:ident) => { struct $i; }
236 }
237 
238 macro_rules! structs_not_exported {
239     ($i:ident) => { struct $i; }
240 }
241 
242 mod priv_mod {
243     #[macro_export]
244     macro_rules! structs_priv {
245         ($i:ident) => { struct $i; }
246     }
247 }
248 "#,
249         expect![[r#"
250             crate
251             Bar: t v
252             Foo: t v
253             bar: t
254             foo: t
255 
256             crate::bar
257             Baz: t v
258         "#]],
259     );
260 }
261 
262 #[test]
macro_use_filter()263 fn macro_use_filter() {
264     check(
265         r#"
266 //- /main.rs crate:main deps:empty,multiple,all
267 #[macro_use()]
268 extern crate empty;
269 
270 foo_not_imported!();
271 
272 #[macro_use(bar1)]
273 #[macro_use()]
274 #[macro_use(bar2, bar3)]
275 extern crate multiple;
276 
277 bar1!();
278 bar2!();
279 bar3!();
280 bar_not_imported!();
281 
282 #[macro_use(baz1)]
283 #[macro_use]
284 #[macro_use(baz2)]
285 extern crate all;
286 
287 baz1!();
288 baz2!();
289 baz3!();
290 
291 //- /empty.rs crate:empty
292 #[macro_export]
293 macro_rules! foo_not_imported { () => { struct NotOkFoo; } }
294 
295 //- /multiple.rs crate:multiple
296 #[macro_export]
297 macro_rules! bar1 { () => { struct OkBar1; } }
298 #[macro_export]
299 macro_rules! bar2 { () => { struct OkBar2; } }
300 #[macro_export]
301 macro_rules! bar3 { () => { struct OkBar3; } }
302 #[macro_export]
303 macro_rules! bar_not_imported { () => { struct NotOkBar; } }
304 
305 //- /all.rs crate:all
306 #[macro_export]
307 macro_rules! baz1 { () => { struct OkBaz1; } }
308 #[macro_export]
309 macro_rules! baz2 { () => { struct OkBaz2; } }
310 #[macro_export]
311 macro_rules! baz3 { () => { struct OkBaz3; } }
312 "#,
313         expect![[r#"
314             crate
315             OkBar1: t v
316             OkBar2: t v
317             OkBar3: t v
318             OkBaz1: t v
319             OkBaz2: t v
320             OkBaz3: t v
321             all: t
322             empty: t
323             multiple: t
324         "#]],
325     );
326 }
327 
328 #[test]
prelude_is_macro_use()329 fn prelude_is_macro_use() {
330     cov_mark::check!(prelude_is_macro_use);
331     check(
332         r#"
333 //- /main.rs edition:2018 crate:main deps:std
334 structs!(Foo);
335 structs_priv!(Bar);
336 structs_outside!(Out);
337 crate::structs!(MacroNotResolved2);
338 
339 mod bar;
340 
341 //- /bar.rs
342 structs!(Baz);
343 crate::structs!(MacroNotResolved3);
344 
345 //- /lib.rs crate:std
346 pub mod prelude {
347     pub mod rust_2018 {
348         #[macro_export]
349         macro_rules! structs {
350             ($i:ident) => { struct $i; }
351         }
352 
353         mod priv_mod {
354             #[macro_export]
355             macro_rules! structs_priv {
356                 ($i:ident) => { struct $i; }
357             }
358         }
359     }
360 }
361 
362 #[macro_export]
363 macro_rules! structs_outside {
364     ($i:ident) => { struct $i; }
365 }
366 "#,
367         expect![[r#"
368             crate
369             Bar: t v
370             Foo: t v
371             Out: t v
372             bar: t
373 
374             crate::bar
375             Baz: t v
376         "#]],
377     );
378 }
379 
380 #[test]
prelude_cycle()381 fn prelude_cycle() {
382     check(
383         r#"
384 #[prelude_import]
385 use self::prelude::*;
386 
387 declare_mod!();
388 
389 mod prelude {
390     macro_rules! declare_mod {
391         () => (mod foo {})
392     }
393 }
394 "#,
395         expect![[r#"
396             crate
397             prelude: t
398 
399             crate::prelude
400         "#]],
401     );
402 }
403 
404 #[test]
legacy_macro_use_before_def()405 fn legacy_macro_use_before_def() {
406     check(
407         r#"
408 m!();
409 
410 macro_rules! m {
411     () => {
412         struct S;
413     }
414 }
415 "#,
416         expect![[r#"
417             crate
418             S: t v
419         "#]],
420     );
421     // FIXME: should not expand. legacy macro scoping is not implemented.
422 }
423 
424 #[test]
plain_macros_are_legacy_textual_scoped()425 fn plain_macros_are_legacy_textual_scoped() {
426     check(
427         r#"
428 //- /main.rs
429 mod m1;
430 bar!(NotFoundNotMacroUse);
431 
432 mod m2 { foo!(NotFoundBeforeInside2); }
433 
434 macro_rules! foo {
435     ($x:ident) => { struct $x; }
436 }
437 foo!(Ok);
438 
439 mod m3;
440 foo!(OkShadowStop);
441 bar!(NotFoundMacroUseStop);
442 
443 #[macro_use]
444 mod m5 {
445     #[macro_use]
446     mod m6 {
447         macro_rules! foo {
448             ($x:ident) => { fn $x() {} }
449         }
450     }
451 }
452 foo!(ok_double_macro_use_shadow);
453 
454 baz!(NotFoundBefore);
455 #[macro_use]
456 mod m7 {
457     macro_rules! baz {
458         ($x:ident) => { struct $x; }
459     }
460 }
461 baz!(OkAfter);
462 
463 //- /m1.rs
464 foo!(NotFoundBeforeInside1);
465 macro_rules! bar {
466     ($x:ident) => { struct $x; }
467 }
468 
469 //- /m3/mod.rs
470 foo!(OkAfterInside);
471 macro_rules! foo {
472     ($x:ident) => { fn $x() {} }
473 }
474 foo!(ok_shadow);
475 
476 #[macro_use]
477 mod m4;
478 bar!(OkMacroUse);
479 
480 mod m5;
481 baz!(OkMacroUseInner);
482 
483 //- /m3/m4.rs
484 foo!(ok_shadow_deep);
485 macro_rules! bar {
486     ($x:ident) => { struct $x; }
487 }
488 //- /m3/m5.rs
489 #![macro_use]
490 macro_rules! baz {
491     ($x:ident) => { struct $x; }
492 }
493 
494 
495 "#,
496         expect![[r#"
497             crate
498             NotFoundBefore: t v
499             Ok: t v
500             OkAfter: t v
501             OkShadowStop: t v
502             m1: t
503             m2: t
504             m3: t
505             m5: t
506             m7: t
507             ok_double_macro_use_shadow: v
508 
509             crate::m1
510 
511             crate::m2
512 
513             crate::m3
514             OkAfterInside: t v
515             OkMacroUse: t v
516             OkMacroUseInner: t v
517             m4: t
518             m5: t
519             ok_shadow: v
520 
521             crate::m3::m4
522             ok_shadow_deep: v
523 
524             crate::m3::m5
525 
526             crate::m5
527             m6: t
528 
529             crate::m5::m6
530 
531             crate::m7
532         "#]],
533     );
534     // FIXME: should not see `NotFoundBefore`
535 }
536 
537 #[test]
type_value_macro_live_in_different_scopes()538 fn type_value_macro_live_in_different_scopes() {
539     check(
540         r#"
541 #[macro_export]
542 macro_rules! foo {
543     ($x:ident) => { type $x = (); }
544 }
545 
546 foo!(foo);
547 use foo as bar;
548 
549 use self::foo as baz;
550 fn baz() {}
551 "#,
552         expect![[r#"
553             crate
554             bar: t m
555             baz: t v m
556             foo: t m
557         "#]],
558     );
559 }
560 
561 #[test]
macro_use_can_be_aliased()562 fn macro_use_can_be_aliased() {
563     check(
564         r#"
565 //- /main.rs crate:main deps:foo
566 #[macro_use]
567 extern crate foo;
568 
569 foo!(Direct);
570 bar!(Alias);
571 
572 //- /lib.rs crate:foo
573 use crate::foo as bar;
574 
575 mod m {
576     #[macro_export]
577     macro_rules! foo {
578         ($x:ident) => { struct $x; }
579     }
580 }
581 "#,
582         expect![[r#"
583             crate
584             Alias: t v
585             Direct: t v
586             foo: t
587         "#]],
588     );
589 }
590 
591 #[test]
path_qualified_macros()592 fn path_qualified_macros() {
593     check(
594         r#"
595 macro_rules! foo {
596     ($x:ident) => { struct $x; }
597 }
598 
599 crate::foo!(NotResolved);
600 
601 crate::bar!(OkCrate);
602 bar!(OkPlain);
603 alias1!(NotHere);
604 m::alias1!(OkAliasPlain);
605 m::alias2!(OkAliasSuper);
606 m::alias3!(OkAliasCrate);
607 not_found!(NotFound);
608 
609 mod m {
610     #[macro_export]
611     macro_rules! bar {
612         ($x:ident) => { struct $x; }
613     }
614     pub use bar as alias1;
615     pub use super::bar as alias2;
616     pub use crate::bar as alias3;
617     pub use self::bar as not_found;
618 }
619 "#,
620         expect![[r#"
621             crate
622             OkAliasCrate: t v
623             OkAliasPlain: t v
624             OkAliasSuper: t v
625             OkCrate: t v
626             OkPlain: t v
627             bar: m
628             m: t
629 
630             crate::m
631             alias1: m
632             alias2: m
633             alias3: m
634             not_found: _
635         "#]],
636     );
637 }
638 
639 #[test]
macro_dollar_crate_is_correct_in_item()640 fn macro_dollar_crate_is_correct_in_item() {
641     cov_mark::check!(macro_dollar_crate_self);
642     check(
643         r#"
644 //- /main.rs crate:main deps:foo
645 #[macro_use]
646 extern crate foo;
647 
648 #[macro_use]
649 mod m {
650     macro_rules! current {
651         () => {
652             use $crate::Foo as FooSelf;
653         }
654     }
655 }
656 
657 struct Foo;
658 
659 current!();
660 not_current1!();
661 foo::not_current2!();
662 
663 //- /lib.rs crate:foo
664 mod m {
665     #[macro_export]
666     macro_rules! not_current1 {
667         () => {
668             use $crate::Bar;
669         }
670     }
671 }
672 
673 #[macro_export]
674 macro_rules! not_current2 {
675     () => {
676         use $crate::Baz;
677     }
678 }
679 
680 pub struct Bar;
681 pub struct Baz;
682 "#,
683         expect![[r#"
684             crate
685             Bar: t v
686             Baz: t v
687             Foo: t v
688             FooSelf: t v
689             foo: t
690             m: t
691 
692             crate::m
693         "#]],
694     );
695 }
696 
697 #[test]
macro_dollar_crate_is_correct_in_indirect_deps()698 fn macro_dollar_crate_is_correct_in_indirect_deps() {
699     cov_mark::check!(macro_dollar_crate_other);
700     // From std
701     check(
702         r#"
703 //- /main.rs edition:2018 crate:main deps:std
704 foo!();
705 
706 //- /std.rs crate:std deps:core
707 pub use core::foo;
708 
709 pub mod prelude {
710     pub mod rust_2018 {}
711 }
712 
713 #[macro_use]
714 mod std_macros;
715 
716 //- /core.rs crate:core
717 #[macro_export]
718 macro_rules! foo {
719     () => {
720         use $crate::bar;
721     }
722 }
723 
724 pub struct bar;
725 "#,
726         expect![[r#"
727             crate
728             bar: t v
729         "#]],
730     );
731 }
732 
733 #[test]
macro_dollar_crate_is_correct_in_derive_meta()734 fn macro_dollar_crate_is_correct_in_derive_meta() {
735     let map = compute_crate_def_map(
736         r#"
737 //- minicore: derive, clone
738 //- /main.rs crate:main deps:lib
739 lib::foo!();
740 
741 //- /lib.rs crate:lib
742 #[macro_export]
743 macro_rules! foo {
744     () => {
745         #[derive($crate::Clone)]
746         struct S;
747     }
748 }
749 
750 pub use core::clone::Clone;
751 "#,
752     );
753     assert_eq!(map.modules[DefMap::ROOT].scope.impls().len(), 1);
754 }
755 
756 #[test]
expand_derive()757 fn expand_derive() {
758     let map = compute_crate_def_map(
759         r#"
760 //- /main.rs crate:main deps:core
761 use core::Copy;
762 
763 #[core::derive(Copy, core::Clone)]
764 struct Foo;
765 
766 //- /core.rs crate:core
767 #[rustc_builtin_macro]
768 pub macro derive($item:item) {}
769 #[rustc_builtin_macro]
770 pub macro Copy {}
771 #[rustc_builtin_macro]
772 pub macro Clone {}
773 "#,
774     );
775     assert_eq!(map.modules[DefMap::ROOT].scope.impls().len(), 2);
776 }
777 
778 #[test]
resolve_builtin_derive()779 fn resolve_builtin_derive() {
780     check(
781         r#"
782 //- /main.rs crate:main deps:core
783 use core::*;
784 
785 //- /core.rs crate:core
786 #[rustc_builtin_macro]
787 pub macro Clone {}
788 
789 pub trait Clone {}
790 "#,
791         expect![[r#"
792             crate
793             Clone: t m
794         "#]],
795     );
796 }
797 
798 #[test]
builtin_derive_with_unresolved_attributes_fall_back()799 fn builtin_derive_with_unresolved_attributes_fall_back() {
800     // Tests that we still resolve derives after ignoring an unresolved attribute.
801     cov_mark::check!(unresolved_attribute_fallback);
802     let map = compute_crate_def_map(
803         r#"
804 //- /main.rs crate:main deps:core
805 use core::{Clone, derive};
806 
807 #[derive(Clone)]
808 #[unresolved]
809 struct Foo;
810 
811 //- /core.rs crate:core
812 #[rustc_builtin_macro]
813 pub macro derive($item:item) {}
814 #[rustc_builtin_macro]
815 pub macro Clone {}
816 "#,
817     );
818     assert_eq!(map.modules[DefMap::ROOT].scope.impls().len(), 1);
819 }
820 
821 #[test]
unresolved_attributes_fall_back_track_per_file_moditems()822 fn unresolved_attributes_fall_back_track_per_file_moditems() {
823     // Tests that we track per-file ModItems when ignoring an unresolved attribute.
824     // Just tracking the `ModItem` leads to `Foo` getting ignored.
825 
826     check(
827         r#"
828         //- /main.rs crate:main
829 
830         mod submod;
831 
832         #[unresolved]
833         struct Foo;
834 
835         //- /submod.rs
836         #[unresolved]
837         struct Bar;
838         "#,
839         expect![[r#"
840             crate
841             Foo: t v
842             submod: t
843 
844             crate::submod
845             Bar: t v
846         "#]],
847     );
848 }
849 
850 #[test]
unresolved_attrs_extern_block_hang()851 fn unresolved_attrs_extern_block_hang() {
852     // Regression test for https://github.com/rust-lang/rust-analyzer/issues/8905
853     check(
854         r#"
855 #[unresolved]
856 extern "C" {
857     #[unresolved]
858     fn f();
859 }
860     "#,
861         expect![[r#"
862         crate
863         f: v
864     "#]],
865     );
866 }
867 
868 #[test]
macros_in_extern_block()869 fn macros_in_extern_block() {
870     check(
871         r#"
872 macro_rules! m {
873     () => { static S: u8; };
874 }
875 
876 extern {
877     m!();
878 }
879     "#,
880         expect![[r#"
881             crate
882             S: v
883         "#]],
884     );
885 }
886 
887 #[test]
resolves_derive_helper()888 fn resolves_derive_helper() {
889     cov_mark::check!(resolved_derive_helper);
890     check(
891         r#"
892 //- /main.rs crate:main deps:proc
893 #[rustc_builtin_macro]
894 pub macro derive($item:item) {}
895 
896 #[derive(proc::Derive)]
897 #[helper]
898 #[unresolved]
899 struct S;
900 
901 //- /proc.rs crate:proc
902 #![crate_type="proc-macro"]
903 #[proc_macro_derive(Derive, attributes(helper))]
904 fn derive() {}
905         "#,
906         expect![[r#"
907             crate
908             S: t v
909             derive: m
910         "#]],
911     );
912 }
913 
914 #[test]
resolves_derive_helper_rustc_builtin_macro()915 fn resolves_derive_helper_rustc_builtin_macro() {
916     cov_mark::check!(resolved_derive_helper);
917     // This is NOT the correct usage of `default` helper attribute, but we don't resolve helper
918     // attributes on non mod items in hir nameres.
919     check(
920         r#"
921 //- minicore: derive, default
922 #[derive(Default)]
923 #[default]
924 enum E {
925     A,
926     B,
927 }
928 "#,
929         expect![[r#"
930             crate
931             E: t
932         "#]],
933     );
934 }
935 
936 #[test]
unresolved_attr_with_cfg_attr_hang()937 fn unresolved_attr_with_cfg_attr_hang() {
938     // Another regression test for https://github.com/rust-lang/rust-analyzer/issues/8905
939     check(
940         r#"
941 #[cfg_attr(not(off), unresolved, unresolved)]
942 struct S;
943         "#,
944         expect![[r#"
945             crate
946             S: t v
947         "#]],
948     );
949 }
950 
951 #[test]
macro_expansion_overflow()952 fn macro_expansion_overflow() {
953     cov_mark::check!(macro_expansion_overflow);
954     check(
955         r#"
956 macro_rules! a {
957     ($e:expr; $($t:tt)*) => {
958         b!(static = (); $($t)*);
959     };
960     () => {};
961 }
962 
963 macro_rules! b {
964     (static = $e:expr; $($t:tt)*) => {
965         a!($e; $($t)*);
966     };
967     () => {};
968 }
969 
970 b! { static = #[] ();}
971 "#,
972         expect![[r#"
973             crate
974         "#]],
975     );
976 }
977 
978 #[test]
macros_defining_macros()979 fn macros_defining_macros() {
980     check(
981         r#"
982 macro_rules! item {
983     ($item:item) => { $item }
984 }
985 
986 item! {
987     macro_rules! indirect_macro { () => { struct S {} } }
988 }
989 
990 indirect_macro!();
991     "#,
992         expect![[r#"
993             crate
994             S: t
995         "#]],
996     );
997 }
998 
999 #[test]
resolves_proc_macros()1000 fn resolves_proc_macros() {
1001     check(
1002         r#"
1003 #![crate_type="proc-macro"]
1004 struct TokenStream;
1005 
1006 #[proc_macro]
1007 pub fn function_like_macro(args: TokenStream) -> TokenStream {
1008     args
1009 }
1010 
1011 #[proc_macro_attribute]
1012 pub fn attribute_macro(_args: TokenStream, item: TokenStream) -> TokenStream {
1013     item
1014 }
1015 
1016 #[proc_macro_derive(DummyTrait)]
1017 pub fn derive_macro(_item: TokenStream) -> TokenStream {
1018     TokenStream
1019 }
1020 
1021 #[proc_macro_derive(AnotherTrait, attributes(helper_attr))]
1022 pub fn derive_macro_2(_item: TokenStream) -> TokenStream {
1023     TokenStream
1024 }
1025 "#,
1026         expect![[r#"
1027             crate
1028             AnotherTrait: m
1029             DummyTrait: m
1030             TokenStream: t v
1031             attribute_macro: v m
1032             derive_macro: v
1033             derive_macro_2: v
1034             function_like_macro: v m
1035         "#]],
1036     );
1037 }
1038 
1039 #[test]
proc_macro_censoring()1040 fn proc_macro_censoring() {
1041     // Make sure that only proc macros are publicly exported from proc-macro crates.
1042 
1043     check(
1044         r#"
1045 //- /main.rs crate:main deps:macros
1046 pub use macros::*;
1047 
1048 //- /macros.rs crate:macros
1049 #![crate_type="proc-macro"]
1050 pub struct TokenStream;
1051 
1052 #[proc_macro]
1053 pub fn function_like_macro(args: TokenStream) -> TokenStream {
1054     args
1055 }
1056 
1057 #[proc_macro_attribute]
1058 pub fn attribute_macro(_args: TokenStream, item: TokenStream) -> TokenStream {
1059     item
1060 }
1061 
1062 #[proc_macro_derive(DummyTrait)]
1063 pub fn derive_macro(_item: TokenStream) -> TokenStream {
1064     TokenStream
1065 }
1066 
1067 #[macro_export]
1068 macro_rules! mbe {
1069     () => {};
1070 }
1071 "#,
1072         expect![[r#"
1073             crate
1074             DummyTrait: m
1075             attribute_macro: m
1076             function_like_macro: m
1077         "#]],
1078     );
1079 }
1080 
1081 #[test]
collects_derive_helpers()1082 fn collects_derive_helpers() {
1083     let db = TestDB::with_files(
1084         r#"
1085 #![crate_type="proc-macro"]
1086 struct TokenStream;
1087 
1088 #[proc_macro_derive(AnotherTrait, attributes(helper_attr))]
1089 pub fn derive_macro_2(_item: TokenStream) -> TokenStream {
1090     TokenStream
1091 }
1092 "#,
1093     );
1094     let krate = db.crate_graph().iter().next().unwrap();
1095     let def_map = db.crate_def_map(krate);
1096 
1097     assert_eq!(def_map.data.exported_derives.len(), 1);
1098     match def_map.data.exported_derives.values().next() {
1099         Some(helpers) => match &**helpers {
1100             [attr] => assert_eq!(attr.display(&db).to_string(), "helper_attr"),
1101             _ => unreachable!(),
1102         },
1103         _ => unreachable!(),
1104     }
1105 }
1106 
1107 #[test]
resolve_macro_def()1108 fn resolve_macro_def() {
1109     check(
1110         r#"
1111 pub macro structs($($i:ident),*) {
1112     $(struct $i { field: u32 } )*
1113 }
1114 structs!(Foo);
1115 "#,
1116         expect![[r#"
1117             crate
1118             Foo: t
1119             structs: m
1120         "#]],
1121     );
1122 }
1123 
1124 #[test]
macro_in_prelude()1125 fn macro_in_prelude() {
1126     check(
1127         r#"
1128 //- /lib.rs edition:2018 crate:lib deps:std
1129 global_asm!();
1130 
1131 //- /std.rs crate:std
1132 pub mod prelude {
1133     pub mod rust_2018 {
1134         pub macro global_asm() {
1135             pub struct S;
1136         }
1137     }
1138 }
1139         "#,
1140         expect![[r#"
1141             crate
1142             S: t v
1143         "#]],
1144     )
1145 }
1146 
1147 #[test]
issue9358_bad_macro_stack_overflow()1148 fn issue9358_bad_macro_stack_overflow() {
1149     cov_mark::check!(issue9358_bad_macro_stack_overflow);
1150     check(
1151         r#"
1152 macro_rules! m {
1153   ($cond:expr) => { m!($cond, stringify!($cond)) };
1154   ($cond:expr, $($arg:tt)*) => { $cond };
1155 }
1156 m!(
1157 "#,
1158         expect![[r#"
1159             crate
1160         "#]],
1161     )
1162 }
1163 
1164 #[test]
eager_macro_correctly_resolves_contents()1165 fn eager_macro_correctly_resolves_contents() {
1166     // Eager macros resolve any contained macros when expanded. This should work correctly with the
1167     // usual name resolution rules, so both of these `include!`s should include the right file.
1168 
1169     check(
1170         r#"
1171 //- /lib.rs
1172 #[rustc_builtin_macro]
1173 macro_rules! include { () => {} }
1174 
1175 include!(inner_a!());
1176 include!(crate::inner_b!());
1177 
1178 #[macro_export]
1179 macro_rules! inner_a {
1180     () => { "inc_a.rs" };
1181 }
1182 #[macro_export]
1183 macro_rules! inner_b {
1184     () => { "inc_b.rs" };
1185 }
1186 //- /inc_a.rs
1187 struct A;
1188 //- /inc_b.rs
1189 struct B;
1190 "#,
1191         expect![[r#"
1192         crate
1193         A: t v
1194         B: t v
1195         inner_a: m
1196         inner_b: m
1197     "#]],
1198     );
1199 }
1200 
1201 #[test]
eager_macro_correctly_resolves_dollar_crate()1202 fn eager_macro_correctly_resolves_dollar_crate() {
1203     // MBE -> eager -> $crate::mbe
1204     check(
1205         r#"
1206 //- /lib.rs
1207 #[rustc_builtin_macro]
1208 macro_rules! include { () => {} }
1209 
1210 #[macro_export]
1211 macro_rules! inner {
1212     () => { "inc.rs" };
1213 }
1214 
1215 macro_rules! m {
1216     () => { include!($crate::inner!()); };
1217 }
1218 
1219 m!();
1220 
1221 //- /inc.rs
1222 struct A;
1223 "#,
1224         expect![[r#"
1225             crate
1226             A: t v
1227             inner: m
1228         "#]],
1229     );
1230     // eager -> MBE -> $crate::mbe
1231     check(
1232         r#"
1233 //- /lib.rs
1234 #[rustc_builtin_macro]
1235 macro_rules! include { () => {} }
1236 
1237 #[macro_export]
1238 macro_rules! inner {
1239     () => { "inc.rs" };
1240 }
1241 
1242 macro_rules! n {
1243     () => {
1244         $crate::inner!()
1245     };
1246 }
1247 
1248 include!(n!());
1249 
1250 //- /inc.rs
1251 struct A;
1252 "#,
1253         expect![[r#"
1254             crate
1255             A: t v
1256             inner: m
1257         "#]],
1258     );
1259 }
1260 
1261 #[test]
macro_use_imports_all_macro_types()1262 fn macro_use_imports_all_macro_types() {
1263     let db = TestDB::with_files(
1264         r#"
1265 //- /main.rs crate:main deps:lib
1266 #[macro_use]
1267 extern crate lib;
1268 
1269 //- /lib.rs crate:lib deps:proc
1270 pub use proc::*;
1271 
1272 #[macro_export]
1273 macro_rules! legacy { () => () }
1274 
1275 pub macro macro20 {}
1276 
1277 //- /proc.rs crate:proc
1278 #![crate_type="proc-macro"]
1279 
1280 struct TokenStream;
1281 
1282 #[proc_macro_attribute]
1283 fn proc_attr(a: TokenStream, b: TokenStream) -> TokenStream { a }
1284     "#,
1285     );
1286     let krate = db.crate_graph().iter().next().unwrap();
1287     let def_map = db.crate_def_map(krate);
1288 
1289     let root_module = &def_map[DefMap::ROOT].scope;
1290     assert!(
1291         root_module.legacy_macros().count() == 0,
1292         "`#[macro_use]` shouldn't bring macros into textual macro scope",
1293     );
1294 
1295     let actual = def_map
1296         .macro_use_prelude
1297         .iter()
1298         .map(|(name, _)| name.display(&db).to_string())
1299         .sorted()
1300         .join("\n");
1301 
1302     expect![[r#"
1303         legacy
1304         macro20
1305         proc_attr"#]]
1306     .assert_eq(&actual);
1307 }
1308 
1309 #[test]
non_prelude_macros_take_precedence_over_macro_use_prelude()1310 fn non_prelude_macros_take_precedence_over_macro_use_prelude() {
1311     check(
1312         r#"
1313 //- /lib.rs edition:2021 crate:lib deps:dep,core
1314 #[macro_use]
1315 extern crate dep;
1316 
1317 macro foo() { struct Ok; }
1318 macro bar() { fn ok() {} }
1319 
1320 foo!();
1321 bar!();
1322 
1323 //- /dep.rs crate:dep
1324 #[macro_export]
1325 macro_rules! foo {
1326     () => { struct NotOk; }
1327 }
1328 
1329 //- /core.rs crate:core
1330 pub mod prelude {
1331     pub mod rust_2021 {
1332         #[macro_export]
1333         macro_rules! bar {
1334             () => { fn not_ok() {} }
1335         }
1336     }
1337 }
1338         "#,
1339         expect![[r#"
1340             crate
1341             Ok: t v
1342             bar: m
1343             dep: t
1344             foo: m
1345             ok: v
1346         "#]],
1347     );
1348 }
1349 
1350 #[test]
macro_use_prelude_is_eagerly_expanded()1351 fn macro_use_prelude_is_eagerly_expanded() {
1352     // See FIXME in `ModCollector::collect_macro_call()`.
1353     check(
1354         r#"
1355 //- /main.rs crate:main deps:lib
1356 #[macro_use]
1357 extern crate lib;
1358 mk_foo!();
1359 mod a {
1360     foo!();
1361 }
1362 //- /lib.rs crate:lib
1363 #[macro_export]
1364 macro_rules! mk_foo {
1365     () => {
1366         macro_rules! foo {
1367             () => { struct Ok; }
1368         }
1369     }
1370 }
1371     "#,
1372         expect![[r#"
1373         crate
1374         a: t
1375         lib: t
1376 
1377         crate::a
1378         Ok: t v
1379     "#]],
1380     );
1381 }
1382 
1383 #[test]
macro_sub_namespace()1384 fn macro_sub_namespace() {
1385     let map = compute_crate_def_map(
1386         r#"
1387 //- minicore: derive, clone
1388 macro_rules! Clone { () => {} }
1389 macro_rules! derive { () => {} }
1390 
1391 #[derive(Clone)]
1392 struct S;
1393     "#,
1394     );
1395     assert_eq!(map.modules[DefMap::ROOT].scope.impls().len(), 1);
1396 }
1397 
1398 #[test]
macro_sub_namespace2()1399 fn macro_sub_namespace2() {
1400     check(
1401         r#"
1402 //- /main.rs edition:2021 crate:main deps:proc,core
1403 use proc::{foo, bar};
1404 
1405 foo!();
1406 bar!();
1407 
1408 //- /proc.rs crate:proc
1409 #![crate_type="proc-macro"]
1410 #[proc_macro_derive(foo)]
1411 pub fn foo() {}
1412 #[proc_macro_attribute]
1413 pub fn bar() {}
1414 
1415 //- /core.rs crate:core
1416 pub mod prelude {
1417     pub mod rust_2021 {
1418         pub macro foo() {
1419             struct Ok;
1420         }
1421         pub macro bar() {
1422             fn ok() {}
1423         }
1424     }
1425 }
1426     "#,
1427         expect![[r#"
1428             crate
1429             Ok: t v
1430             bar: m
1431             foo: m
1432             ok: v
1433         "#]],
1434     );
1435 }
1436