Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/cfg/src/dnf.rs')
| -rw-r--r-- | crates/cfg/src/dnf.rs | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/crates/cfg/src/dnf.rs b/crates/cfg/src/dnf.rs index 75ded9aa1f..0ae685a7d0 100644 --- a/crates/cfg/src/dnf.rs +++ b/crates/cfg/src/dnf.rs @@ -255,11 +255,11 @@ impl Builder { fn make_dnf(expr: CfgExpr) -> CfgExpr { match expr { CfgExpr::Invalid | CfgExpr::Atom(_) | CfgExpr::Not(_) => expr, - CfgExpr::Any(e) => CfgExpr::Any(e.into_iter().map(make_dnf).collect()), + CfgExpr::Any(e) => flatten(CfgExpr::Any(e.into_iter().map(make_dnf).collect())), CfgExpr::All(e) => { - let e = e.into_iter().map(make_nnf).collect::<Vec<_>>(); + let e = e.into_iter().map(make_dnf).collect::<Vec<_>>(); - CfgExpr::Any(distribute_conj(&e)) + flatten(CfgExpr::Any(distribute_conj(&e))) } } } @@ -289,7 +289,7 @@ fn distribute_conj(conj: &[CfgExpr]) -> Vec<CfgExpr> { } } - let mut out = Vec::new(); + let mut out = Vec::new(); // contains only `all()` let mut with = Vec::new(); go(&mut out, &mut with, conj); @@ -318,3 +318,28 @@ fn make_nnf(expr: CfgExpr) -> CfgExpr { }, } } + +/// Collapses nested `any()` and `all()` predicates. +fn flatten(expr: CfgExpr) -> CfgExpr { + match expr { + CfgExpr::All(inner) => CfgExpr::All( + inner + .into_iter() + .flat_map(|e| match e { + CfgExpr::All(inner) => inner, + _ => vec![e], + }) + .collect(), + ), + CfgExpr::Any(inner) => CfgExpr::Any( + inner + .into_iter() + .flat_map(|e| match e { + CfgExpr::Any(inner) => inner, + _ => vec![e], + }) + .collect(), + ), + _ => expr, + } +} |