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.rs33
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,
+ }
+}