diff --git a/src/internal/incompatibility.rs b/src/internal/incompatibility.rs index 168c5218..8de990c2 100644 --- a/src/internal/incompatibility.rs +++ b/src/internal/incompatibility.rs @@ -45,6 +45,8 @@ pub enum Kind { NoVersions(P, VS), /// Dependencies of the package are unavailable for versions in that range. UnavailableDependencies(P, VS), + /// Dependencies of the package are unusable for versions in that range. + UnusableDependencies(P, VS, Option), /// Incompatibility coming from the dependencies of a given package. FromDependencyOf(P, VS, P, VS), /// Derived from two causes. Stores cause ids. @@ -104,6 +106,17 @@ impl Incompatibility { } } + /// 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: Option) -> Self { + let set = VS::singleton(version); + Self { + package_terms: SmallMap::One([(package.clone(), Term::Positive(set.clone()))]), + kind: Kind::UnusableDependencies(package, set, reason), + } + } + /// Build an incompatibility from a given dependency. pub fn from_dependency(package: P, version: VS::V, dep: (&P, &VS)) -> Self { let set1 = VS::singleton(version); @@ -206,6 +219,9 @@ impl Incompatibility { Kind::UnavailableDependencies(package, set) => DerivationTree::External( External::UnavailableDependencies(package.clone(), set.clone()), ), + Kind::UnusableDependencies(package, set, reason) => DerivationTree::External( + External::UnusableDependencies(package.clone(), set.clone(), reason.clone()), + ), Kind::FromDependencyOf(package, set, dep_package, dep_set) => { DerivationTree::External(External::FromDependencyOf( package.clone(), diff --git a/src/range.rs b/src/range.rs index 47e76e44..9800c002 100644 --- a/src/range.rs +++ b/src/range.rs @@ -117,6 +117,10 @@ impl Range { segments: SmallVec::one((Included(v1.into()), Excluded(v2.into()))), } } + + pub fn is_empty(&self) -> bool { + self.segments.is_empty() + } } impl Range { diff --git a/src/report.rs b/src/report.rs index ff0b2d3f..57e862bd 100644 --- a/src/report.rs +++ b/src/report.rs @@ -41,6 +41,8 @@ pub enum External { NoVersions(P, VS), /// Dependencies of the package are unavailable for versions in that set. UnavailableDependencies(P, VS), + /// Dependencies of the package are unusable for versions in that set. + UnusableDependencies(P, VS, Option), /// Incompatibility coming from the dependencies of a given package. FromDependencyOf(P, VS, P, VS), } @@ -113,6 +115,13 @@ impl DerivationTree { DerivationTree::External(External::UnavailableDependencies(_, r)) => Some( DerivationTree::External(External::UnavailableDependencies(package, set.union(&r))), ), + DerivationTree::External(External::UnusableDependencies(_, r, reason)) => { + Some(DerivationTree::External(External::UnusableDependencies( + package, + set.union(&r), + reason, + ))) + } DerivationTree::External(External::FromDependencyOf(p1, r1, p2, r2)) => { if p1 == package { Some(DerivationTree::External(External::FromDependencyOf( @@ -158,6 +167,29 @@ impl fmt::Display for External { ) } } + Self::UnusableDependencies(package, set, reason) => { + if let Some(reason) = reason { + if set == &VS::full() { + write!(f, "dependencies of {} are unusable: {reason}", package) + } else { + write!( + f, + "dependencies of {} at version {} are unusable: {reason}", + package, set + ) + } + } else { + if set == &VS::full() { + write!(f, "dependencies of {} are unusable", package) + } else { + write!( + f, + "dependencies of {} at version {} are unusable", + package, set + ) + } + } + } Self::FromDependencyOf(p, set_p, dep, set_dep) => { if set_p == &VS::full() && set_dep == &VS::full() { write!(f, "{} depends on {}", p, dep)