Skip to content

Commit 10cb803

Browse files
authored
Add State::add_incompatibility_from_dependencies (#27) (pubgrub-rs#300)
This wrapper avoids accessing the `incompatibility_store` directly in uv code. Before: ```rust let dep_incompats = self.pubgrub.add_version( package.clone(), version.clone(), dependencies, ); self.pubgrub.partial_solution.add_version( package.clone(), version.clone(), dep_incompats, &self.pubgrub.incompatibility_store, ); ``` After: ```rust self.pubgrub.add_incompatibility_from_dependencies(package.clone(), version.clone(), dependencies); ``` `add_incompatibility_from_dependencies` is one of the main methods for the custom interface to pubgrub.
1 parent 7767ef2 commit 10cb803

File tree

3 files changed

+31
-17
lines changed

3 files changed

+31
-17
lines changed

src/internal/core.rs

+19-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use std::collections::HashSet as Set;
77
use std::sync::Arc;
88

99
use crate::internal::{
10-
Arena, DecisionLevel, HashArena, Id, IncompDpId, Incompatibility, PartialSolution, Relation,
11-
SatisfierSearch, SmallVec,
10+
Arena, DecisionLevel, HashArena, Id, IncompDpId, IncompId, Incompatibility, PartialSolution,
11+
Relation, SatisfierSearch, SmallVec,
1212
};
1313
use crate::{DependencyProvider, DerivationTree, Map, NoSolutionError, VersionSet};
1414

@@ -73,6 +73,23 @@ impl<DP: DependencyProvider> State<DP> {
7373
}
7474
}
7575

76+
/// Add the dependencies for the current version of the current package as incompatibilities.
77+
pub(crate) fn add_package_version_dependencies(
78+
&mut self,
79+
package: Id<DP::P>,
80+
version: DP::V,
81+
dependencies: impl IntoIterator<Item = (DP::P, DP::VS)>,
82+
) -> Option<IncompId<DP::P, DP::VS, DP::M>> {
83+
let dep_incompats =
84+
self.add_incompatibility_from_dependencies(package, version.clone(), dependencies);
85+
self.partial_solution.add_package_version_incompatibilities(
86+
package,
87+
version.clone(),
88+
dep_incompats,
89+
&self.incompatibility_store,
90+
)
91+
}
92+
7693
/// Add an incompatibility to the state.
7794
pub(crate) fn add_incompatibility(&mut self, incompat: Incompatibility<DP::P, DP::VS, DP::M>) {
7895
let id = self.incompatibility_store.alloc(incompat);

src/internal/partial_solution.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -417,12 +417,15 @@ impl<DP: DependencyProvider> PartialSolution<DP> {
417417
self.has_ever_backtracked = true;
418418
}
419419

420-
/// We can add the version to the partial solution as a decision
421-
/// if it doesn't produce any conflict with the new incompatibilities.
422-
/// In practice I think it can only produce a conflict if one of the dependencies
423-
/// (which are used to make the new incompatibilities)
424-
/// is already in the partial solution with an incompatible version.
425-
pub(crate) fn add_version(
420+
/// Add a package version as decision if none of its dependencies conflicts with the partial
421+
/// solution.
422+
///
423+
/// If the resolution never backtracked before, a fast path adds the package version directly
424+
/// without checking dependencies.
425+
///
426+
/// Returns the incompatibility that caused the current version to be rejected, if a conflict
427+
/// in the dependencies was found.
428+
pub(crate) fn add_package_version_incompatibilities(
426429
&mut self,
427430
package: Id<DP::P>,
428431
version: DP::V,

src/solver.rs

+3-9
Original file line numberDiff line numberDiff line change
@@ -228,15 +228,9 @@ pub fn resolve<DP: DependencyProvider>(
228228
};
229229

230230
// Add that package and version if the dependencies are not problematic.
231-
let dep_incompats =
232-
state.add_incompatibility_from_dependencies(p, v.clone(), dependencies);
233-
234-
if let Some(conflict) = state.partial_solution.add_version(
235-
p,
236-
v,
237-
dep_incompats,
238-
&state.incompatibility_store,
239-
) {
231+
if let Some(conflict) =
232+
state.add_package_version_dependencies(p, v.clone(), dependencies)
233+
{
240234
conflict_tracker.entry(p).or_default().dependencies_affected += 1;
241235
for (incompat_package, _) in state.incompatibility_store[conflict].iter() {
242236
if incompat_package == p {

0 commit comments

Comments
 (0)