Skip to content

Commit 403cd31

Browse files
committed
Fix redundant enumeration of all package versions in some resolver errors
1 parent f5add0c commit 403cd31

File tree

2 files changed

+58
-10
lines changed

2 files changed

+58
-10
lines changed

crates/uv-resolver/src/error.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ impl std::fmt::Display for NoSolutionError {
333333
}
334334

335335
collapse_unavailable_versions(&mut tree);
336+
collapse_redundant_no_versions(&mut tree);
336337
collapse_redundant_depends_on_no_versions(&mut tree);
337338

338339
if should_display_tree {
@@ -427,6 +428,62 @@ fn display_tree_inner(
427428
}
428429
}
429430

431+
fn collapse_redundant_no_versions(
432+
tree: &mut DerivationTree<PubGrubPackage, Range<Version>, UnavailableReason>,
433+
) {
434+
match tree {
435+
DerivationTree::External(_) => {}
436+
DerivationTree::Derived(derived) => {
437+
match (
438+
Arc::make_mut(&mut derived.cause1),
439+
Arc::make_mut(&mut derived.cause2),
440+
) {
441+
// If we have a node for a package with no versions...
442+
(
443+
DerivationTree::External(External::NoVersions(package, versions)),
444+
ref mut other,
445+
)
446+
| (
447+
ref mut other,
448+
DerivationTree::External(External::NoVersions(package, versions)),
449+
) => {
450+
// First, always recursively visit the other side of the tree
451+
collapse_redundant_no_versions(other);
452+
453+
let DerivationTree::Derived(derived) = other else {
454+
return;
455+
};
456+
457+
// If the range in the conclusion (terms) matches the range of no versions,
458+
// then we'll drop this node
459+
let Some(Term::Positive(term)) = derived.terms.get(package) else {
460+
return;
461+
};
462+
let versions = versions.complement();
463+
464+
// If we're disqualifying a single version, this is important to retain, e.g,
465+
// for `only foo==1.0.0 is available`
466+
if versions.as_singleton().is_some() {
467+
return;
468+
}
469+
470+
if *term != versions {
471+
return;
472+
}
473+
474+
// Replace this node with the other tree
475+
*tree = other.clone();
476+
}
477+
// If not, just recurse
478+
_ => {
479+
collapse_redundant_no_versions(Arc::make_mut(&mut derived.cause1));
480+
collapse_redundant_no_versions(Arc::make_mut(&mut derived.cause2));
481+
}
482+
}
483+
}
484+
}
485+
}
486+
430487
/// Given a [`DerivationTree`], collapse any `NoVersion` incompatibilities for workspace members
431488
/// to avoid saying things like "only <workspace-member>==0.1.0 is available".
432489
fn collapse_no_versions_of_workspace_members(

crates/uv/tests/it/pip_compile.rs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13126,16 +13126,7 @@ fn compile_enumerate_no_versions() -> Result<()> {
1312613126
----- stderr -----
1312713127
× No solution found when resolving dependencies:
1312813128
╰─▶ Because the current Python version (3.10.[X]) does not satisfy Python>=3.11,<4.0 and all versions of rooster-blue depend on Python>=3.11,<4.0, we can conclude that all versions of rooster-blue cannot be used.
13129-
And because only the following versions of rooster-blue are available:
13130-
rooster-blue==0.0.1
13131-
rooster-blue==0.0.2
13132-
rooster-blue==0.0.3
13133-
rooster-blue==0.0.4
13134-
rooster-blue==0.0.5
13135-
rooster-blue==0.0.6
13136-
rooster-blue==0.0.7
13137-
rooster-blue==0.0.8
13138-
and you require rooster-blue, we can conclude that your requirements are unsatisfiable.
13129+
And because you require rooster-blue, we can conclude that your requirements are unsatisfiable.
1313913130
"###);
1314013131

1314113132
Ok(())

0 commit comments

Comments
 (0)