diff --git a/src/internal/core.rs b/src/internal/core.rs index 1274ecbf..31143ff4 100644 --- a/src/internal/core.rs +++ b/src/internal/core.rs @@ -24,6 +24,7 @@ pub struct State { root_version: V, incompatibilities: Map>>, + used_incompatibilities: rustc_hash::FxHashSet>, /// Partial solution. /// TODO: remove pub. @@ -52,6 +53,7 @@ impl State { root_package, root_version, incompatibilities, + used_incompatibilities: rustc_hash::FxHashSet::default(), partial_solution: PartialSolution::empty(), incompatibility_store, unit_propagation_buffer: vec![], @@ -100,6 +102,9 @@ impl State { let mut conflict_id = None; // We only care about incompatibilities if it contains the current package. for &incompat_id in self.incompatibilities[¤t_package].iter().rev() { + if self.used_incompatibilities.contains(&incompat_id) { + continue; + } let current_incompat = &self.incompatibility_store[incompat_id]; match self.partial_solution.relation(current_incompat) { // If the partial solution satisfies the incompatibility @@ -110,6 +115,7 @@ impl State { } Relation::AlmostSatisfied(package_almost) => { self.unit_propagation_buffer.push(package_almost.clone()); + self.used_incompatibilities.insert(incompat_id); // Add (not term) to the partial solution with incompat as cause. self.partial_solution.add_derivation( package_almost, @@ -117,6 +123,9 @@ impl State { &self.incompatibility_store, ); } + Relation::Contradicted(_) => { + self.used_incompatibilities.insert(incompat_id); + } _ => {} } } @@ -124,6 +133,7 @@ impl State { let (package_almost, root_cause) = self.conflict_resolution(incompat_id)?; self.unit_propagation_buffer.clear(); self.unit_propagation_buffer.push(package_almost.clone()); + self.used_incompatibilities.insert(root_cause); // Add to the partial solution with incompat as cause. self.partial_solution.add_derivation( package_almost, @@ -200,6 +210,7 @@ impl State { ) { self.partial_solution .backtrack(decision_level, &self.incompatibility_store); + self.used_incompatibilities.clear(); if incompat_changed { self.merge_incompatibility(incompat); }