Skip to content

Commit

Permalink
Merge branch 'dev' into dependabot/cargo/indexmap-2.7.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Eh2406 authored Dec 20, 2024
2 parents 0294820 + 10cb803 commit 0996fcc
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 25 deletions.
21 changes: 19 additions & 2 deletions src/internal/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use std::collections::HashSet as Set;
use std::sync::Arc;

use crate::internal::{
Arena, DecisionLevel, HashArena, Id, IncompDpId, Incompatibility, PartialSolution, Relation,
SatisfierSearch, SmallVec,
Arena, DecisionLevel, HashArena, Id, IncompDpId, IncompId, Incompatibility, PartialSolution,
Relation, SatisfierSearch, SmallVec,
};
use crate::{DependencyProvider, DerivationTree, Map, NoSolutionError, VersionSet};

Expand Down Expand Up @@ -73,6 +73,23 @@ impl<DP: DependencyProvider> State<DP> {
}
}

/// Add the dependencies for the current version of the current package as incompatibilities.
pub(crate) fn add_package_version_dependencies(
&mut self,
package: Id<DP::P>,
version: DP::V,
dependencies: impl IntoIterator<Item = (DP::P, DP::VS)>,
) -> Option<IncompId<DP::P, DP::VS, DP::M>> {
let dep_incompats =
self.add_incompatibility_from_dependencies(package, version.clone(), dependencies);
self.partial_solution.add_package_version_incompatibilities(
package,
version.clone(),
dep_incompats,
&self.incompatibility_store,
)
}

/// Add an incompatibility to the state.
pub(crate) fn add_incompatibility(&mut self, incompat: Incompatibility<DP::P, DP::VS, DP::M>) {
let id = self.incompatibility_store.alloc(incompat);
Expand Down
15 changes: 9 additions & 6 deletions src/internal/partial_solution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,12 +417,15 @@ impl<DP: DependencyProvider> PartialSolution<DP> {
self.has_ever_backtracked = true;
}

/// We can add the version to the partial solution as a decision
/// if it doesn't produce any conflict with the new incompatibilities.
/// In practice I think it can only produce a conflict if one of the dependencies
/// (which are used to make the new incompatibilities)
/// is already in the partial solution with an incompatible version.
pub(crate) fn add_version(
/// Add a package version as decision if none of its dependencies conflicts with the partial
/// solution.
///
/// If the resolution never backtracked before, a fast path adds the package version directly
/// without checking dependencies.
///
/// Returns the incompatibility that caused the current version to be rejected, if a conflict
/// in the dependencies was found.
pub(crate) fn add_package_version_incompatibilities(
&mut self,
package: Id<DP::P>,
version: DP::V,
Expand Down
12 changes: 3 additions & 9 deletions src/solver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,15 +228,9 @@ pub fn resolve<DP: DependencyProvider>(
};

// Add that package and version if the dependencies are not problematic.
let dep_incompats =
state.add_incompatibility_from_dependencies(p, v.clone(), dependencies);

if let Some(conflict) = state.partial_solution.add_version(
p,
v,
dep_incompats,
&state.incompatibility_store,
) {
if let Some(conflict) =
state.add_package_version_dependencies(p, v.clone(), dependencies)
{
conflict_tracker.entry(p).or_default().dependencies_affected += 1;
for (incompat_package, _) in state.incompatibility_store[conflict].iter() {
if incompat_package == p {
Expand Down
24 changes: 16 additions & 8 deletions version-ranges/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,11 @@ impl<V: Ord> Ranges<V> {
}

/// Returns true if self contains the specified value.
pub fn contains(&self, version: &V) -> bool {
pub fn contains<Q>(&self, version: &Q) -> bool
where
V: Borrow<Q>,
Q: ?Sized + PartialOrd,
{
self.segments
.binary_search_by(|segment| {
// We have to reverse because we need the segment wrt to the version, while
Expand Down Expand Up @@ -470,19 +474,23 @@ impl<V: Ord> Ord for Ranges<V> {
/// ^ ^ ^
/// less equal greater
/// ```
fn within_bounds<V: PartialOrd>(version: &V, segment: &Interval<V>) -> Ordering {
fn within_bounds<Q, V>(version: &Q, segment: &Interval<V>) -> Ordering
where
V: Borrow<Q>,
Q: ?Sized + PartialOrd,
{
let below_lower_bound = match segment {
(Excluded(start), _) => version <= start,
(Included(start), _) => version < start,
(Excluded(start), _) => version <= start.borrow(),
(Included(start), _) => version < start.borrow(),
(Unbounded, _) => false,
};
if below_lower_bound {
return Ordering::Less;
}
let below_upper_bound = match segment {
(_, Unbounded) => true,
(_, Included(end)) => version <= end,
(_, Excluded(end)) => version < end,
(_, Included(end)) => version <= end.borrow(),
(_, Excluded(end)) => version < end.borrow(),
};
if below_upper_bound {
return Ordering::Equal;
Expand Down Expand Up @@ -1304,7 +1312,7 @@ pub mod tests {

#[test]
fn always_contains_exact(version in version_strat()) {
assert!(Ranges::singleton(version).contains(&version));
assert!(Ranges::<u32>::singleton(version).contains(&version));
}

#[test]
Expand All @@ -1326,7 +1334,7 @@ pub mod tests {

#[test]
fn from_range_bounds(range in any::<(Bound<u32>, Bound<u32>)>(), version in version_strat()) {
let rv: Ranges<_> = Ranges::from_range_bounds(range);
let rv: Ranges<_> = Ranges::<u32>::from_range_bounds(range);
assert_eq!(range.contains(&version), rv.contains(&version));
}

Expand Down

0 comments on commit 0996fcc

Please sign in to comment.