Skip to content

Instantly share code, notes, and snippets.

@alexcrichton
Created December 10, 2020 16:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexcrichton/dc68eb4acc6fe2d131fb8f42d8cdcd95 to your computer and use it in GitHub Desktop.
Save alexcrichton/dc68eb4acc6fe2d131fb8f42d8cdcd95 to your computer and use it in GitHub Desktop.
diff --git a/src/cargo/core/registry.rs b/src/cargo/core/registry.rs
index 0380c447d..a0cc41d85 100644
--- a/src/cargo/core/registry.rs
+++ b/src/cargo/core/registry.rs
@@ -726,7 +726,9 @@ fn lock(
// If this dependency did not have a locked version, then we query
// all known locked packages to see if they match this dependency.
- // If anything does then we lock it to that and move on.
+ // If anything does then we lock it to that and move on. This will help
+ // us to use an existing lock file as much as possible, even when new
+ // nodes and dependencies are introduced.
let v = locked
.get(&(dep.source_id(), dep.package_name()))
.and_then(|vec| vec.iter().find(|&&(id, _)| dep.matches_id(id)));
@@ -737,6 +739,20 @@ fn lock(
return dep;
}
+ // Ok and failing all that, we make one last ditch attempt to search the
+ // patches as well. If our dependency matches a patched package and we
+ // can use that for a dependency then we do so.
+ let v = patches
+ .get(dep.source_id().canonical_url())
+ .and_then(|vec| vec.iter().find(|id| dep.matches_ignoring_source(**id)));
+ if let Some(id) = v {
+ trace!("\tthird hit on {}", id);
+ let mut dep = dep;
+ let req = VersionReq::exact(id.version());
+ dep.set_version_req(req);
+ return dep;
+ }
+
trace!("\tnope, unlocked");
dep
})
diff --git a/tests/testsuite/patch.rs b/tests/testsuite/patch.rs
index 8e2a3b1a3..20a82b32d 100644
--- a/tests/testsuite/patch.rs
+++ b/tests/testsuite/patch.rs
@@ -2012,3 +2012,66 @@ fn can_update_with_alt_reg() {
)
.run();
}
+
+#[cargo_test]
+fn use_for_new_registry_dependencies() {
+ Package::new("dep1", "0.1.0").dep("bar", "0.1").publish();
+ Package::new("bar", "0.1.0").publish();
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [dependencies]
+ dep1 = "0.1"
+
+ [patch.crates-io]
+ bar = { path = "bar" }
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
+ .file("bar/src/lib.rs", "")
+ .file(
+ "dep2/Cargo.toml",
+ r#"
+ [package]
+ name = "dep2"
+ version = "0.1.0"
+
+ [dependencies]
+ bar = "0.1"
+ "#,
+ )
+ .file("dep2/src/lib.rs", "")
+ .build();
+
+ p.cargo("check").run();
+ p.change_file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [dependencies]
+ dep1 = "0.1"
+ dep2 = { path = 'dep2' }
+
+ [patch.crates-io]
+ bar = { path = "bar" }
+ "#,
+ );
+ p.cargo("check")
+ .with_stderr(
+ "\
+[CHECKING] dep2 [..]
+[CHECKING] foo [..]
+[FINISHED] [..]
+",
+ )
+ .run();
+}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment