Skip to content

Commit 5d2e4d3

Browse files
committed
fix: Prevent combinatorial explosion in test_parse
1 parent eeb4fb4 commit 5d2e4d3

2 files changed

Lines changed: 20 additions & 73 deletions

File tree

crates/libtest2/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ pub mod _private {
4444
pub use libtest2_harness::TestKind;
4545

4646
pub use crate::_main_parse as main_parse;
47+
pub use crate::_parse_ignore as parse_ignore;
4748
pub use crate::_test_parse as test_parse;
4849
pub use crate::case::DynCase;
4950
}

crates/libtest2/src/macros.rs

Lines changed: 19 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -26,44 +26,35 @@ macro_rules! _test_parse {
2626
};
2727

2828
// Recursively handle attributes
29-
(name=$name:ident body=[$($item:tt)*] unparsed_attrs=[] parsed_attrs=[$(#[$parsed_attr:meta])*] $(ignore=$state:expr)?) => {
29+
(name=$name:ident body=[$($item:tt)*] unparsed_attrs=[] parsed_attrs=[$(#[$parsed_attr:meta])*] $(ignore=$ignore:tt)?) => {
3030
$crate::_private::test_parse! {
3131
name=$name
3232
body=[$($item)*]
3333
attrs=[$(#[$parsed_attr])*]
34-
$(ignore=$state)?
34+
$(ignore=$ignore)?
3535
}
3636
};
37-
(name=$name:ident body=[$($item:tt)*] unparsed_attrs=[#[ignore] $(#[$($unparsed_attr:tt)+])*] parsed_attrs=[$(#[$parsed_attr:meta])*] $(ignore=$state:expr)?) => {
37+
(name=$name:ident body=[$($item:tt)*] unparsed_attrs=[#[ignore $(= $reason:literal)?] $(#[$($unparsed_attr:tt)+])*] parsed_attrs=[$(#[$parsed_attr:meta])*] $(ignore=$ignore:tt)?) => {
3838
$crate::_private::test_parse! {
3939
name=$name
4040
body=[$($item)*]
4141
unparsed_attrs=[$(#[$($unparsed_attr)*])*]
4242
parsed_attrs=[$(#[$parsed_attr])*]
43-
ignore=()
43+
ignore=[$($reason)?]
4444
}
4545
};
46-
(name=$name:ident body=[$($item:tt)*] unparsed_attrs=[#[ignore = $reason:literal] $(#[$($unparsed_attr:tt)+])*] parsed_attrs=[$(#[$parsed_attr:meta])*] $(ignore=$state:expr)?) => {
47-
$crate::_private::test_parse! {
48-
name=$name
49-
body=[$($item)*]
50-
unparsed_attrs=[$(#[$($unparsed_attr)*])*]
51-
parsed_attrs=[$(#[$parsed_attr])*]
52-
ignore=$reason
53-
}
54-
};
55-
(name=$name:ident body=[$($item:tt)*] unparsed_attrs=[#[$($attr:tt)+] $(#[$($unparsed_attr:tt)+])*] parsed_attrs=[$(#[$parsed_attr:meta])*] $(ignore=$state:expr)?) => {
46+
(name=$name:ident body=[$($item:tt)*] unparsed_attrs=[#[$($attr:tt)+] $(#[$($unparsed_attr:tt)+])*] parsed_attrs=[$(#[$parsed_attr:meta])*] $(ignore=$ignore:tt)?) => {
5647
$crate::_private::test_parse! {
5748
name=$name
5849
body=[$($item)*]
5950
unparsed_attrs=[$(#[$($unparsed_attr)*])*]
6051
parsed_attrs=[#[$($attr)* $(#[$($parsed_attr)*])*]]
61-
$(ignore=$state)?
52+
$(ignore=$ignore)?
6253
}
6354
};
6455

6556
// End result
66-
(name=$name:ident body=[$($item:tt)*] attrs=[$(#[$attr:meta])*]) => {
57+
(name=$name:ident body=[$($item:tt)*] attrs=[$(#[$attr:meta])*] $(ignore=$ignore:tt)?) => {
6758
#[allow(non_camel_case_types)]
6859
struct $name;
6960

@@ -87,68 +78,23 @@ macro_rules! _test_parse {
8778
$(#[$attr])*
8879
fn run $($item)*
8980

90-
run(context)
91-
}
92-
}
93-
};
94-
(name=$name:ident body=[$($item:tt)*] attrs=[$(#[$attr:meta])*] ignore=$reason:literal) => {
95-
#[allow(non_camel_case_types)]
96-
struct $name;
97-
98-
impl $crate::_private::Case for $name {
99-
fn name(&self) -> &str {
100-
$crate::_private::push!(crate::TESTS, _: $crate::_private::DynCase = $crate::_private::DynCase(&$name));
101-
102-
stringify!($name)
103-
}
104-
fn kind(&self) -> $crate::_private::TestKind {
105-
Default::default()
106-
}
107-
fn source(&self) -> Option<&$crate::_private::Source> {
108-
None
109-
}
110-
fn exclusive(&self, _: &$crate::TestContext) -> bool {
111-
false
112-
}
113-
114-
fn run(&self, context: &$crate::TestContext) -> $crate::RunResult {
115-
$(#[$attr])*
116-
fn run $($item)*
117-
118-
context.ignore_for($reason)?;
81+
$(
82+
$crate::_private::parse_ignore!($ignore, context)?;
83+
)?
11984

12085
run(context)
12186
}
12287
}
12388
};
124-
(name=$name:ident body=[$($item:tt)*] attrs=[$(#[$attr:meta])*] ignore=$unused:expr) => {
125-
#[allow(non_camel_case_types)]
126-
struct $name;
127-
128-
impl $crate::_private::Case for $name {
129-
fn name(&self) -> &str {
130-
$crate::_private::push!(crate::TESTS, _: $crate::_private::DynCase = $crate::_private::DynCase(&$name));
131-
132-
stringify!($name)
133-
}
134-
fn kind(&self) -> $crate::_private::TestKind {
135-
Default::default()
136-
}
137-
fn source(&self) -> Option<&$crate::_private::Source> {
138-
None
139-
}
140-
fn exclusive(&self, _: &$crate::TestContext) -> bool {
141-
false
142-
}
143-
144-
fn run(&self, context: &$crate::TestContext) -> $crate::RunResult {
145-
$(#[$attr])*
146-
fn run $($item)*
147-
148-
context.ignore()?;
89+
}
14990

150-
run(context)
151-
}
152-
}
91+
#[macro_export]
92+
#[doc(hidden)]
93+
macro_rules! _parse_ignore {
94+
([$reason:literal], $context:expr) => {
95+
$context.ignore_for($reason)
96+
};
97+
([], $context:expr) => {
98+
$context.ignore()
15399
};
154100
}

0 commit comments

Comments
 (0)