fast image operations
ofshex dumpascii
0000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 01 0c 00 00 00 b2 08 02 00 00 00 38 59 66 .PNG........IHDR.............8Yf
0020 75 00 00 00 20 63 48 52 4d 00 00 7a 26 00 00 80 84 00 00 fa 00 00 00 80 e8 00 00 75 30 00 00 ea u....cHRM..z&..............u0...
0040 60 00 00 3a 98 00 00 17 70 9c ba 51 3c 00 00 00 04 67 41 4d 41 00 00 b1 8e 7c fb 51 93 00 01 24 `..:....p..Q<....gAMA....|.Q...$
0060 ed 49 44 41 54 78 da 6c 59 d9 92 ec 38 6e c5 46 52 59 f7 ce f4 f8 c1 0f b6 ff ff ef fa b1 bb 2a .IDATx.lY...8n.FRY.............*
0080 53 c4 62 12 88 54 29 6a e6 84 82 09 41 e2 02 10 1b 95 f8 8f a3 01 80 47 ac 16 21 1a f1 22 82 d0 S.b..T)j....A..........G..!.."..
00a0 cc cd 9d 88 dc 1d a0 40 88 18 61 90 58 34 bc 11 11 17 41 44 75 bb 08 fc 7e 2d 16 41 b1 6f eb 05 .......@..a.X4....ADu...~-.A.o..
00c0 0f 45 60 33 03 66 77 af 2e 11 f9 5a b6 3f 67 b9 6e 3d 16 61 e1 44 b4 88 6b 85 98 83 ef 71 08 21 .E`3.fw....Z.?g.n=.a.D..k....q.!
00e0 c1 04 22 32 9a 48 a3 47 ef c2 c8 8b 26 46 44 b3 e9 ee a3 f1 74 63 6a ea 96 cc 20 40 77 6d 6d 3c .."2.H.G....&FD.....tcj....@wmm<
0100 cf 17 f3 a2 81 20 44 24 57 88 81 60 66 ae c6 4d 52 0f 14 09 4c 84 a3 a3 53 09 8e f8 f5 9a a3 6d ......D$W..`f..MR...L...S......m
0120 01 eb 91 f9 64 66 d3 90 46 98 00 00 11 99 33 f9 66 44 64 1a 98 30 88 05 55 25 02 22 49 01 31 5b ....df..F.....3.fDd..0..U%."I.1[
0140 f0 88 d7 d4 53 17 01 af d7 cb 91 cc cc dd 6b 40 22 e8 2c 8b 68 c2 0b a3 71 2e 2f 44 08 7c b5 92 ....S.........k@".,.h...q./D.|..
0160 62 5a ad 50 d5 d5 8d 00 4b 57 ee 5e ea 2e 95 7a ca a5 be 07 98 96 3a f7 cd 69 82 47 97 30 ed bd bZ.P....KW.^...z......:..i.G.0..
0180 73 eb 8f c7 63 6b 16 71 da 7e b5 36 65 ce b9 5b b7 31 86 1b 8c a3 e9 eb a9 aa ff fd af df eb fd s...ck.q.~.6e..[.1..............
01a0 30 97 ce 08 d0 9a 1c 5d 46 eb c8 84 ad c3 e2 b0 90 b0 88 a0 9d dc b9 35 fe 9f ff fb df 7f fd f3 0......]F..............5........
01c0 8f 3f ff fc b3 f7 3e c6 d0 f3 74 35 8f f9 fc fc bb f7 03 90 db ee 18 24 42 d2 41 27 11 2a 06 82 .?....>...t5...........$B.A'.*..
01e0 b4 d6 ce e7 27 01 2e 22 f5 03 0a 10 d0 17 1d ae 8d 83 16 a4 93 b0 1b a4 aa 29 08 c9 2d 6d fc 4c ....'..".................)..-m.L
0200 15 b1 bb af ee 02 09 84 32 5f 76 08 06 34 f7 78 2b eb 87 27 5c 70 f7 1f a6 7c e9 88 2f bb 47 0c ........2_v..4.x+..'\p...|../.G.
0220 f7 cd 4c 6c 02 dd 43 09 05 83 cb 90 2f 3b 73 f7 b7 83 dd 47 4b d3 4f 60 11 10 c5 ac db ef 15 12 ..Ll..C...../;s....GK.O`........
0240 86 87 43 d4 ae e3 46 ce b0 00 d1 1b f7 2e 25 07 81 b5 2e 73 9e 8b 16 24 a6 2d 4c 6f dd 39 9d 93 ..C...F.......%....s...$.-Lo.9..
0260 db e7 e7 e7 ef a3 47 84 88 3c e7 49 48 42 30 2d 00 7d f4 66 46 69 f7 9c 02 fa 6a 19 30 08 21 c8 ......G..<.IHB0-.}.fFi....j.0.!.
0280 1d df 8a 8a c7 40 04 ef 4d 10 38 99 02 e8 a6 c1 cc e6 13 11 04 05 99 30 18 f7 38 40 cc 88 1a e1 .....@..M.8............0..8@....
02a0 cc 2c 80 af e9 1f 47 77 b5 3d 4a 3a b6 12 12 91 99 c1 86 3e 4f 17 91 d3 f4 da 05 da 80 88 3d 45 .,....Gw.=J:.......>O.........=E
02c0 69 72 9a 6d d1 ba 10 ad 2b 9a c8 9e 77 0b 8c 66 96 8e b1 45 79 ef 21 32 73 6d 84 08 d7 46 20 e3 ir.m....+...w..f...Ey.!2sm...F..
02e0 79 9e 66 4a 24 08 81 5b 90 14 9f 18 59 d2 d3 94 19 4d e3 ee f0 8b 5e bd 86 34 0a e8 c7 11 f6 52 y.fJ$..[....Y....M....^..4.....R
0300 75 11 51 07 9b be 27 49 fb a9 49 4f 9d 83 87 4d e5 26 5f af cf 23 1e a3 c9 a9 67 6b 0f e6 f6 71 u.Q...'I..IO...M.&_..#....gk...q
0320 3c 3e 5f 9f b9 18 3a e7 4b cf 09 00 e7 d7 df 8f 8f 41 d8 02 81 32 a0 a7 e8 ee 84 0e d1 b9 59 60 <>_...:.K........A...2........Y`
0340 84 45 38 4b f7 d8 52 a8 9a 03 58 7a 50 5a 18 4f f3 a3 bd 43 06 c5 02 7a 1a 9b e9 65 c6 b1 61 02 .E8K..R...XzPZ.O...C...z...e..a.
0360 89 9b c1 85 03 10 71 b8 5d a1 1d 36 28 7f fd ee 15 97 65 5f 5e f4 c3 70 2f 60 a2 4c 94 10 03 ac ......q.]..6(.....e_^..p/`.L....
0380 78 51 be 74 ad a1 a6 8b b8 52 48 05 d4 9a e2 9e a3 ea 51 bd ff dd 97 90 00 c3 1c 99 dc 9d 89 18 xQ.t.....RH.......Q.............
03a0 21 c0 98 1b 63 80 eb 18 9d 88 21 dd ac b5 8f dc 72 5b 68 c7 41 04 25 4e 04 fc eb f7 6f 22 30 db !...c.....!.....r[h.A.%N....o"0.
03c0 82 fc f3 e3 63 33 01 47 b8 ab 01 13 b0 30 93 aa 66 2c 6c 9f 7f 7f ad 96 db 36 0b 91 0e 00 66 16 ....c3.G.....0..f,l......6....f.
03e0 e1 44 5d d5 72 cd e5 cf 8a 28 d8 16 49 ee 8c 58 e2 40 97 6e 66 bd 04 ae 38 87 6c 66 8f 96 46 28 .D].r....(..I..X.@.nf...8.lf..F(
0400 e8 0e ea 4e 84 8b e1 6a 5b 24 e0 08 b4 50 ca 15 9e a0 d7 8e a4 81 36 c0 6f cd f4 9e 41 db 8d 32 ...N...j[$...P........6.o...A..2
0420 72 31 93 88 a0 87 99 02 04 13 10 4b 94 af 84 a7 8b 0a 05 22 20 20 9e a6 11 50 d1 8a b3 7b 4e 14 r1.........K.......".....P...{N.
0440 35 72 4d c1 09 33 5d 00 26 83 a8 47 a9 28 62 6a f3 f5 3a 8e 6e f6 95 2a b5 7a 9a a6 89 ee fe 9a 5rM..3].&..G.(bj..:.n..*.z......
0460 26 22 0e 44 c2 99 5a 7b 6b 2d 90 7a 3f 34 60 90 30 0f 57 1b ad 8d 31 9e cf cf de fb 9c 33 dd 41 &".D..Z{k-.z?4`.0.W...1......3.A
0480 b6 b0 6d 84 6b eb 1f 08 28 c2 95 54 c3 91 98 22 90 f7 8c 3a 1e 4d d5 73 49 c2 91 ab 0f 7e e9 39 ..m.k...(..T..."...:.M.sI....~.9
04a0 c6 c8 70 40 9a 46 88 19 12 00 54 44 6c ce dc 1d cb 2c a4 54 e6 55 46 5a b8 6c b1 78 6f 22 8a b8 ..p@.F....TDl....,.T.UFZ.l.xo"..
04c0 d7 45 57 32 a9 96 88 ee 29 e5 ce ac 59 0c a2 50 7c 83 78 cf 88 ff 29 41 61 bd 29 22 f7 55 61 e2 .EW2....)...Y..P|.x...)Aa.)".Ua.
04e0 a2 0b 77 6f 41 fe f6 28 07 8c 8a ac 10 a3 b7 d1 7b 23 38 9a 74 a6 7d 09 0b f1 af 5f bf 8e 3e 30 ..woA..(........{#8.t.}...._..>0
0500 b6 c5 8f d6 17 b3 31 2d e2 18 cc 8c 22 84 09 11 d9 2f f4 c5 ef 94 93 ec ee 42 e3 90 de 04 c2 c7 ......1-...."..../.......B......
0520 fa 61 72 3b 09 fd 68 9d 01 9b f0 58 dc 46 c7 90 26 b4 2e 61 5e b4 08 1f c7 01 00 a3 73 cf a7 44 .ar;..h....X.F..&..a^.......s..D
0540 c8 bc 9a 6d d3 42 30 1a 1f 5d 28 62 df 0a 2d 92 05 09 43 88 46 93 21 cd 5d f9 1d a1 30 f1 ad 99 ...m.B0..](b..-...C.F.!.]...0...
0560 04 be a1 7a 32 33 24 ea 5d 30 af 90 cf271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171
//! Real world regressions and issues, not particularly minimized.
//!
//! While it's OK to just dump large macros here, it's preferable to come up
//! with a minimal example for the program and put a specific test to the parent
//! directory.

use expect_test::expect;

use crate::macro_expansion_tests::check;

#[test]
fn test_vec() {
    check(
        r#"
macro_rules! vec {
    () => (
        $crate::__rust_force_expr!($crate::vec::Vec::new())
    );
    ($elem:expr; $n:expr) => (
        $crate::__rust_force_expr!($crate::vec::from_elem($elem, $n))
    );
    ($($x:expr),+ $(,)?) => (
        $crate::__rust_force_expr!(<[_]>::into_vec(
            // This rustc_box is not required, but it produces a dramatic improvement in compile
            // time when constructing arrays with many elements.
            #[rustc_box]
            $crate::boxed::Box::new([$($x),+])
        ))
    );
}

macro_rules! __rust_force_expr {
    ($e:expr) => {
        $e
    };
}

fn main() {
    vec!();
    vec![1u32,2];
    vec![a.];
}
"#,
        expect![[r#"
macro_rules! vec {
    () => (
        $crate::__rust_force_expr!($crate::vec::Vec::new())
    );
    ($elem:expr; $n:expr) => (
        $crate::__rust_force_expr!($crate::vec::from_elem($elem, $n))
    );
    ($($x:expr),+ $(,)?) => (
        $crate::__rust_force_expr!(<[_]>::into_vec(
            // This rustc_box is not required, but it produces a dramatic improvement in compile
            // time when constructing arrays with many elements.
            #[rustc_box]
            $crate::boxed::Box::new([$($x),+])
        ))
    );
}

macro_rules! __rust_force_expr {
    ($e:expr) => {
        $e
    };
}

fn main() {
    $crate::__rust_force_expr!($crate:: vec:: Vec:: new());
    $crate::__rust_force_expr!(<[_]>:: into_vec(#[rustc_box]$crate:: boxed:: Box:: new([1u32, 2])));
    /* error: expected Expr */$crate::__rust_force_expr!($crate:: vec:: from_elem((a.), $n));
}
"#]],
    );
    // FIXME we should have testing infra for multi level expansion tests
    check(
        r#"
macro_rules! __rust_force_expr {
    ($e:expr) => {
        $e
    };
}

fn main() {
    __rust_force_expr!(crate:: vec:: Vec:: new());
    __rust_force_expr!(<[_]>:: into_vec(#[rustc_box] crate:: boxed:: Box:: new([1u32, 2])));
    __rust_force_expr/*+errors*/!(crate:: vec:: from_elem((a.), $n));
}
"#,
        expect![[r#"
macro_rules! __rust_force_expr {
    ($e:expr) => {
        $e
    };
}

fn main() {
    (crate ::vec::Vec::new());
    (<[_]>::into_vec(#[rustc_box] crate ::boxed::Box::new([1u32, 2])));
    /* error: expected Expr *//* parse error: expected field name or number */
/* parse error: expected expression */
/* parse error: expected R_PAREN */
/* parse error: expected COMMA */
/* parse error: expected expression, item or let statement */
(crate ::vec::from_elem((a.), $n));
}
"#]],
    );
}

#[test]
fn test_winapi_struct() {
    // from https://github.com/retep998/winapi-rs/blob/a7ef2bca086aae76cf6c4ce4c2552988ed9798ad/src/macros.rs#L366

    check(
        r#"
macro_rules! STRUCT {
    ($(#[$attrs:meta])* struct $name:ident {
        $($field:ident: $ftype:ty,)+
    }) => (
        #[repr(C)] #[derive(Copy)] $(#[$attrs])*
        pub struct $name {
            $(pub $field: $ftype,)+
        }
        impl Clone for $name {
            #[inline]
            fn clone(&self) -> $name { *self }
        }
        #[cfg(feature = "impl-default")]
        impl Default for $name {
            #[inline]
            fn default() -> $name { unsafe { $crate::_core::mem::zeroed() } }
        }
    );
}

// from https://github.com/retep998/winapi-rs/blob/a7ef2bca086aae76cf6c4ce4c2552988ed9798ad/src/shared/d3d9caps.rs
STRUCT!{struct D3DVSHADERCAPS2_0 {Caps: u8,}}

STRUCT!{#[cfg_attr(target_arch = "x86", repr(packed))] struct D3DCONTENTPROTECTIONCAPS {Caps : u8 ,}}
"#,
        expect![[r#"
macro_rules! STRUCT {
    ($(#[$attrs:meta])* struct $name:ident {
        $($field:ident: $ftype:ty,)+
    }) => (
        #[repr(C)] #[derive(Copy)] $(#[$attrs])*
        pub struct $name {
            $(pub $field: $ftype,)+
        }
        impl Clone for $name {
            #[inline]
            fn clone(&self) -> $name { *self }
        }
        #[cfg(feature = "impl-default")]
        impl Default for $name {
            #[inline]
            fn default() -> $name { unsafe { $crate::_core::mem::zeroed() } }
        }
    );
}

#[repr(C)]
#[derive(Copy)] pub struct D3DVSHADERCAPS2_0 {
    pub Caps: u8,
}
impl Clone for D3DVSHADERCAPS2_0 {
    #[inline] fn clone(&self ) -> D3DVSHADERCAPS2_0 {
        *self
    }
}
#[cfg(feature = "impl-default")] impl Default for D3DVSHADERCAPS2_0 {
    #[inline] fn default() -> D3DVSHADERCAPS2_0 {
        unsafe {
            $crate::_core::mem::zeroed()
        }
    }
}

#[repr(C)]
#[derive(Copy)]
#[cfg_attr(target_arch = "x86", repr(packed))] pub struct D3DCONTENTPROTECTIONCAPS {
    pub Caps: u8,
}
impl Clone for D3DCONTENTPROTECTIONCAPS {
    #[inline] fn clone(&self ) -> D3DCONTENTPROTECTIONCAPS {
        *self
    }
}
#[cfg(feature = "impl-default")] impl Default for D3DCONTENTPROTECTIONCAPS {
    #[inline] fn default() -> D3DCONTENTPROTECTIONCAPS {
        unsafe {
            $crate::_core::mem::zeroed()
        }
    }
}
"#]],
    );
}

#[test]
fn test_int_base() {
    check(
        r#"
macro_rules! int_base {
    ($Trait:ident for $T:ident as $U:ident -> $Radix:ident) => {
        #[stable(feature = "rust1", since = "1.0.0")]
        impl fmt::$Trait for $T {
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                $Radix.fmt_int(*self as $U, f)
            }
        }
    }
}
int_base!{Binary for isize as usize -> Binary}
"#,
        expect![[r#"
macro_rules! int_base {
    ($Trait:ident for $T:ident as $U:ident -> $Radix:ident) => {
        #[stable(feature = "rust1", since = "1.0.0")]
        impl fmt::$Trait for $T {
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                $Radix.fmt_int(*self as $U, f)
            }
        }
    }
}
#[stable(feature = "rust1", since = "1.0.0")] impl fmt::Binary for isize {
    fn fmt(&self , f: &mut fmt::Formatter<'_>) -> fmt::Result {
        Binary.fmt_int(*self as usize, f)
    }
}
"#]],
    );
}

#[test]
fn test_generate_pattern_iterators() {
    // From <https://github.com/rust-lang/rust/blob/316a391dcb7d66dc25f1f9a4ec9d368ef7615005/src/libcore/str/mod.rs>.
    check(
        r#"
macro_rules! generate_pattern_iterators {
    { double ended; with $(#[$common_stability_attribute:meta])*,
                        $forward_iterator:ident,
                        $reverse_iterator:ident, $iterty:ty
    } => { ok!(); }
}
generate_pattern_iterators ! ( double ended ; with # [ stable ( feature = "rust1" , since = "1.0.0" ) ] , Split , RSplit , & 'a str );
"#,
        expect![[r##"
macro_rules! generate_pattern_iterators {
    { double ended; with $(#[$common_stability_attribute:meta])*,
                        $forward_iterator:ident,
                        $reverse_iterator:ident, $iterty:ty
    } => { ok!(); }
}
ok!();
"##]],
    );
}

#[test]
fn test_impl_fn_for_zst() {
    // From <https://github.com/rust-lang/rust/blob/5d20ff4d2718c820632b38c1e49d4de648a9810b/src/libcore/internal_macros.rs>.
    check(
        r#"
macro_rules! impl_fn_for_zst  {
    {$( $( #[$attr: meta] )*
    struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )? Fn =
        |$( $arg: ident: $ArgTy: ty ),*| -> $ReturnTy: ty $body: block;
    )+} => {$(
        $( #[$attr] )*
        struct $Name;

        impl $( <$( $lifetime ),+> )? Fn<($( $ArgTy, )*)> for $Name {
            #[inline]
            extern "rust-call" fn call(&self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
                $body
            }
        }

        impl $( <$( $lifetime ),+> )? FnMut<($( $ArgTy, )*)> for $Name {
            #[inline]
            extern "rust-call" fn call_mut(
                &mut self,
                ($( $arg, )*): ($( $ArgTy, )*)
            ) -> $ReturnTy {
                Fn::call(&*self, ($( $arg, )*))
            }
        }

        impl $( <$( $lifetime ),+> )? FnOnce<($( $ArgTy, )*)> for $Name {
            type Output = $ReturnTy;

            #[inline]
            extern "rust-call" fn call_once(self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
                Fn::call(&self, ($( $arg, )*))
            }
        }
    )+}
}

impl_fn_for_zst !   {
    #[derive(Clone)]
    struct CharEscapeDebugContinue impl Fn = |c: char| -> char::EscapeDebug {
        c.escape_debug_ext(false)
    };

    #[derive(Clone)]
    struct CharEscapeUnicode impl Fn = |c: char| -> char::EscapeUnicode {
        c.escape_unicode()
    };

    #[derive(Clone)]
    struct CharEscapeDefault impl Fn = |c: char| -> char::EscapeDefault {
        c.escape_default()
    };
}

"#,
        expect![[r#"
macro_rules! impl_fn_for_zst  {
    {$( $( #[$attr: meta] )*
    struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )? Fn =
        |$( $arg: ident: $ArgTy: ty ),*| -> $ReturnTy: ty $body: block;
    )+} => {$(
        $( #[$attr] )*
        struct $Name;

        impl $( <$( $lifetime ),+> )? Fn<($( $ArgTy, )*)> for $Name {
            #[inline]
            extern "rust-call" fn call(&self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
                $body
            }
        }

        impl $( <$( $lifetime ),+> )? FnMut<($( $ArgTy, )*)> for $Name {
            #[inline]
            extern "rust-call" fn call_mut(
                &mut self,
                ($( $arg, )*): ($( $ArgTy, )*)
            ) -> $ReturnTy {
                Fn::call(&*self, ($( $arg, )*))
            }
        }

        impl $( <$( $lifetime ),+> )? FnOnce<($( $ArgTy, )*)> for $Name {
            type Output = $ReturnTy;

            #[inline]
            extern "rust-call" fn call_once(self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
                Fn::call(&self, ($( $arg, )*))
            }
        }
    )+}
}

#[derive(Clone)] struct CharEscapeDebugContinue;
impl Fn<(char, )> for CharEscapeDebugContinue {
    #[inline] extern "rust-call" fn call(&self , (c, ): (char, )) -> char::EscapeDebug { {
            c.escape_debug_ext(false )
        }
    }
}
impl FnMut<(char, )> for CharEscapeDebugContinue {
    #[inline] extern "rust-call" fn call_mut(&mut self , (c, ): (char, )) -> char::EscapeDebug {
        Fn::call(&*self , (c, ))
    }
}
impl FnOnce<(char, )> for CharEscapeDebugContinue {
    type Output = char::EscapeDebug;
    #[inline] extern "rust-call" fn call_once(self , (c, ): (char, )) -> char::EscapeDebug {
        Fn::call(&self , (c, ))
    }
}
#[derive(Clone)] struct CharEscapeUnicode;
impl Fn<(char, )> for CharEscapeUnicode {
    #[inline] extern "rust-call" fn call(&self , (c, ): (char, )) -> char::EscapeUnicode { {
            c.escape_unicode()
        }
    }
}
impl FnMut<(char, )> for CharEscapeUnicode {
    #[inline] extern "rust-call" fn call_mut(&mut self , (c, ): (char, )) -> char::EscapeUnicode {
        Fn::call(&*self , (c, ))
    }
}
impl FnOnce<(char, )> for CharEscapeUnicode {
    type Output = char::EscapeUnicode;
    #[inline] extern "rust-call" fn call_once(self , (c, ): (char, )) -> char::EscapeUnicode {
        Fn::call(&self , (c, ))
    }
}
#[derive(Clone)] struct CharEscapeDefault;
impl Fn<(char, )> for CharEscapeDefault {
    #[inline] extern "rust-call" fn call(&self , (c, ): (char, )) -> char::EscapeDefault { {
            c.escape_default()
        }
    }
}
impl FnMut<(char, )> for CharEscapeDefault {
    #[inline] extern "rust-call" fn call_mut(&mut self , (c, ): (char, )) -> char::EscapeDefault {
        Fn::call(&*self , (c, ))
    }
}
impl FnOnce<(char, )> for CharEscapeDefault {
    type Output = char::EscapeDefault;
    #[inline] extern "rust-call" fn call_once(self , (c, ): (char, )) -> char::EscapeDefault {
        Fn::call(&self , (c, ))
    }
}

"#]],
    );
}

#[test]
fn test_impl_nonzero_fmt() {
    // From <https://github.com/rust-lang/rust/blob/316a391dcb7d66dc25f1f9a4ec9d368ef7615005/src/libcore/num/mod.rs#L12>.
    check(
        r#"
macro_rules! impl_nonzero_fmt {
    ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => { ok!(); }
}
impl_nonzero_fmt! {
    #[stable(feature= "nonzero",since="1.28.0")]
    (Debug, Display, Binary, Octal, LowerHex, UpperHex) for NonZeroU8
}
"#,
        expect![[r##"
macro_rules! impl_nonzero_fmt {
    ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => { ok!(); }
}
ok!();
"##]],
    );
}

#[test]
fn test_cfg_if_items() {
    // From <https://github.com/rust-lang/rust/blob/33fe1131cadba69d317156847be9a402b89f11bb/src/libstd/macros.rs#L986>.
    check(
        r#"
macro_rules! __cfg_if_items {
    (($($not:meta,)*) ; ) => {};
    (($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => {
            __cfg_if_items! { ($($not,)* $($m,)*) ; $($rest)* }
    }
}
__cfg_if_items! {
    (rustdoc,);
    ( () (
           #[ cfg(any(target_os = "redox", unix))]
           #[ stable(feature = "rust1", since = "1.0.0")]
           pub use sys::ext as unix;

           #[cfg(windows)]
           #[stable(feature = "rust1", since = "1.0.0")]
           pub use sys::ext as windows;

           #[cfg(any(target_os = "linux", target_os = "l4re"))]
           pub mod linux;
    )),
}
"#,
        expect![[r#"
macro_rules! __cfg_if_items {
    (($($not:meta,)*) ; ) => {};
    (($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => {
            __cfg_if_items! { ($($not,)* $($m,)*) ; $($rest)* }
    }
}
__cfg_if_items! {
    (rustdoc, );
}
"#]],
    );
}

#[test]
fn test_cfg_if_main() {
    // From <https://github.com/rust-lang/rust/blob/3d211248393686e0f73851fc7548f6605220fbe1/src/libpanic_unwind/macros.rs#L9>.
    check(
        r#"
macro_rules! cfg_if {
    ($(if #[cfg($($meta:meta),*)] { $($it:item)* } )else* else { $($it2:item)* })
    => {
        __cfg_if_items! {
            () ;
            $( ( ($($meta),*) ($($it)*) ), )*
            ( () ($($it2)*) ),
        }
    };

    // Internal macro to Apply a cfg attribute to a list of items
    (@__apply $m:meta, $($it:item)*) => { $(#[$m] $it)* };
}

cfg_if! {
    if #[cfg(target_env = "msvc")] {
        // no extra unwinder support needed
    } else if #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] {
        // no unwinder on the system!
    } else {
        mod libunwind;
        pub use libunwind::*;
    }
}

cfg_if! {
    @__apply cfg(all(not(any(not(any(target_os = "solaris", target_os = "illumos")))))),
}
"#,
        expect![[r#"
macro_rules! cfg_if {
    ($(if #[cfg($($meta:meta),*)] { $($it:item)* } )else* else { $($it2:item)* })
    => {
        __cfg_if_items! {
            () ;
            $( ( ($($meta),*) ($($it)*) ), )*
            ( () ($($it2)*) ),
        }
    };

    // Internal macro to Apply a cfg attribute to a list of items
    (@__apply $m:meta, $($it:item)*) => { $(#[$m] $it)* };
}

__cfg_if_items! {
    ();
    ((target_env = "msvc")()), ((all(target_arch = "wasm32", not(target_os = "emscripten")))()), (()(mod libunwind;
    pub use libunwind::*;
    )),
}


"#]],
    );
}

#[test]
fn test_proptest_arbitrary() {
    // From <https://github.com/AltSysrq/proptest/blob/d1c4b049337d2f75dd6f49a095115f7c532e5129/proptest/src/arbitrary/macros.rs#L16>.
    check(
        r#"
macro_rules! arbitrary {
    ([$($bounds : tt)*] $typ: ty, $strategy: ty, $params: ty;
        $args: ident => $logic: expr) => {
        impl<$($bounds)*> $crate::arbitrary::Arbitrary for $typ {
            type Parameters = $params;
            type Strategy = $strategy;
            fn arbitrary_with($args: Self::Parameters) -> Self::Strategy {
                $logic
            }
        }
    };
}

arbitrary!(
    [A:Arbitrary]
    Vec<A> ,
    VecStrategy<A::Strategy>,
    RangedParams1<A::Parameters>;
    args =>   {
        let product_unpack![range, a] = args;
        vec(any_with::<A>(a), range)
    }
);
"#,
        expect![[r#"
macro_rules! arbitrary {
    ([$($bounds : tt)*] $typ: ty, $strategy: ty, $params: ty;
        $args: ident => $logic: expr) => {
        impl<$($bounds)*> $crate::arbitrary::Arbitrary for $typ {
            type Parameters = $params;
            type Strategy = $strategy;
            fn arbitrary_with($args: Self::Parameters) -> Self::Strategy {
                $logic
            }
        }
    };
}

impl <A: Arbitrary> $crate::arbitrary::Arbitrary for Vec<A> {
    type Parameters = RangedParams1<A::Parameters> ;
    type Strategy = VecStrategy<A::Strategy> ;
    fn arbitrary_with(args: Self::Parameters) -> Self::Strategy { {
            let product_unpack![range, a] = args;
            vec(any_with::<A>(a), range)
        }
    }
}
"#]],
    );
}

#[test]
fn test_old_ridl() {
    // This is from winapi 2.8, which do not have a link from github.
    check(
        r#"
#[macro_export]
macro_rules! RIDL {
    (interface $interface:ident ($vtbl:ident) : $pinterface:ident ($pvtbl:ident)
        {$(
            fn $method:ident(&mut self $(,$p:ident : $t:ty)*) -> $rtr:ty
        ),+}
    ) => {
        impl $interface {
            $(pub unsafe fn $method(&mut self) -> $rtr {
                ((*self.lpVtbl).$method)(self $(,$p)*)
            })+
        }
    };
}

RIDL!{interface ID3D11Asynchronous(ID3D11AsynchronousVtbl): ID3D11DeviceChild(ID3D11DeviceChildVtbl) {
    fn GetDataSize(&mut self) -> UINT
}}
"#,
        expect![[r#"
#[macro_export]
macro_rules! RIDL {
    (interface $interface:ident ($vtbl:ident) : $pinterface:ident ($pvtbl:ident)
        {$(
            fn $method:ident(&mut self $(,$p:ident : $t:ty)*) -> $rtr:ty
        ),+}
    ) => {
        impl $interface {
            $(pub unsafe fn $method(&mut self) -> $rtr {
                ((*self.lpVtbl).$method)(self $(,$p)*)
            })+
        }
    };
}

impl ID3D11Asynchronous {
    pub unsafe fn GetDataSize(&mut self ) -> UINT {
        ((*self .lpVtbl).GetDataSize)(self )
    }
}
"#]],
    );
}

#[test]
fn test_quick_error() {
    check(
        r#"
macro_rules! quick_error {
    (SORT [enum $name:ident $( #[$meta:meta] )*]
        items [$($( #[$imeta:meta] )*
                  => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
                                {$( $ifuncs:tt )*} )* ]
        buf [ ]
        queue [ ]
    ) => {
        quick_error!(ENUMINITION [enum $name $( #[$meta] )*]
            body []
            queue [$(
                $( #[$imeta] )*
                =>
                $iitem: $imode [$( $ivar: $ityp ),*]
            )*]
        );
    };
}
quick_error ! (
    SORT
    [enum Wrapped #[derive(Debug)]]
    items [
        => One: UNIT [] {}
        => Two: TUPLE [s :String] {display ("two: {}" , s) from ()} ]
    buf [ ]
    queue [ ]
);

"#,
        expect![[r#"
macro_rules! quick_error {
    (SORT [enum $name:ident $( #[$meta:meta] )*]
        items [$($( #[$imeta:meta] )*
                  => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
                                {$( $ifuncs:tt )*} )* ]
        buf [ ]
        queue [ ]
    ) => {
        quick_error!(ENUMINITION [enum $name $( #[$meta] )*]
            body []
            queue [$(
                $( #[$imeta] )*
                =>
                $iitem: $imode [$( $ivar: $ityp ),*]
            )*]
        );
    };
}
quick_error!(ENUMINITION[enum Wrapped#[derive(Debug)]]body[]queue[ = > One: UNIT[] = > Two: TUPLE[s: String]]);

"#]],
    )
}

#[test]
fn test_empty_repeat_vars_in_empty_repeat_vars() {
    check(
        r#"
macro_rules! delegate_impl {
    ([$self_type:ident, $self_wrap:ty, $self_map:ident]
     pub trait $name:ident $(: $sup:ident)* $(+ $more_sup:ident)* {

        $(
        @escape [type $assoc_name_ext:ident]
        )*
        $(
        @section type
        $(
            $(#[$_assoc_attr:meta])*
            type $assoc_name:ident $(: $assoc_bound:ty)*;
        )+
        )*
        $(
        @section self
        $(
            $(#[$_method_attr:meta])*
            fn $method_name:ident(self $(: $self_selftype:ty)* $(,$marg:ident : $marg_ty:ty)*) -> $mret:ty;
        )+
        )*
        $(
        @section nodelegate
        $($tail:tt)*
        )*
    }) => {
        impl<> $name for $self_wrap where $self_type: $name {
            $(
            $(
                fn $method_name(self $(: $self_selftype)* $(,$marg: $marg_ty)*) -> $mret {
                    $self_map!(self).$method_name($($marg),*)
                }
            )*
            )*
        }
    }
}
delegate_impl ! {
    [G, &'a mut G, deref] pub trait Data: GraphBase {@section type type NodeWeight;}
}
"#,
        expect![[r#"
macro_rules! delegate_impl {
    ([$self_type:ident, $self_wrap:ty, $self_map:ident]
     pub trait $name:ident $(: $sup:ident)* $(+ $more_sup:ident)* {

        $(
        @escape [type $assoc_name_ext:ident]
        )*
        $(
        @section type
        $(
            $(#[$_assoc_attr:meta])*
            type $assoc_name:ident $(: $assoc_bound:ty)*;
        )+
        )*
        $(
        @section self
        $(
            $(#[$_method_attr:meta])*
            fn $method_name:ident(self $(: $self_selftype:ty)* $(,$marg:ident : $marg_ty:ty)*) -> $mret:ty;
        )+
        )*
        $(
        @section nodelegate
        $($tail:tt)*
        )*
    }) => {
        impl<> $name for $self_wrap where $self_type: $name {
            $(
            $(
                fn $method_name(self $(: $self_selftype)* $(,$marg: $marg_ty)*) -> $mret {
                    $self_map!(self).$method_name($($marg),*)
                }
            )*
            )*
        }
    }
}
impl <> Data for &'a mut G where G: Data {}
"#]],
    );
}

#[test]
fn test_issue_2520() {
    check(
        r#"
macro_rules! my_macro {
    {
        ( $(
            $( [] $sname:ident : $stype:ty  )?
            $( [$expr:expr] $nname:ident : $ntype:ty  )?
        ),* )
    } => {ok!(
        Test {
            $(
                $( $sname, )?
            )*
        }
    );};
}

my_macro! {
    ([] p1: u32, [|_| S0K0] s: S0K0, [] k0: i32)
}
    "#,
        expect![[r#"
macro_rules! my_macro {
    {
        ( $(
            $( [] $sname:ident : $stype:ty  )?
            $( [$expr:expr] $nname:ident : $ntype:ty  )?
        ),* )
    } => {ok!(
        Test {
            $(
                $( $sname, )?
            )*
        }
    );};
}

ok!(Test {
    p1, k0,
}
);
    "#]],
    );
}

#[test]
fn test_repeat_bad_var() {
    // FIXME: the second rule of the macro should be removed and an error about
    // `$( $c )+` raised
    check(
        r#"
macro_rules! foo {
    ($( $b:ident )+) => { ok!($( $c )+); };
    ($( $b:ident )+) => { ok!($( $b )+); }
}

foo!(b0 b1);
"#,
        expect![[r#"
macro_rules! foo {
    ($( $b:ident )+) => { ok!($( $c )+); };
    ($( $b:ident )+) => { ok!($( $b )+); }
}

ok!(b0 b1);
"#]],
    );
}

#[test]
fn test_issue_3861() {
    // This is should (and does) produce a parse error. It used to infinite loop
    // instead.
    check(
        r#"
macro_rules! rgb_color {
    ($p:expr, $t:ty) => {
        pub fn new() {
            let _ = 0 as $t << $p;
        }
    };
}
// +tree +errors
rgb_color!(8 + 8, u32);
"#,
        expect![[r#"
macro_rules! rgb_color {
    ($p:expr, $t:ty) => {
        pub fn new() {
            let _ = 0 as $t << $p;
        }
    };
}
/* parse error: expected type */
/* parse error: expected R_PAREN */
/* parse error: expected R_ANGLE */
/* parse error: expected `::` */
/* parse error: expected COMMA */
/* parse error: expected R_ANGLE */
/* parse error: expected SEMICOLON */
/* parse error: expected expression, item or let statement */
pub fn new() {
    let _ = 0 as u32<<(8+8);
}
// MACRO_ITEMS@0..31
//   FN@0..31
//     VISIBILITY@0..3
//       PUB_KW@0..3 "pub"
//     FN_KW@3..5 "fn"
//     NAME@5..8
//       IDENT@5..8 "new"
//     PARAM_LIST@8..10
//       L_PAREN@8..9 "("
//       R_PAREN@9..10 ")"
//     BLOCK_EXPR@10..31
//       STMT_LIST@10..31
//         L_CURLY@10..11 "{"
//         LET_STMT@11..28
//           LET_KW@11..14 "let"
//           WILDCARD_PAT@14..15
//             UNDERSCORE@14..15 "_"
//           EQ@15..16 "="
//           CAST_EXPR@16..28
//             LITERAL@16..17
//               INT_NUMBER@16..17 "0"
//             AS_KW@17..19 "as"
//             PATH_TYPE@19..28
//               PATH@19..28
//                 PATH_SEGMENT@19..28
//                   NAME_REF@19..22
//                     IDENT@19..22 "u32"
//                   GENERIC_ARG_LIST@22..28
//                     L_ANGLE@22..23 "<"
//                     TYPE_ARG@23..27
//                       DYN_TRAIT_TYPE@23..27
//                         TYPE_BOUND_LIST@23..27
//                           TYPE_BOUND@23..26
//                             PATH_TYPE@23..26
//                               PATH@23..26
//                                 PATH_SEGMENT@23..26
//                                   TYPE_ANCHOR@23..26
//                                     L_ANGLE@23..24 "<"
//                                     PAREN_TYPE@24..26
//                                       L_PAREN@24..25 "("
//                                       ERROR@25..26
//                                         INT_NUMBER@25..26 "8"
//                           PLUS@26..27 "+"
//                     CONST_ARG@27..28
//                       LITERAL@27..28
//                         INT_NUMBER@27..28 "8"
//         ERROR@28..29
//           R_PAREN@28..29 ")"
//         SEMICOLON@29..30 ";"
//         R_CURLY@30..31 "}"

"#]],
    );
}

#[test]
fn test_no_space_after_semi_colon() {
    check(
        r#"
macro_rules! with_std {
    ($($i:item)*) => ($(#[cfg(feature = "std")]$i)*)
}

with_std! {mod m;mod f;}
"#,
        expect![[r#"
macro_rules! with_std {
    ($($i:item)*) => ($(#[cfg(feature = "std")]$i)*)
}

#[cfg(feature = "std")] mod m;
#[cfg(feature = "std")] mod f;
"#]],
    )
}

#[test]
fn eager_regression_15403() {
    check(
        r#"
#[rustc_builtin_macro]
#[macro_export]
macro_rules! format_args {}

fn main() {
    format_args /* +errors */ !("{}", line.1.);
}

"#,
        expect![[r##"
#[rustc_builtin_macro]
#[macro_export]
macro_rules! format_args {}

fn main() {
    /* parse error: expected field name or number */
builtin #format_args ("{}", line.1.);
}

"##]],
    );
}

#[test]
fn eager_regression_154032() {
    check(
        r#"
#[rustc_builtin_macro]
#[macro_export]
macro_rules! format_args {}

fn main() {
    format_args /* +errors */ !("{}", &[0 2]);
}

"#,
        expect![[r##"
#[rustc_builtin_macro]
#[macro_export]
macro_rules! format_args {}

fn main() {
    /* parse error: expected COMMA */
/* parse error: expected R_BRACK */
/* parse error: expected COMMA */
/* parse error: expected COMMA */
/* parse error: expected expression */
/* parse error: expected R_PAREN */
/* parse error: expected expression, item or let statement */
/* parse error: expected expression, item or let statement */
builtin #format_args ("{}", &[0 2]);
}

"##]],
    );
}

#[test]
fn eager_concat_line() {
    check(
        r#"
#[rustc_builtin_macro]
#[macro_export]
macro_rules! concat {}

#[rustc_builtin_macro]
#[macro_export]
macro_rules! line {}

fn main() {
    concat!("event ", line!());
}

"#,
        expect![[r##"
#[rustc_builtin_macro]
#[macro_export]
macro_rules! concat {}

#[rustc_builtin_macro]
#[macro_export]
macro_rules! line {}

fn main() {
    "event 0";
}

"##]],
    );
}

#[test]
fn eager_concat_bytes_panic() {
    check(
        r#"
#[rustc_builtin_macro]
#[macro_export]
macro_rules! concat_bytes {}

fn main() {
    let x = concat_bytes!(2);
}

"#,
        expect![[r#"
#[rustc_builtin_macro]
#[macro_export]
macro_rules! concat_bytes {}

fn main() {
    let x = /* error: unexpected token */b"";
}

"#]],
    );
}

#[test]
fn regression_16529() {
    check(
        r#"
mod any {
    #[macro_export]
    macro_rules! nameable {
        {
            struct $name:ident[$a:lifetime]
        } => {
            $crate::any::nameable! {
                struct $name[$a]
                a
            }
        };
        {
            struct $name:ident[$a:lifetime]
            a
        } => {};
    }
    pub use nameable;

    nameable! {
        Name['a]
    }
}
"#,
        expect![[r#"
mod any {
    #[macro_export]
    macro_rules! nameable {
        {
            struct $name:ident[$a:lifetime]
        } => {
            $crate::any::nameable! {
                struct $name[$a]
                a
            }
        };
        {
            struct $name:ident[$a:lifetime]
            a
        } => {};
    }
    pub use nameable;

    /* error: unexpected token in input */$crate::any::nameable! {
        struct $name[$a]a
    }
}
"#]],
    );
}

#[test]
fn regression_18148() {
    check(
        r#"
macro_rules! m {
    ( $e:expr ) => {};
}

fn foo() {
    m!(r#const);
}
"#,
        expect![[r#"
macro_rules! m {
    ( $e:expr ) => {};
}

fn foo() {
    ;
}
"#]],
    );
}