]> git.lizzy.rs Git - rust.git/blob - crates/hir_def/src/macro_expansion_tests/mbe.rs
Merge #10824
[rust.git] / crates / hir_def / src / macro_expansion_tests / mbe.rs
1 //! Tests specific to declarative macros, aka macros by example. This covers
2 //! both stable `macro_rules!` macros as well as unstable `macro` macros.
3
4 mod tt_conversion;
5 mod matching;
6 mod meta_syntax;
7 mod regression;
8
9 use expect_test::expect;
10
11 use crate::macro_expansion_tests::check;
12
13 #[test]
14 fn token_mapping_smoke_test() {
15     check(
16         r#"
17 // +tokenids
18 macro_rules! f {
19     ( struct $ident:ident ) => {
20         struct $ident {
21             map: ::std::collections::HashSet<()>,
22         }
23     };
24 }
25
26 // +tokenids
27 f!(struct MyTraitMap2);
28 "#,
29         expect![[r##"
30 // call ids will be shifted by Shift(30)
31 // +tokenids
32 macro_rules! f {#0
33     (#1 struct#2 $#3ident#4:#5ident#6 )#1 =#7>#8 {#9
34         struct#10 $#11ident#12 {#13
35             map#14:#15 :#16:#17std#18:#19:#20collections#21:#22:#23HashSet#24<#25(#26)#26>#27,#28
36         }#13
37     }#9;#29
38 }#0
39
40 // // +tokenids
41 // f!(struct#1 MyTraitMap2#2);
42 struct#10 MyTraitMap2#32 {#13
43     map#14:#15 ::std#18::collections#21::HashSet#24<#25(#26)#26>#27,#28
44 }#13
45 "##]],
46     );
47 }
48
49 #[test]
50 fn mbe_smoke_test() {
51     check(
52         r#"
53 macro_rules! impl_froms {
54     ($e:ident: $($v:ident),*) => {
55         $(
56             impl From<$v> for $e {
57                 fn from(it: $v) -> $e { $e::$v(it) }
58             }
59         )*
60     }
61 }
62 impl_froms!(TokenTree: Leaf, Subtree);
63 "#,
64         expect![[r#"
65 macro_rules! impl_froms {
66     ($e:ident: $($v:ident),*) => {
67         $(
68             impl From<$v> for $e {
69                 fn from(it: $v) -> $e { $e::$v(it) }
70             }
71         )*
72     }
73 }
74 impl From<Leaf> for TokenTree {
75     fn from(it: Leaf) -> TokenTree {
76         TokenTree::Leaf(it)
77     }
78 }
79 impl From<Subtree> for TokenTree {
80     fn from(it: Subtree) -> TokenTree {
81         TokenTree::Subtree(it)
82     }
83 }
84 "#]],
85     );
86 }
87
88 #[test]
89 fn expansion_does_not_parse_as_expression() {
90     check(
91         r#"
92 macro_rules! stmts {
93     () => { let _ = 0; }
94 }
95
96 fn f() { let _ = stmts!(); }
97 "#,
98         expect![[r#"
99 macro_rules! stmts {
100     () => { let _ = 0; }
101 }
102
103 fn f() { let _ = /* error: could not convert tokens */; }
104 "#]],
105     )
106 }
107
108 #[test]
109 fn wrong_nesting_level() {
110     check(
111         r#"
112 macro_rules! m {
113     ($($i:ident);*) => ($i)
114 }
115 m!{a}
116 "#,
117         expect![[r#"
118 macro_rules! m {
119     ($($i:ident);*) => ($i)
120 }
121 /* error: expected simple binding, found nested binding `i` */
122 "#]],
123     );
124 }
125
126 #[test]
127 fn match_by_first_token_literally() {
128     check(
129         r#"
130 macro_rules! m {
131     ($i:ident) => ( mod $i {} );
132     (= $i:ident) => ( fn $i() {} );
133     (+ $i:ident) => ( struct $i; )
134 }
135 m! { foo }
136 m! { = bar }
137 m! { + Baz }
138 "#,
139         expect![[r#"
140 macro_rules! m {
141     ($i:ident) => ( mod $i {} );
142     (= $i:ident) => ( fn $i() {} );
143     (+ $i:ident) => ( struct $i; )
144 }
145 mod foo {}
146 fn bar() {}
147 struct Baz;
148 "#]],
149     );
150 }
151
152 #[test]
153 fn match_by_last_token_literally() {
154     check(
155         r#"
156 macro_rules! m {
157     ($i:ident) => ( mod $i {} );
158     ($i:ident =) => ( fn $i() {} );
159     ($i:ident +) => ( struct $i; )
160 }
161 m! { foo }
162 m! { bar = }
163 m! { Baz + }
164 "#,
165         expect![[r#"
166 macro_rules! m {
167     ($i:ident) => ( mod $i {} );
168     ($i:ident =) => ( fn $i() {} );
169     ($i:ident +) => ( struct $i; )
170 }
171 mod foo {}
172 fn bar() {}
173 struct Baz;
174 "#]],
175     );
176 }
177
178 #[test]
179 fn match_by_ident() {
180     check(
181         r#"
182 macro_rules! m {
183     ($i:ident) => ( mod $i {} );
184     (spam $i:ident) => ( fn $i() {} );
185     (eggs $i:ident) => ( struct $i; )
186 }
187 m! { foo }
188 m! { spam bar }
189 m! { eggs Baz }
190 "#,
191         expect![[r#"
192 macro_rules! m {
193     ($i:ident) => ( mod $i {} );
194     (spam $i:ident) => ( fn $i() {} );
195     (eggs $i:ident) => ( struct $i; )
196 }
197 mod foo {}
198 fn bar() {}
199 struct Baz;
200 "#]],
201     );
202 }
203
204 #[test]
205 fn match_by_separator_token() {
206     check(
207         r#"
208 macro_rules! m {
209     ($($i:ident),*) => ($(mod $i {} )*);
210     ($($i:ident)#*) => ($(fn $i() {} )*);
211     ($i:ident ,# $ j:ident) => ( struct $i; struct $ j; )
212 }
213
214 m! { foo, bar }
215
216 m! { foo# bar }
217
218 m! { Foo,# Bar }
219 "#,
220         expect![[r##"
221 macro_rules! m {
222     ($($i:ident),*) => ($(mod $i {} )*);
223     ($($i:ident)#*) => ($(fn $i() {} )*);
224     ($i:ident ,# $ j:ident) => ( struct $i; struct $ j; )
225 }
226
227 mod foo {}
228 mod bar {}
229
230 fn foo() {}
231 fn bar() {}
232
233 struct Foo;
234 struct Bar;
235 "##]],
236     );
237 }
238
239 #[test]
240 fn test_match_group_pattern_with_multiple_defs() {
241     check(
242         r#"
243 macro_rules! m {
244     ($($i:ident),*) => ( impl Bar { $(fn $i() {})* } );
245 }
246 m! { foo, bar }
247 "#,
248         expect![[r#"
249 macro_rules! m {
250     ($($i:ident),*) => ( impl Bar { $(fn $i() {})* } );
251 }
252 impl Bar {
253     fn foo() {}
254     fn bar() {}
255 }
256 "#]],
257     );
258 }
259
260 #[test]
261 fn test_match_group_pattern_with_multiple_statement() {
262     check(
263         r#"
264 macro_rules! m {
265     ($($i:ident),*) => ( fn baz() { $($i ();)* } );
266 }
267 m! { foo, bar }
268 "#,
269         expect![[r#"
270 macro_rules! m {
271     ($($i:ident),*) => ( fn baz() { $($i ();)* } );
272 }
273 fn baz() {
274     foo();
275     bar();
276 }
277 "#]],
278     )
279 }
280
281 #[test]
282 fn test_match_group_pattern_with_multiple_statement_without_semi() {
283     check(
284         r#"
285 macro_rules! m {
286     ($($i:ident),*) => ( fn baz() { $($i() );* } );
287 }
288 m! { foo, bar }
289 "#,
290         expect![[r#"
291 macro_rules! m {
292     ($($i:ident),*) => ( fn baz() { $($i() );* } );
293 }
294 fn baz() {
295     foo();
296     bar()
297 }
298 "#]],
299     )
300 }
301
302 #[test]
303 fn test_match_group_empty_fixed_token() {
304     check(
305         r#"
306 macro_rules! m {
307     ($($i:ident)* #abc) => ( fn baz() { $($i ();)* } );
308 }
309 m!{#abc}
310 "#,
311         expect![[r##"
312 macro_rules! m {
313     ($($i:ident)* #abc) => ( fn baz() { $($i ();)* } );
314 }
315 fn baz() {}
316 "##]],
317     )
318 }
319
320 #[test]
321 fn test_match_group_in_subtree() {
322     check(
323         r#"
324 macro_rules! m {
325     (fn $name:ident { $($i:ident)* } ) => ( fn $name() { $($i ();)* } );
326 }
327 m! { fn baz { a b } }
328 "#,
329         expect![[r#"
330 macro_rules! m {
331     (fn $name:ident { $($i:ident)* } ) => ( fn $name() { $($i ();)* } );
332 }
333 fn baz() {
334     a();
335     b();
336 }
337 "#]],
338     )
339 }
340
341 #[test]
342 fn test_expr_order() {
343     check(
344         r#"
345 macro_rules! m {
346     ($ i:expr) => { fn bar() { $ i * 3; } }
347 }
348 // +tree
349 m! { 1 + 2 }
350 "#,
351         expect![[r#"
352 macro_rules! m {
353     ($ i:expr) => { fn bar() { $ i * 3; } }
354 }
355 fn bar() {
356     (1+2)*3;
357 }
358 // MACRO_ITEMS@0..17
359 //   FN@0..17
360 //     FN_KW@0..2 "fn"
361 //     NAME@2..5
362 //       IDENT@2..5 "bar"
363 //     PARAM_LIST@5..7
364 //       L_PAREN@5..6 "("
365 //       R_PAREN@6..7 ")"
366 //     BLOCK_EXPR@7..17
367 //       STMT_LIST@7..17
368 //         L_CURLY@7..8 "{"
369 //         EXPR_STMT@8..16
370 //           BIN_EXPR@8..15
371 //             PAREN_EXPR@8..13
372 //               L_PAREN@8..9 "("
373 //               BIN_EXPR@9..12
374 //                 LITERAL@9..10
375 //                   INT_NUMBER@9..10 "1"
376 //                 PLUS@10..11 "+"
377 //                 LITERAL@11..12
378 //                   INT_NUMBER@11..12 "2"
379 //               R_PAREN@12..13 ")"
380 //             STAR@13..14 "*"
381 //             LITERAL@14..15
382 //               INT_NUMBER@14..15 "3"
383 //           SEMICOLON@15..16 ";"
384 //         R_CURLY@16..17 "}"
385
386 "#]],
387     )
388 }
389
390 #[test]
391 fn test_match_group_with_multichar_sep() {
392     check(
393         r#"
394 macro_rules! m {
395     (fn $name:ident { $($i:literal)* }) => ( fn $name() -> bool { $($i)&&* } );
396 }
397 m! (fn baz { true false } );
398 "#,
399         expect![[r#"
400 macro_rules! m {
401     (fn $name:ident { $($i:literal)* }) => ( fn $name() -> bool { $($i)&&* } );
402 }
403 fn baz() -> bool {
404     true && false
405 }
406 "#]],
407     );
408
409     check(
410         r#"
411 macro_rules! m {
412     (fn $name:ident { $($i:literal)&&* }) => ( fn $name() -> bool { $($i)&&* } );
413 }
414 m! (fn baz { true && false } );
415 "#,
416         expect![[r#"
417 macro_rules! m {
418     (fn $name:ident { $($i:literal)&&* }) => ( fn $name() -> bool { $($i)&&* } );
419 }
420 fn baz() -> bool {
421     true && false
422 }
423 "#]],
424     );
425 }
426
427 #[test]
428 fn test_match_group_zero_match() {
429     check(
430         r#"
431 macro_rules! m { ( $($i:ident)* ) => (); }
432 m!();
433 "#,
434         expect![[r#"
435 macro_rules! m { ( $($i:ident)* ) => (); }
436
437 "#]],
438     );
439 }
440
441 #[test]
442 fn test_match_group_in_group() {
443     check(
444         r#"
445 macro_rules! m {
446     [ $( ( $($i:ident)* ) )* ] => [ ok![$( ( $($i)* ) )*]; ]
447 }
448 m! ( (a b) );
449 "#,
450         expect![[r#"
451 macro_rules! m {
452     [ $( ( $($i:ident)* ) )* ] => [ ok![$( ( $($i)* ) )*]; ]
453 }
454 ok![(a b)];
455 "#]],
456     )
457 }
458
459 #[test]
460 fn test_expand_to_item_list() {
461     check(
462         r#"
463 macro_rules! structs {
464     ($($i:ident),*) => { $(struct $i { field: u32 } )* }
465 }
466
467 // +tree
468 structs!(Foo, Bar);
469             "#,
470         expect![[r#"
471 macro_rules! structs {
472     ($($i:ident),*) => { $(struct $i { field: u32 } )* }
473 }
474
475 struct Foo {
476     field: u32
477 }
478 struct Bar {
479     field: u32
480 }
481 // MACRO_ITEMS@0..40
482 //   STRUCT@0..20
483 //     STRUCT_KW@0..6 "struct"
484 //     NAME@6..9
485 //       IDENT@6..9 "Foo"
486 //     RECORD_FIELD_LIST@9..20
487 //       L_CURLY@9..10 "{"
488 //       RECORD_FIELD@10..19
489 //         NAME@10..15
490 //           IDENT@10..15 "field"
491 //         COLON@15..16 ":"
492 //         PATH_TYPE@16..19
493 //           PATH@16..19
494 //             PATH_SEGMENT@16..19
495 //               NAME_REF@16..19
496 //                 IDENT@16..19 "u32"
497 //       R_CURLY@19..20 "}"
498 //   STRUCT@20..40
499 //     STRUCT_KW@20..26 "struct"
500 //     NAME@26..29
501 //       IDENT@26..29 "Bar"
502 //     RECORD_FIELD_LIST@29..40
503 //       L_CURLY@29..30 "{"
504 //       RECORD_FIELD@30..39
505 //         NAME@30..35
506 //           IDENT@30..35 "field"
507 //         COLON@35..36 ":"
508 //         PATH_TYPE@36..39
509 //           PATH@36..39
510 //             PATH_SEGMENT@36..39
511 //               NAME_REF@36..39
512 //                 IDENT@36..39 "u32"
513 //       R_CURLY@39..40 "}"
514
515             "#]],
516     );
517 }
518
519 #[test]
520 fn test_two_idents() {
521     check(
522         r#"
523 macro_rules! m {
524     ($i:ident, $j:ident) => { fn foo() { let a = $i; let b = $j; } }
525 }
526 m! { foo, bar }
527 "#,
528         expect![[r#"
529 macro_rules! m {
530     ($i:ident, $j:ident) => { fn foo() { let a = $i; let b = $j; } }
531 }
532 fn foo() {
533     let a = foo;
534     let b = bar;
535 }
536 "#]],
537     );
538 }
539
540 #[test]
541 fn test_tt_to_stmts() {
542     check(
543         r#"
544 macro_rules! m {
545     () => {
546         let a = 0;
547         a = 10 + 1;
548         a
549     }
550 }
551
552 fn f() -> i32 {
553     // +tree
554     m!{}
555 }
556 "#,
557         expect![[r#"
558 macro_rules! m {
559     () => {
560         let a = 0;
561         a = 10 + 1;
562         a
563     }
564 }
565
566 fn f() -> i32 {
567     let a = 0;
568     a = 10+1;
569     a
570 // MACRO_STMTS@0..15
571 //   LET_STMT@0..7
572 //     LET_KW@0..3 "let"
573 //     IDENT_PAT@3..4
574 //       NAME@3..4
575 //         IDENT@3..4 "a"
576 //     EQ@4..5 "="
577 //     LITERAL@5..6
578 //       INT_NUMBER@5..6 "0"
579 //     SEMICOLON@6..7 ";"
580 //   EXPR_STMT@7..14
581 //     BIN_EXPR@7..13
582 //       PATH_EXPR@7..8
583 //         PATH@7..8
584 //           PATH_SEGMENT@7..8
585 //             NAME_REF@7..8
586 //               IDENT@7..8 "a"
587 //       EQ@8..9 "="
588 //       BIN_EXPR@9..13
589 //         LITERAL@9..11
590 //           INT_NUMBER@9..11 "10"
591 //         PLUS@11..12 "+"
592 //         LITERAL@12..13
593 //           INT_NUMBER@12..13 "1"
594 //     SEMICOLON@13..14 ";"
595 //   PATH_EXPR@14..15
596 //     PATH@14..15
597 //       PATH_SEGMENT@14..15
598 //         NAME_REF@14..15
599 //           IDENT@14..15 "a"
600
601 }
602 "#]],
603     );
604 }
605
606 #[test]
607 fn test_match_literal() {
608     check(
609         r#"
610 macro_rules! m {
611     ('(') => { fn l_paren() {} }
612 }
613 m!['('];
614 "#,
615         expect![[r#"
616 macro_rules! m {
617     ('(') => { fn l_paren() {} }
618 }
619 fn l_paren() {}
620 "#]],
621     );
622 }
623
624 #[test]
625 fn test_parse_macro_def_simple() {
626     cov_mark::check!(parse_macro_def_simple);
627     check(
628         r#"
629 macro m($id:ident) { fn $id() {} }
630 m!(bar);
631 "#,
632         expect![[r#"
633 macro m($id:ident) { fn $id() {} }
634 fn bar() {}
635 "#]],
636     );
637 }
638
639 #[test]
640 fn test_parse_macro_def_rules() {
641     cov_mark::check!(parse_macro_def_rules);
642
643     check(
644         r#"
645 macro m {
646     ($id:ident) => { fn $id() {} }
647 }
648 m!(bar);
649 "#,
650         expect![[r#"
651 macro m {
652     ($id:ident) => { fn $id() {} }
653 }
654 fn bar() {}
655 "#]],
656     );
657 }
658
659 #[test]
660 fn test_macro_2_0_panic_2015() {
661     check(
662         r#"
663 macro panic_2015 {
664     () => (),
665     (bar) => (),
666 }
667 panic_2015!(bar);
668 "#,
669         expect![[r#"
670 macro panic_2015 {
671     () => (),
672     (bar) => (),
673 }
674
675 "#]],
676     );
677 }
678
679 #[test]
680 fn test_path() {
681     check(
682         r#"
683 macro_rules! m {
684     ($p:path) => { fn foo() { let a = $p; } }
685 }
686
687 m! { foo }
688
689 m! { bar::<u8>::baz::<u8> }
690 "#,
691         expect![[r#"
692 macro_rules! m {
693     ($p:path) => { fn foo() { let a = $p; } }
694 }
695
696 fn foo() {
697     let a = foo;
698 }
699
700 fn foo() {
701     let a = bar::<u8>::baz::<u8> ;
702 }
703 "#]],
704     );
705 }
706
707 #[test]
708 fn test_two_paths() {
709     check(
710         r#"
711 macro_rules! m {
712     ($i:path, $j:path) => { fn foo() { let a = $ i; let b = $j; } }
713 }
714 m! { foo, bar }
715 "#,
716         expect![[r#"
717 macro_rules! m {
718     ($i:path, $j:path) => { fn foo() { let a = $ i; let b = $j; } }
719 }
720 fn foo() {
721     let a = foo;
722     let b = bar;
723 }
724 "#]],
725     );
726 }
727
728 #[test]
729 fn test_path_with_path() {
730     check(
731         r#"
732 macro_rules! m {
733     ($p:path) => { fn foo() { let a = $p::bar; } }
734 }
735 m! { foo }
736 "#,
737         expect![[r#"
738 macro_rules! m {
739     ($p:path) => { fn foo() { let a = $p::bar; } }
740 }
741 fn foo() {
742     let a = foo::bar;
743 }
744 "#]],
745     );
746 }
747
748 #[test]
749 fn test_expr() {
750     check(
751         r#"
752 macro_rules! m {
753     ($e:expr) => { fn bar() { $e; } }
754 }
755
756 m! { 2 + 2 * baz(3).quux() }
757 "#,
758         expect![[r#"
759 macro_rules! m {
760     ($e:expr) => { fn bar() { $e; } }
761 }
762
763 fn bar() {
764     (2+2*baz(3).quux());
765 }
766 "#]],
767     )
768 }
769
770 #[test]
771 fn test_last_expr() {
772     check(
773         r#"
774 macro_rules! vec {
775     ($($item:expr),*) => {{
776             let mut v = Vec::new();
777             $( v.push($item); )*
778             v
779     }};
780 }
781
782 fn f() {
783     vec![1,2,3];
784 }
785 "#,
786         expect![[r#"
787 macro_rules! vec {
788     ($($item:expr),*) => {{
789             let mut v = Vec::new();
790             $( v.push($item); )*
791             v
792     }};
793 }
794
795 fn f() {
796      {
797         let mut v = Vec::new();
798         v.push(1);
799         v.push(2);
800         v.push(3);
801         v
802     };
803 }
804 "#]],
805     );
806 }
807
808 #[test]
809 fn test_expr_with_attr() {
810     check(
811         r#"
812 macro_rules! m { ($a:expr) => { ok!(); } }
813 m!(#[allow(a)]());
814 "#,
815         expect![[r#"
816 macro_rules! m { ($a:expr) => { ok!(); } }
817 ok!();
818 "#]],
819     )
820 }
821
822 #[test]
823 fn test_ty() {
824     check(
825         r#"
826 macro_rules! m {
827     ($t:ty) => ( fn bar() -> $t {} )
828 }
829 m! { Baz<u8> }
830 "#,
831         expect![[r#"
832 macro_rules! m {
833     ($t:ty) => ( fn bar() -> $t {} )
834 }
835 fn bar() -> Baz<u8> {}
836 "#]],
837     )
838 }
839
840 #[test]
841 fn test_ty_with_complex_type() {
842     check(
843         r#"
844 macro_rules! m {
845     ($t:ty) => ( fn bar() -> $ t {} )
846 }
847
848 m! { &'a Baz<u8> }
849
850 m! { extern "Rust" fn() -> Ret }
851 "#,
852         expect![[r#"
853 macro_rules! m {
854     ($t:ty) => ( fn bar() -> $ t {} )
855 }
856
857 fn bar() -> & 'a Baz<u8> {}
858
859 fn bar() -> extern "Rust"fn() -> Ret {}
860 "#]],
861     );
862 }
863
864 #[test]
865 fn test_pat_() {
866     check(
867         r#"
868 macro_rules! m {
869     ($p:pat) => { fn foo() { let $p; } }
870 }
871 m! { (a, b) }
872 "#,
873         expect![[r#"
874 macro_rules! m {
875     ($p:pat) => { fn foo() { let $p; } }
876 }
877 fn foo() {
878     let (a, b);
879 }
880 "#]],
881     );
882 }
883
884 #[test]
885 fn test_stmt() {
886     check(
887         r#"
888 macro_rules! m {
889     ($s:stmt) => ( fn bar() { $s; } )
890 }
891 m! { 2 }
892 m! { let a = 0 }
893 "#,
894         expect![[r#"
895 macro_rules! m {
896     ($s:stmt) => ( fn bar() { $s; } )
897 }
898 fn bar() {
899     2;
900 }
901 fn bar() {
902     let a = 0;
903 }
904 "#]],
905     )
906 }
907
908 #[test]
909 fn test_single_item() {
910     check(
911         r#"
912 macro_rules! m { ($i:item) => ( $i ) }
913 m! { mod c {} }
914 "#,
915         expect![[r#"
916 macro_rules! m { ($i:item) => ( $i ) }
917 mod c {}
918 "#]],
919     )
920 }
921
922 #[test]
923 fn test_all_items() {
924     check(
925         r#"
926 macro_rules! m { ($($i:item)*) => ($($i )*) }
927 m! {
928     extern crate a;
929     mod b;
930     mod c {}
931     use d;
932     const E: i32 = 0;
933     static F: i32 = 0;
934     impl G {}
935     struct H;
936     enum I { Foo }
937     trait J {}
938     fn h() {}
939     extern {}
940     type T = u8;
941 }
942 "#,
943         expect![[r#"
944 macro_rules! m { ($($i:item)*) => ($($i )*) }
945 extern crate a;
946 mod b;
947 mod c {}
948 use d;
949 const E: i32 = 0;
950 static F: i32 = 0;
951 impl G {}
952 struct H;
953 enum I {
954     Foo
955 }
956 trait J {}
957 fn h() {}
958 extern {}
959 type T = u8;
960 "#]],
961     );
962 }
963
964 #[test]
965 fn test_block() {
966     check(
967         r#"
968 macro_rules! m { ($b:block) => { fn foo() $b } }
969 m! { { 1; } }
970 "#,
971         expect![[r#"
972 macro_rules! m { ($b:block) => { fn foo() $b } }
973 fn foo() {
974     1;
975 }
976 "#]],
977     );
978 }
979
980 #[test]
981 fn test_meta() {
982     check(
983         r#"
984 macro_rules! m {
985     ($m:meta) => ( #[$m] fn bar() {} )
986 }
987 m! { cfg(target_os = "windows") }
988 m! { hello::world }
989 "#,
990         expect![[r##"
991 macro_rules! m {
992     ($m:meta) => ( #[$m] fn bar() {} )
993 }
994 #[cfg(target_os = "windows")] fn bar() {}
995 #[hello::world] fn bar() {}
996 "##]],
997     );
998 }
999
1000 #[test]
1001 fn test_meta_doc_comments() {
1002     cov_mark::check!(test_meta_doc_comments);
1003     check(
1004         r#"
1005 macro_rules! m {
1006     ($(#[$m:meta])+) => ( $(#[$m])+ fn bar() {} )
1007 }
1008 m! {
1009     /// Single Line Doc 1
1010     /**
1011         MultiLines Doc
1012     */
1013 }
1014 "#,
1015         expect![[r##"
1016 macro_rules! m {
1017     ($(#[$m:meta])+) => ( $(#[$m])+ fn bar() {} )
1018 }
1019 #[doc = " Single Line Doc 1"]
1020 #[doc = "\n        MultiLines Doc\n    "] fn bar() {}
1021 "##]],
1022     );
1023 }
1024
1025 #[test]
1026 fn test_meta_extended_key_value_attributes() {
1027     check(
1028         r#"
1029 macro_rules! m {
1030     (#[$m:meta]) => ( #[$m] fn bar() {} )
1031 }
1032 m! { #[doc = concat!("The `", "bla", "` lang item.")] }
1033 "#,
1034         expect![[r##"
1035 macro_rules! m {
1036     (#[$m:meta]) => ( #[$m] fn bar() {} )
1037 }
1038 #[doc = concat!("The `", "bla", "` lang item.")] fn bar() {}
1039 "##]],
1040     );
1041 }
1042
1043 #[test]
1044 fn test_meta_doc_comments_non_latin() {
1045     check(
1046         r#"
1047 macro_rules! m {
1048     ($(#[$ m:meta])+) => ( $(#[$m])+ fn bar() {} )
1049 }
1050 m! {
1051     /// 錦瑟無端五十弦,一弦一柱思華年。
1052     /**
1053         莊生曉夢迷蝴蝶,望帝春心託杜鵑。
1054     */
1055 }
1056 "#,
1057         expect![[r##"
1058 macro_rules! m {
1059     ($(#[$ m:meta])+) => ( $(#[$m])+ fn bar() {} )
1060 }
1061 #[doc = " 錦瑟無端五十弦,一弦一柱思華年。"]
1062 #[doc = "\n        莊生曉夢迷蝴蝶,望帝春心託杜鵑。\n    "] fn bar() {}
1063 "##]],
1064     );
1065 }
1066
1067 #[test]
1068 fn test_meta_doc_comments_escaped_characters() {
1069     check(
1070         r#"
1071 macro_rules! m {
1072     ($(#[$m:meta])+) => ( $(#[$m])+ fn bar() {} )
1073 }
1074 m! {
1075     /// \ " '
1076 }
1077 "#,
1078         expect![[r##"
1079 macro_rules! m {
1080     ($(#[$m:meta])+) => ( $(#[$m])+ fn bar() {} )
1081 }
1082 #[doc = " \\ \" \'"] fn bar() {}
1083 "##]],
1084     );
1085 }
1086
1087 #[test]
1088 fn test_tt_block() {
1089     check(
1090         r#"
1091 macro_rules! m { ($tt:tt) => { fn foo() $tt } }
1092 m! { { 1; } }
1093 "#,
1094         expect![[r#"
1095 macro_rules! m { ($tt:tt) => { fn foo() $tt } }
1096 fn foo() {
1097     1;
1098 }
1099 "#]],
1100     );
1101 }
1102
1103 #[test]
1104 fn test_tt_group() {
1105     check(
1106         r#"
1107 macro_rules! m { ($($tt:tt)*) => { $($tt)* } }
1108 m! { fn foo() {} }"
1109 "#,
1110         expect![[r#"
1111 macro_rules! m { ($($tt:tt)*) => { $($tt)* } }
1112 fn foo() {}"
1113 "#]],
1114     );
1115 }
1116
1117 #[test]
1118 fn test_tt_composite() {
1119     check(
1120         r#"
1121 macro_rules! m { ($tt:tt) => { ok!(); } }
1122 m! { => }
1123 m! { = > }
1124 "#,
1125         expect![[r#"
1126 macro_rules! m { ($tt:tt) => { ok!(); } }
1127 ok!();
1128 /* error: leftover tokens */ok!();
1129 "#]],
1130     );
1131 }
1132
1133 #[test]
1134 fn test_tt_composite2() {
1135     check(
1136         r#"
1137 macro_rules! m { ($($tt:tt)*) => { abs!(=> $($tt)*); } }
1138 m! {#}
1139 "#,
1140         expect![[r##"
1141 macro_rules! m { ($($tt:tt)*) => { abs!(=> $($tt)*); } }
1142 abs!( = > #);
1143 "##]],
1144     );
1145 }
1146
1147 #[test]
1148 fn test_tt_with_composite_without_space() {
1149     // Test macro input without any spaces
1150     // See https://github.com/rust-analyzer/rust-analyzer/issues/6692
1151     check(
1152         r#"
1153 macro_rules! m { ($ op:tt, $j:path) => ( ok!(); ) }
1154 m!(==,Foo::Bool)
1155 "#,
1156         expect![[r#"
1157 macro_rules! m { ($ op:tt, $j:path) => ( ok!(); ) }
1158 ok!();
1159 "#]],
1160     );
1161 }
1162
1163 #[test]
1164 fn test_underscore() {
1165     check(
1166         r#"
1167 macro_rules! m { ($_:tt) => { ok!(); } }
1168 m! { => }
1169 "#,
1170         expect![[r#"
1171 macro_rules! m { ($_:tt) => { ok!(); } }
1172 ok!();
1173 "#]],
1174     );
1175 }
1176
1177 #[test]
1178 fn test_underscore_not_greedily() {
1179     check(
1180         r#"
1181 // `_` overlaps with `$a:ident` but rustc matches it under the `_` token.
1182 macro_rules! m1 {
1183     ($($a:ident)* _) => { ok!(); }
1184 }
1185 m1![a b c d _];
1186
1187 // `_ => ou` overlaps with `$a:expr => $b:ident` but rustc matches it under `_ => $c:expr`.
1188 macro_rules! m2 {
1189     ($($a:expr => $b:ident)* _ => $c:expr) => { ok!(); }
1190 }
1191 m2![a => b c => d _ => ou]
1192 "#,
1193         expect![[r#"
1194 // `_` overlaps with `$a:ident` but rustc matches it under the `_` token.
1195 macro_rules! m1 {
1196     ($($a:ident)* _) => { ok!(); }
1197 }
1198 ok!();
1199
1200 // `_ => ou` overlaps with `$a:expr => $b:ident` but rustc matches it under `_ => $c:expr`.
1201 macro_rules! m2 {
1202     ($($a:expr => $b:ident)* _ => $c:expr) => { ok!(); }
1203 }
1204 ok!();
1205 "#]],
1206     );
1207 }
1208
1209 #[test]
1210 fn test_underscore_flavors() {
1211     check(
1212         r#"
1213 macro_rules! m1 { ($a:ty) => { ok!(); } }
1214 m1![_];
1215
1216 macro_rules! m2 { ($a:lifetime) => { ok!(); } }
1217 m2!['_];
1218 "#,
1219         expect![[r#"
1220 macro_rules! m1 { ($a:ty) => { ok!(); } }
1221 ok!();
1222
1223 macro_rules! m2 { ($a:lifetime) => { ok!(); } }
1224 ok!();
1225 "#]],
1226     );
1227 }
1228
1229 #[test]
1230 fn test_vertical_bar_with_pat() {
1231     check(
1232         r#"
1233 macro_rules! m { (|$pat:pat| ) => { ok!(); } }
1234 m! { |x| }
1235  "#,
1236         expect![[r#"
1237 macro_rules! m { (|$pat:pat| ) => { ok!(); } }
1238 ok!();
1239  "#]],
1240     );
1241 }
1242
1243 #[test]
1244 fn test_dollar_crate_lhs_is_not_meta() {
1245     check(
1246         r#"
1247 macro_rules! m {
1248     ($crate) => { err!(); };
1249     () => { ok!(); };
1250 }
1251 m!{}
1252 "#,
1253         expect![[r#"
1254 macro_rules! m {
1255     ($crate) => { err!(); };
1256     () => { ok!(); };
1257 }
1258 ok!();
1259 "#]],
1260     );
1261 }
1262
1263 #[test]
1264 fn test_lifetime() {
1265     check(
1266         r#"
1267 macro_rules! m {
1268     ($lt:lifetime) => { struct Ref<$lt>{ s: &$ lt str } }
1269 }
1270 m! {'a}
1271 "#,
1272         expect![[r#"
1273 macro_rules! m {
1274     ($lt:lifetime) => { struct Ref<$lt>{ s: &$ lt str } }
1275 }
1276 struct Ref<'a> {
1277     s: &'a str
1278 }
1279 "#]],
1280     );
1281 }
1282
1283 #[test]
1284 fn test_literal() {
1285     check(
1286         r#"
1287 macro_rules! m {
1288     ($type:ty, $lit:literal) => { const VALUE: $type = $ lit; };
1289 }
1290 m!(u8, 0);
1291 "#,
1292         expect![[r#"
1293 macro_rules! m {
1294     ($type:ty, $lit:literal) => { const VALUE: $type = $ lit; };
1295 }
1296 const VALUE: u8 = 0;
1297 "#]],
1298     );
1299
1300     check(
1301         r#"
1302 macro_rules! m {
1303     ($type:ty, $lit:literal) => { const VALUE: $ type = $ lit; };
1304 }
1305 m!(i32, -1);
1306 "#,
1307         expect![[r#"
1308 macro_rules! m {
1309     ($type:ty, $lit:literal) => { const VALUE: $ type = $ lit; };
1310 }
1311 const VALUE: i32 = -1;
1312 "#]],
1313     );
1314 }
1315
1316 #[test]
1317 fn test_boolean_is_ident() {
1318     check(
1319         r#"
1320 macro_rules! m {
1321     ($lit0:literal, $lit1:literal) => { const VALUE: (bool, bool) = ($lit0, $lit1); };
1322 }
1323 m!(true, false);
1324 "#,
1325         expect![[r#"
1326 macro_rules! m {
1327     ($lit0:literal, $lit1:literal) => { const VALUE: (bool, bool) = ($lit0, $lit1); };
1328 }
1329 const VALUE: (bool, bool) = (true , false );
1330 "#]],
1331     );
1332 }
1333
1334 #[test]
1335 fn test_vis() {
1336     check(
1337         r#"
1338 macro_rules! m {
1339     ($vis:vis $name:ident) => { $vis fn $name() {} }
1340 }
1341 m!(pub foo);
1342 m!(foo);
1343 "#,
1344         expect![[r#"
1345 macro_rules! m {
1346     ($vis:vis $name:ident) => { $vis fn $name() {} }
1347 }
1348 pub fn foo() {}
1349 fn foo() {}
1350 "#]],
1351     );
1352 }
1353
1354 #[test]
1355 fn test_inner_macro_rules() {
1356     check(
1357         r#"
1358 macro_rules! m {
1359     ($a:ident, $b:ident, $c:tt) => {
1360         macro_rules! inner {
1361             ($bi:ident) => { fn $bi() -> u8 { $c } }
1362         }
1363
1364         inner!($a);
1365         fn $b() -> u8 { $c }
1366     }
1367 }
1368 m!(x, y, 1);
1369 "#,
1370         expect![[r#"
1371 macro_rules! m {
1372     ($a:ident, $b:ident, $c:tt) => {
1373         macro_rules! inner {
1374             ($bi:ident) => { fn $bi() -> u8 { $c } }
1375         }
1376
1377         inner!($a);
1378         fn $b() -> u8 { $c }
1379     }
1380 }
1381 macro_rules !inner {
1382     ($bi: ident) = > {
1383         fn $bi()-> u8 {
1384             1
1385         }
1386     }
1387 }
1388 inner!(x);
1389 fn y() -> u8 {
1390     1
1391 }
1392 "#]],
1393     );
1394 }
1395
1396 #[test]
1397 fn test_expr_after_path_colons() {
1398     check(
1399         r#"
1400 macro_rules! m {
1401     ($k:expr) => { fn f() { K::$k; } }
1402 }
1403 // +tree +errors
1404 m!(C("0"));
1405 "#,
1406         expect![[r#"
1407 macro_rules! m {
1408     ($k:expr) => { fn f() { K::$k; } }
1409 }
1410 /* parse error: expected identifier */
1411 /* parse error: expected SEMICOLON */
1412 /* parse error: expected SEMICOLON */
1413 /* parse error: expected expression */
1414 fn f() {
1415     K::(C("0"));
1416 }
1417 // MACRO_ITEMS@0..19
1418 //   FN@0..19
1419 //     FN_KW@0..2 "fn"
1420 //     NAME@2..3
1421 //       IDENT@2..3 "f"
1422 //     PARAM_LIST@3..5
1423 //       L_PAREN@3..4 "("
1424 //       R_PAREN@4..5 ")"
1425 //     BLOCK_EXPR@5..19
1426 //       STMT_LIST@5..19
1427 //         L_CURLY@5..6 "{"
1428 //         EXPR_STMT@6..10
1429 //           PATH_EXPR@6..10
1430 //             PATH@6..10
1431 //               PATH@6..7
1432 //                 PATH_SEGMENT@6..7
1433 //                   NAME_REF@6..7
1434 //                     IDENT@6..7 "K"
1435 //               COLON2@7..9 "::"
1436 //               ERROR@9..10
1437 //                 L_PAREN@9..10 "("
1438 //         EXPR_STMT@10..16
1439 //           CALL_EXPR@10..16
1440 //             PATH_EXPR@10..11
1441 //               PATH@10..11
1442 //                 PATH_SEGMENT@10..11
1443 //                   NAME_REF@10..11
1444 //                     IDENT@10..11 "C"
1445 //             ARG_LIST@11..16
1446 //               L_PAREN@11..12 "("
1447 //               LITERAL@12..15
1448 //                 STRING@12..15 "\"0\""
1449 //               R_PAREN@15..16 ")"
1450 //         ERROR@16..17
1451 //           R_PAREN@16..17 ")"
1452 //         SEMICOLON@17..18 ";"
1453 //         R_CURLY@18..19 "}"
1454
1455 "#]],
1456     );
1457 }
1458
1459 #[test]
1460 fn test_match_is_not_greedy() {
1461     check(
1462         r#"
1463 macro_rules! foo {
1464     ($($i:ident $(,)*),*) => {};
1465 }
1466 foo!(a,b);
1467 "#,
1468         expect![[r#"
1469 macro_rules! foo {
1470     ($($i:ident $(,)*),*) => {};
1471 }
1472
1473 "#]],
1474     );
1475 }
1476
1477 #[test]
1478 fn expr_interpolation() {
1479     check(
1480         r#"
1481 macro_rules! m { ($expr:expr) => { map($expr) } }
1482 fn f() {
1483     let _ = m!(x + foo);
1484 }
1485 "#,
1486         expect![[r#"
1487 macro_rules! m { ($expr:expr) => { map($expr) } }
1488 fn f() {
1489     let _ = map((x+foo));
1490 }
1491 "#]],
1492     )
1493 }
1494
1495 #[test]
1496 fn mbe_are_not_attributes() {
1497     check(
1498         r#"
1499 macro_rules! error {
1500     () => {struct Bar}
1501 }
1502
1503 #[error]
1504 struct Foo;
1505 "#,
1506         expect![[r##"
1507 macro_rules! error {
1508     () => {struct Bar}
1509 }
1510
1511 #[error]
1512 struct Foo;
1513 "##]],
1514     )
1515 }