Skip to content

Commit

Permalink
Return NoSolutionError from unit propagation
Browse files Browse the repository at this point in the history
In uv, the only pubgrub error that can occur is a `NoSolutionError`, and the only place it can occur is `unit_propagation`. By returning `NoSolutionError` instead of `PubGrubError`, we can remove `unreachable!()` calls on uv's side. `NoSolutionError` is a type alias for `DerivationTree`.
  • Loading branch information
konstin committed Jul 15, 2024
1 parent b4435e2 commit c25306c
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 12 deletions.
22 changes: 16 additions & 6 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,19 @@ use thiserror::Error;
use crate::report::DerivationTree;
use crate::solver::DependencyProvider;

/// There is no solution for this set of dependencies.
pub type NoSolutionError<DP> = DerivationTree<
<DP as DependencyProvider>::P,
<DP as DependencyProvider>::VS,
<DP as DependencyProvider>::M,
>;

/// Errors that may occur while solving dependencies.
#[derive(Error)]
pub enum PubGrubError<DP>
where
DP: DependencyProvider,
{
pub enum PubGrubError<DP: DependencyProvider> {
/// There is no solution for this set of dependencies.
#[error("No solution")]
NoSolution(DerivationTree<DP::P, DP::VS, DP::M>),
NoSolution(NoSolutionError<DP>),

/// Error arising when the implementer of
/// [DependencyProvider]
Expand Down Expand Up @@ -62,13 +66,19 @@ where
Failure(String),
}

impl<DP: DependencyProvider> From<NoSolutionError<DP>> for PubGrubError<DP> {
fn from(err: NoSolutionError<DP>) -> Self {
Self::NoSolution(err)
}
}

impl<DP> std::fmt::Debug for PubGrubError<DP>
where
DP: DependencyProvider,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::NoSolution(arg0) => f.debug_tuple("NoSolution").field(arg0).finish(),
Self::NoSolution(err) => f.debug_tuple("NoSolution").field(&err).finish(),
Self::ErrorRetrievingDependencies {
package,
version,
Expand Down
10 changes: 4 additions & 6 deletions src/internal/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use std::collections::HashSet as Set;
use std::sync::Arc;

use crate::error::PubGrubError;
use crate::error::NoSolutionError;
use crate::internal::arena::Arena;
use crate::internal::incompatibility::{Incompatibility, Relation};
use crate::internal::partial_solution::SatisfierSearch::{
Expand Down Expand Up @@ -126,7 +126,7 @@ impl<DP: DependencyProvider> State<DP> {

/// Unit propagation is the core mechanism of the solving algorithm.
/// CF <https://github.com/dart-lang/pub/blob/master/doc/solver.md#unit-propagation>
pub fn unit_propagation(&mut self, package: DP::P) -> Result<(), PubGrubError<DP>> {
pub fn unit_propagation(&mut self, package: DP::P) -> Result<(), NoSolutionError<DP>> {
self.unit_propagation_buffer.clear();
self.unit_propagation_buffer.push(package);
while let Some(current_package) = self.unit_propagation_buffer.pop() {
Expand Down Expand Up @@ -205,16 +205,14 @@ impl<DP: DependencyProvider> State<DP> {
fn conflict_resolution(
&mut self,
incompatibility: IncompDpId<DP>,
) -> Result<(DP::P, IncompDpId<DP>), PubGrubError<DP>> {
) -> Result<(DP::P, IncompDpId<DP>), NoSolutionError<DP>> {
let mut current_incompat_id = incompatibility;
let mut current_incompat_changed = false;
loop {
if self.incompatibility_store[current_incompat_id]
.is_terminal(&self.root_package, &self.root_version)
{
return Err(PubGrubError::NoSolution(
self.build_derivation_tree(current_incompat_id),
));
return Err(self.build_derivation_tree(current_incompat_id));
} else {
let (package, satisfier_search_result) = self.partial_solution.satisfier_search(
&self.incompatibility_store[current_incompat_id],
Expand Down

0 comments on commit c25306c

Please sign in to comment.