diff --git a/src/cargo/core/registry.rs b/src/cargo/core/registry.rs index 451efcb57e6..6747720a5d5 100644 --- a/src/cargo/core/registry.rs +++ b/src/cargo/core/registry.rs @@ -573,18 +573,22 @@ fn lock(locked: &LockedMap, patches: &HashMap>, summary: Sum } } - // If this dependency did not have a locked version, then we query + // Querying a git dependency has the side effect of pulling changes. + // So even the conservative re-resolution may be to aggressive. + // If this git 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. - let v = locked - .get(dep.source_id()) - .and_then(|map| map.get(&*dep.name())) - .and_then(|vec| vec.iter().find(|&&(ref id, _)| dep.matches_id(id))); - if let Some(&(ref id, _)) = v { - trace!("\tsecond hit on {}", id); - let mut dep = dep.clone(); - dep.lock_to(id); - return dep; + if dep.source_id().git_reference().is_some() { + let v = locked + .get(dep.source_id()) + .and_then(|map| map.get(&*dep.name())) + .and_then(|vec| vec.iter().find(|&&(ref id, _)| dep.matches_id(id))); + if let Some(&(ref id, _)) = v { + trace!("\tsecond hit on {}", id); + let mut dep = dep.clone(); + dep.lock_to(id); + return dep; + } } // Finally we check to see if any registered patches correspond to diff --git a/tests/testsuite/path.rs b/tests/testsuite/path.rs index e7ea0f024b0..43bba365a45 100644 --- a/tests/testsuite/path.rs +++ b/tests/testsuite/path.rs @@ -765,18 +765,19 @@ fn override_self() { let p = project("foo"); let root = p.root().clone(); - let p = p.file( - ".cargo/config", - &format!( - r#" - paths = ['{}'] - "#, - root.display() - ), - ).file( - "Cargo.toml", + let p = + p.file( + ".cargo/config", &format!( r#" + paths = ['{}'] + "#, + root.display() + ), + ).file( + "Cargo.toml", + &format!( + r#" [package] name = "foo" @@ -787,12 +788,12 @@ fn override_self() { path = '{}' "#, - bar.root().display() - ), - ) - .file("src/lib.rs", "") - .file("src/main.rs", "fn main() {}") - .build(); + bar.root().display() + ), + ) + .file("src/lib.rs", "") + .file("src/main.rs", "fn main() {}") + .build(); assert_that(p.cargo("build"), execs().with_status(0)); } @@ -1177,6 +1178,75 @@ Caused by: ); } +#[test] +fn cargo_update_downgrade_dependencies() { + // https://github.com/rust-lang/cargo/issues/5529 + + Package::new("x", "1.0.3").publish(); + Package::new("x", "1.0.2").publish(); + Package::new("x", "1.0.1").publish(); + Package::new("x", "1.0.0").publish(); + Package::new("x", "0.9.1").publish(); + Package::new("x", "0.9.0").publish(); + + let p = project("foo") + .file( + "Cargo.toml", + r#" + [workspace] + members = ["a", "b", "c"] + "#, + ) + .file("a/src/lib.rs", "") + .file( + "a/Cargo.toml", + r#" + [package] + name = "a" + version = "0.1.0" + + [dependencies] + x="0.9" + "#, + ) + .file("b/src/lib.rs", "") + .file( + "b/Cargo.toml", + r#" + [package] + name = "b" + version = "0.1.0" + + [dependencies] + x=">= 0.9, < 2.0" + "#, + ) + .file("c/src/lib.rs", "") + .file( + "c/Cargo.toml", + r#" + [package] + name = "c" + version = "0.1.0" + + [dependencies] + x="1.0" + "#, + ) + .build(); + + // Generate a lock file + assert_that(p.cargo("generate-lockfile"), execs().with_status(0)); + + let good_lock = fs::read_to_string(&p.root().join("Cargo.lock")).unwrap(); + + assert_that(p.cargo("update -p c"), execs().with_status(0)); + + let new_lock = fs::read_to_string(&p.root().join("Cargo.lock")).unwrap(); + + assert_eq!(good_lock, new_lock); +} + #[test] fn invalid_path_dep_in_workspace_with_lockfile() { Package::new("bar", "1.0.0").publish();