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