| //@ check-pass |
| // |
| // During development of #124141 at one point expression on attributes were |
| // being duplicated and `m1` caused an exponential blowup that caused OOM. |
| // The number of recursive calls depends on the number of doc comments on the |
| // expr block. On each recursive call, the `#[allow(deprecated)]` attribute(s) on |
| // the `0` somehow get duplicated, resulting in 1, 2, 4, 8, ... identical |
| // attributes. |
| // |
| // After the fix, the code compiles quickly and normally. |
| |
| macro_rules! m1 { |
| ($(#[$meta:meta])* { $e:expr }) => { |
| m1! { expr: { $e }, unprocessed: [$(#[$meta])*] } |
| }; |
| |
| (expr: { $e:expr }, unprocessed: [ #[$meta:meta] $($metas:tt)* ]) => { |
| m1! { expr: { $e }, unprocessed: [ $($metas)* ] } |
| }; |
| |
| (expr: { $e:expr }, unprocessed: []) => { |
| { $e } |
| } |
| } |
| |
| macro_rules! m2 { |
| ($(#[$meta:meta])* { $e:stmt }) => { |
| m2! { stmt: { $e }, unprocessed: [$(#[$meta])*] } |
| }; |
| |
| (stmt: { $e:stmt }, unprocessed: [ #[$meta:meta] $($metas:tt)* ]) => { |
| m2! { stmt: { $e }, unprocessed: [ $($metas)* ] } |
| }; |
| |
| (stmt: { $e:stmt }, unprocessed: []) => { |
| { $e } |
| } |
| } |
| |
| macro_rules! m3 { |
| ($(#[$meta:meta])* { $e:item }) => { |
| m3! { item: { $e }, unprocessed: [$(#[$meta])*] } |
| }; |
| |
| (item: { $e:item }, unprocessed: [ #[$meta:meta] $($metas:tt)* ]) => { |
| m3! { item: { $e }, unprocessed: [ $($metas)* ] } |
| }; |
| |
| (item: { $e:item }, unprocessed: []) => { |
| { $e } |
| } |
| } |
| |
| fn main() { |
| // Each additional doc comment line doubles the compile time. |
| m1!( |
| /// a1 |
| /// a2 |
| /// a3 |
| /// a4 |
| /// a5 |
| /// a6 |
| /// a7 |
| /// a8 |
| /// a9 |
| /// a10 |
| /// a11 |
| /// a12 |
| /// a13 |
| /// a14 |
| /// a15 |
| /// a16 |
| /// a17 |
| /// a18 |
| /// a19 |
| /// a20 |
| { |
| #[allow(deprecated)] 0 |
| } |
| ); |
| |
| m2!( |
| /// a1 |
| /// a2 |
| /// a3 |
| /// a4 |
| /// a5 |
| /// a6 |
| /// a7 |
| /// a8 |
| /// a9 |
| /// a10 |
| /// a11 |
| /// a12 |
| /// a13 |
| /// a14 |
| /// a15 |
| /// a16 |
| /// a17 |
| /// a18 |
| /// a19 |
| /// a20 |
| { |
| #[allow(deprecated)] let x = 5 |
| } |
| ); |
| |
| m3!( |
| /// a1 |
| /// a2 |
| /// a3 |
| /// a4 |
| /// a5 |
| /// a6 |
| /// a7 |
| /// a8 |
| /// a9 |
| /// a10 |
| /// a11 |
| /// a12 |
| /// a13 |
| /// a14 |
| /// a15 |
| /// a16 |
| /// a17 |
| /// a18 |
| /// a19 |
| /// a20 |
| { |
| #[allow(deprecated)] struct S; |
| } |
| ); |
| } |