Fix problem causing rusqlite
compilation to OOM.
This makes the expression re-parsing more like how it's originally done in `parse_nonterminal`.
This commit is contained in:
parent
81afdbc161
commit
592d113ff2
2 changed files with 136 additions and 1 deletions
|
@ -1397,7 +1397,9 @@ impl<'a> Parser<'a> {
|
||||||
} else if let Some(expr) = self.eat_metavar_seq_with_matcher(
|
} else if let Some(expr) = self.eat_metavar_seq_with_matcher(
|
||||||
|mv_kind| matches!(mv_kind, MetaVarKind::Expr { .. }),
|
|mv_kind| matches!(mv_kind, MetaVarKind::Expr { .. }),
|
||||||
|this| {
|
|this| {
|
||||||
let expr = this.parse_expr();
|
// Force collection (as opposed to just `parse_expr`) is required to avoid the
|
||||||
|
// attribute duplication seen in #138478.
|
||||||
|
let expr = this.parse_expr_force_collect();
|
||||||
// FIXME(nnethercote) Sometimes with expressions we get a trailing comma, possibly
|
// FIXME(nnethercote) Sometimes with expressions we get a trailing comma, possibly
|
||||||
// related to the FIXME in `collect_tokens_for_expr`. Examples are the multi-line
|
// related to the FIXME in `collect_tokens_for_expr`. Examples are the multi-line
|
||||||
// `assert_eq!` calls involving arguments annotated with `#[rustfmt::skip]` in
|
// `assert_eq!` calls involving arguments annotated with `#[rustfmt::skip]` in
|
||||||
|
|
133
tests/ui/attributes/dont-dup-expr-attrs.rs
Normal file
133
tests/ui/attributes/dont-dup-expr-attrs.rs
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
//@ 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;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue