rust/tests/ui/attributes/dont-dup-expr-attrs.rs
Nicholas Nethercote 592d113ff2 Fix problem causing rusqlite compilation to OOM.
This makes the expression re-parsing more like how it's originally done
in `parse_nonterminal`.
2025-04-02 06:21:18 +11:00

133 lines
2.7 KiB
Rust

//@ 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;
}
);
}