diff --git a/src/internal/incompatibility.rs b/src/internal/incompatibility.rs index e3206f8b..b908674a 100644 --- a/src/internal/incompatibility.rs +++ b/src/internal/incompatibility.rs @@ -43,11 +43,11 @@ enum Kind { /// Initial incompatibility aiming at picking the root package for the first decision. NotRoot(P, V), /// There are no versions in the given range for this package. - NoVersions(P, Range), + NoVersions(P), /// Dependencies of the package are unavailable for versions in that range. - UnavailableDependencies(P, Range), + UnavailableDependencies(P), /// Incompatibility coming from the dependencies of a given package. - FromDependencyOf(P, Range, P, Range), + FromDependencyOf(P, P), /// Derived from two causes. Stores cause ids. DerivedFrom(IncompId, IncompId), } @@ -84,13 +84,10 @@ impl Incompatibility { /// Create an incompatibility to remember /// that a given range does not contain any version. pub fn no_versions(package: P, term: Term) -> Self { - let range = match &term { - Term::Positive(r) => r.clone(), - Term::Negative(_) => panic!("No version should have a positive term"), - }; + assert!(term.is_positive(), "No version should have a positive term"); Self { package_terms: SmallMap::One([(package.clone(), term)]), - kind: Kind::NoVersions(package, range), + kind: Kind::NoVersions(package), } } @@ -98,10 +95,12 @@ impl Incompatibility { /// that a package version is not selectable /// because its list of dependencies is unavailable. pub fn unavailable_dependencies(package: P, version: V) -> Self { - let range = Range::exact(version); Self { - package_terms: SmallMap::One([(package.clone(), Term::Positive(range.clone()))]), - kind: Kind::UnavailableDependencies(package, range), + package_terms: SmallMap::One([( + package.clone(), + Term::Positive(Range::exact(version)), + )]), + kind: Kind::UnavailableDependencies(package), } } @@ -114,7 +113,7 @@ impl Incompatibility { (package.clone(), Term::Positive(range1.clone())), (p2.clone(), Term::Negative(range2.clone())), ]), - kind: Kind::FromDependencyOf(package, range1, p2.clone(), range2.clone()), + kind: Kind::FromDependencyOf(package, p2.clone()), } } @@ -239,7 +238,8 @@ impl Incompatibility { shared_ids: &Set>, store: &Arena, ) -> DerivationTree { - match &store[self_id].kind { + let val = &store[self_id]; + match &val.kind { Kind::DerivedFrom(id1, id2) => { let cause1 = Self::build_derivation_tree(*id1, shared_ids, store); let cause2 = Self::build_derivation_tree(*id2, shared_ids, store); @@ -254,18 +254,22 @@ impl Incompatibility { Kind::NotRoot(package, version) => { DerivationTree::External(External::NotRoot(package.clone(), version.clone())) } - Kind::NoVersions(package, range) => { - DerivationTree::External(External::NoVersions(package.clone(), range.clone())) + Kind::NoVersions(package) => DerivationTree::External(External::NoVersions( + package.clone(), + val.package_terms[package].as_range().clone(), + )), + Kind::UnavailableDependencies(package) => { + DerivationTree::External(External::UnavailableDependencies( + package.clone(), + val.package_terms[package].as_range().clone(), + )) } - Kind::UnavailableDependencies(package, range) => DerivationTree::External( - External::UnavailableDependencies(package.clone(), range.clone()), - ), - Kind::FromDependencyOf(package, range, dep_package, dep_range) => { + Kind::FromDependencyOf(package, dep_package) => { DerivationTree::External(External::FromDependencyOf( package.clone(), - range.clone(), + val.package_terms[package].as_range().clone(), dep_package.clone(), - dep_range.clone(), + val.package_terms[dep_package].as_range().clone(), )) } } @@ -305,12 +309,12 @@ pub mod tests { let mut store = Arena::new(); let i1 = store.alloc(Incompatibility { package_terms: SmallMap::Two([("p1", t1.clone()), ("p2", t2.negate())]), - kind: Kind::UnavailableDependencies("0", Range::any()) + kind: Kind::UnavailableDependencies("0") }); let i2 = store.alloc(Incompatibility { package_terms: SmallMap::Two([("p2", t2), ("p3", t3.clone())]), - kind: Kind::UnavailableDependencies("0", Range::any()) + kind: Kind::UnavailableDependencies("0") }); let mut i3 = Map::default(); diff --git a/src/internal/small_map.rs b/src/internal/small_map.rs index a1fe5f9e..375b4cbc 100644 --- a/src/internal/small_map.rs +++ b/src/internal/small_map.rs @@ -1,5 +1,5 @@ use crate::type_aliases::Map; -use std::hash::Hash; +use std::{hash::Hash, ops::Index}; #[derive(Debug, Clone)] pub enum SmallMap { @@ -146,6 +146,13 @@ impl SmallMap { } } +impl Index<&K> for SmallMap { + type Output = V; + fn index(&self, key: &K) -> &V { + &self.get(key).unwrap() + } +} + impl SmallMap { pub fn as_map(&self) -> Map { match self { diff --git a/src/term.rs b/src/term.rs index 63c4da7d..5bdfbdb9 100644 --- a/src/term.rs +++ b/src/term.rs @@ -71,6 +71,14 @@ impl Term { _ => panic!("Negative term cannot unwrap positive range"), } } + + /// Unwrap the range contains in the term. + pub(crate) fn as_range(&self) -> &Range { + match self { + Self::Positive(range) => range, + Self::Negative(range) => range, + } + } } /// Set operations with terms.