diff --git a/src/internal/core.rs b/src/internal/core.rs index d3281d24..6c3b5d55 100644 --- a/src/internal/core.rs +++ b/src/internal/core.rs @@ -25,7 +25,7 @@ pub struct State { root_package: DP::P, root_version: DP::V, - /// All incompatibilities indexed by package. + /// The set of incompatibilities for each package. #[allow(clippy::type_complexity)] incompatibilities: Map>>, diff --git a/src/internal/incompatibility.rs b/src/internal/incompatibility.rs index fb45ca48..da906c70 100644 --- a/src/internal/incompatibility.rs +++ b/src/internal/incompatibility.rs @@ -34,14 +34,14 @@ use crate::version_set::VersionSet; #[derive(Debug, Clone)] pub struct Incompatibility { package_terms: SmallMap>, - /// The reason for the incompatibility. + /// The reason why this version or combination of versions can't be selected. pub kind: Kind, } /// Type alias of unique identifiers for incompatibilities. pub type IncompId = Id>; -/// The reason for the incompatibility. +/// The reason why a version or combination of versions can't be selected. #[derive(Debug, Clone)] pub enum Kind { /// Initial incompatibility aiming at picking the root package for the first decision. @@ -138,6 +138,17 @@ impl Incompatibilit } } + /// Create an incompatibility to remember + /// that a package version is not selectable + /// because its dependencies are not usable. + pub fn unusable_dependencies(package: P, version: VS::V, reason: M) -> Self { + let set = VS::singleton(version); + Self { + package_terms: SmallMap::One([(package.clone(), Term::Positive(set.clone()))]), + kind: Kind::Custom(package, set, reason), + } + } + /// Build an incompatibility from a given dependency. pub fn from_dependency(package: P, versions: VS, dep: (&P, &VS)) -> Self { let (p2, set2) = dep; @@ -154,8 +165,7 @@ impl Incompatibilit } } - /// Return the two packages where this incompatibility when the incompatibility was created - /// through a dependency edge between the two. + /// The two packages causing the incompatibility, if it was derived from dependencies. pub fn as_dependency(&self) -> Option<(&P, &P)> { match &self.kind { Kind::FromDependencyOf(p1, _, p2, _) => Some((p1, p2)), @@ -296,11 +306,9 @@ impl Incompatibilit dep_set.clone(), )) } - Kind::Custom(package, set, metadata) => DerivationTree::External(External::Custom( - package.clone(), - set.clone(), - metadata.clone(), - )), + Kind::Custom(package, set, reason) => { + DerivationTree::External(External::Custom(package, set, reason)) + } } } } diff --git a/src/report.rs b/src/report.rs index 6a309165..35880dce 100644 --- a/src/report.rs +++ b/src/report.rs @@ -121,6 +121,9 @@ impl DerivationTree // // Cannot be merged because the reason may not match DerivationTree::External(External::NoVersions(_, _)) => None, + DerivationTree::External(External::Custom(_, r, reason)) => Some( + DerivationTree::External(External::Custom(package, set.union(&r), reason)), + ), DerivationTree::External(External::FromDependencyOf(p1, r1, p2, r2)) => { if p1 == package { Some(DerivationTree::External(External::FromDependencyOf( @@ -138,8 +141,6 @@ impl DerivationTree ))) } } - // Cannot be merged because the reason may not match - DerivationTree::External(External::Custom(_, _, _)) => None, } } } @@ -159,18 +160,14 @@ impl fmt::Display write!(f, "there is no version of {} in {}", package, set) } } - Self::Custom(package, set, metadata) => { + Self::Custom(package, set, reason) => { if set == &VS::full() { - write!( - f, - "dependencies of {} are unavailable {}", - package, metadata - ) + write!(f, "dependencies of {} are unusable: {reason}", package) } else { write!( f, - "dependencies of {} at version {} are unavailable {}", - package, set, metadata + "dependencies of {} at version {} are unusable: {reason}", + package, set ) } }