Fix disagreement about lockfile ordering on stable/nightly

This commit fixes an issue where the order of packages serialized into a
lock file differs on stable vs nightly. This is due to a bug introduced
in #9133 where a manual `Ord` implementation was replaced with a
`#[derive]`'d one. This was an unintended consequence of #9133 and means
that the same lock file produced by two different versions of Cargo only
differs in what order items are serialized.

With #9133 being reverted soon on the current beta channel this is
intended to be the nightly fix for #9334. This will hopefully mean that
those projects which don't build with beta/nightly will remain
unaffected, and those affected on beta/nightly will need to switch to
the new nightly ordering when it's published (which matches the current
stable). The reverted beta will match this ordering as well.

Closes #9334
This commit is contained in:
Alex Crichton 2021-04-20 13:23:06 -07:00
parent eb5476bd13
commit eb6e1b34a4
2 changed files with 77 additions and 2 deletions

View File

@ -44,8 +44,9 @@ struct SourceIdInner {
/// source. /// source.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
enum SourceKind { enum SourceKind {
/// A git repository. // Note that the ordering here is important for how it affects the `Ord`
Git(GitReference), // implementation, notably how this affects the ordering of serialized
// packages into lock files.
/// A local path.. /// A local path..
Path, Path,
/// A remote registry. /// A remote registry.
@ -54,6 +55,8 @@ enum SourceKind {
LocalRegistry, LocalRegistry,
/// A directory-based registry. /// A directory-based registry.
Directory, Directory,
/// A git repository.
Git(GitReference),
} }
/// Information to find a specific commit in a Git repository. /// Information to find a specific commit in a Git repository.

View File

@ -771,3 +771,75 @@ dependencies = [
p.cargo("build --locked").run(); p.cargo("build --locked").run();
} }
#[cargo_test]
fn same_name_version_different_sources() {
let cksum = Package::new("foo", "0.1.0").publish();
let (git_project, repo) = git::new_repo("dep1", |project| {
project
.file(
"Cargo.toml",
r#"
[project]
name = "foo"
version = "0.1.0"
"#,
)
.file("src/lib.rs", "")
});
let head_id = repo.head().unwrap().target().unwrap();
// Lockfile was generated with Rust 1.51
let lockfile = format!(
r#"# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "foo"
version = "0.1.0"
dependencies = [
"foo 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"foo 0.1.0 (git+{url})",
]
[[package]]
name = "foo"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "{cksum}"
[[package]]
name = "foo"
version = "0.1.0"
source = "git+{url}#{sha}"
"#,
sha = head_id,
url = git_project.url(),
cksum = cksum
);
let p = project()
.file(
"Cargo.toml",
&format!(
r#"
[project]
name = "foo"
version = "0.1.0"
[dependencies]
foo = "0.1.0"
foo2 = {{ git = '{}', package = 'foo' }}
"#,
git_project.url(),
),
)
.file("src/lib.rs", "")
.file("Cargo.lock", &lockfile)
.build();
p.cargo("build").run();
assert_eq!(p.read_file("Cargo.lock"), lockfile);
}