Skip to content

Unavoidable Cargo.lock package collision occurs if path dependencies share same name and version #10353

Closed as duplicate of#8639
@jagunter

Description

@jagunter

Problem

If you find yourself with dependencies on two packages with the same name, you can normally include dependencies on both by renaming the dependencies. However, if these packages are included via path dependencies and both have the same version, then cargo generate-lockfile will fail with a package collision error. This occurs even when the dependencies are renamed to avoid collision.

Steps

  1. cargo init /tmp/foo
  2. cargo init --lib /tmp/foo/dir1/pkg
  3. cargo init --lib /tmp/foo/dir2/pkg
  4. Update Cargo.toml in foo to include both pkg crates as dependencies, renaming to avoid conflict
[package]
name = "foo"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
pkg1 = { path = "dir1/pkg", package = "pkg" }
pkg2 = { path = "dir2/pkg", package = "pkg" }
  1. Run cargo generate-lockfile in foo and observe package collision despite rename.
error: package collision in the lockfile: packages pkg v0.1.0 (/tmp/foo/dir1/pkg) and pkg v0.1.0 (/tmp/foo/dir2/pkg) are different, but only one can be written to lockfile unambiguously

Possible Solution(s)

It appears the Cargo.lock file only tracks the package name and version for path dependencies. For other dependencies, additional information appears to be included. For example, with a git dependency mixed with a crates.io dependency:

[dependencies]
libc = { version = "0.2.116" }
libc2 = { git = "https://github.com/rust-lang/libc.git", package = "libc" }

the dependencies in foo are distinguished by their source in the Cargo.lock file:

version = 3

[[package]]
name = "foo"
version = "0.1.0"
dependencies = [
 "libc 0.2.116 (registry+https://github.com/rust-lang/crates.io-index)",
 "libc 0.2.116 (git+https://github.com/rust-lang/libc.git)",
]

[[package]]
name = "libc"
version = "0.2.116"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "565dbd88872dbe4cc8a46e527f26483c1d1f7afa6b884a3bd6cd893d4f98da74"

[[package]]
name = "libc"
version = "0.2.116"
source = "git+https://github.com/rust-lang/libc.git#2dc7cfe3f5e0f8b8fa92e73cde7f06c85a754de4"

Inclusion of a source for path dependencies could help differentiate in the that case.

Notes

If the version is changed for one of the pkg crates to a different version than the other, then the lock file is generated successfully:

# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3

[[package]]
name = "foo"
version = "0.1.0"
dependencies = [
 "pkg 0.1.0",
 "pkg 0.2.0",
]

[[package]]
name = "pkg"
version = "0.1.0"

[[package]]
name = "pkg"
version = "0.2.0"

Version

cargo 1.60.0-nightly (95bb3c92b 2022-01-18)
release: 1.60.0-nightly
commit-hash: 95bb3c92bf516017e812e7f1c14c2dea3845b30e
commit-date: 2022-01-18
host: x86_64-unknown-linux-gnu
libgit2: 1.3.0 (sys:0.13.23 vendored)
libcurl: 7.80.0-DEV (sys:0.4.51+curl-7.80.0 vendored ssl:OpenSSL/1.1.1l)
os: Ubuntu 18.04 (bionic) [64-bit]

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lockfileArea: Cargo.lock issuesS-needs-team-inputStatus: Needs input from team on whether/how to proceed.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions