Skip to content

Commit 0af2f65

Browse files
committed
fix(resolver): Make resolver behavior independent of package order
This addresses the ordering issue of for one of the problems from #12599. The intent behind the `path_pkg` check is to make sure we update workspace members in the lockfile if their version number changed. In this case, we don't need to recursively walk, because the change doesn't affect dependencies. However, we also shouldn't *prevent* recursive walks which is what we are doing today, both for packages marked to keep and for packages that have been "poisoned". So we fix this by moving that call after all recursive adds are complete so as to not interfere with them.
1 parent 2676a4a commit 0af2f65

File tree

2 files changed

+24
-15
lines changed

2 files changed

+24
-15
lines changed

src/cargo/ops/resolve.rs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -632,23 +632,11 @@ fn register_previous_locks(
632632
// however, nothing else in the dependency graph depends on `log` and the
633633
// newer version of `serde` requires a new version of `log` it'll get pulled
634634
// in (as we didn't accidentally lock it to an old version).
635-
//
636-
// Additionally, here we process all path dependencies listed in the previous
637-
// resolve. They can not only have their dependencies change but also
638-
// the versions of the package change as well. If this ends up happening
639-
// then we want to make sure we don't lock a package ID node that doesn't
640-
// actually exist. Note that we don't do transitive visits of all the
641-
// package's dependencies here as that'll be covered below to poison those
642-
// if they changed.
643635
let mut avoid_locking = HashSet::new();
644636
registry.add_to_yanked_whitelist(resolve.iter().filter(keep));
645637
for node in resolve.iter() {
646638
if !keep(&node) {
647639
add_deps(resolve, node, &mut avoid_locking);
648-
} else if let Some(pkg) = path_pkg(node.source_id()) {
649-
if pkg.package_id() != node {
650-
avoid_locking.insert(node);
651-
}
652640
}
653641
}
654642

@@ -741,6 +729,24 @@ fn register_previous_locks(
741729
}
742730
}
743731

732+
// Additionally, here we process all path dependencies listed in the previous
733+
// resolve. They can not only have their dependencies change but also
734+
// the versions of the package change as well. If this ends up happening
735+
// then we want to make sure we don't lock a package ID node that doesn't
736+
// actually exist. Note that we don't do transitive visits of all the
737+
// package's dependencies here as that'll be covered below to poison those
738+
// if they changed.
739+
//
740+
// This must come after all other `add_deps` calls to ensure it recursively walks the tree when
741+
// called.
742+
for node in resolve.iter() {
743+
if let Some(pkg) = path_pkg(node.source_id()) {
744+
if pkg.package_id() != node {
745+
avoid_locking.insert(node);
746+
}
747+
}
748+
}
749+
744750
// Alright now that we've got our new, fresh, shiny, and refined `keep`
745751
// function let's put it to action. Take a look at the previous lock file,
746752
// filter everything by this callback, and then shove everything else into

tests/testsuite/update.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,10 +1082,13 @@ rustdns.workspace = true
10821082
p.change_file("Cargo.toml", &workspace_toml.replace("2.29.8", "2.29.81"));
10831083

10841084
p.cargo("update -p crate2")
1085-
.with_stderr(
1085+
.with_stderr(&format!(
10861086
"\
1087+
[UPDATING] git repository `{}`
10871088
[UPDATING] crate1 v2.29.8 ([CWD]/crate1) -> v2.29.81
1088-
[UPDATING] crate2 v2.29.8 ([CWD]/crate2) -> v2.29.81",
1089-
)
1089+
[UPDATING] crate2 v2.29.8 ([CWD]/crate2) -> v2.29.81
1090+
[UPDATING] rustdns v0.5.0 ([..]) -> [..]",
1091+
git_project.url(),
1092+
))
10901093
.run();
10911094
}

0 commit comments

Comments
 (0)