Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cargo downgrades transitive dependency that should not change #14446

Open
konstin opened this issue Aug 23, 2024 · 3 comments · May be fixed by #14582
Open

Cargo downgrades transitive dependency that should not change #14446

konstin opened this issue Aug 23, 2024 · 3 comments · May be fixed by #14582
Labels
A-dependency-resolution Area: dependency resolution and the resolver A-git Area: anything dealing with git C-bug Category: bug S-triage Status: This issue is waiting on initial triage.

Comments

@konstin
Copy link
Contributor

konstin commented Aug 23, 2024

Problem

Our project, uv, depends on a git version of pubgrub. pubgrub depends on rustc-hash = ">=1.0.0, <3.0.0". uv has dependencies with both rustc-hash 1 and rustc-hash 2. At 6bd677d60d15ab950ae5466197cab4f3f2405bf4, Cargo.lock in uv has:

[[package]]
name = "pubgrub"
version = "0.2.1"
source = "git+https://github.com/astral-sh/pubgrub?rev=aaef464c1b0d8eea4ff9ffaee4f3458c236d10da#aaef464c1b0d8eea4ff9ffaee4f3458c236d10da"
dependencies = [
 "indexmap",
 "log",
 "priority-queue",
 "rustc-hash 2.0.0",
 "thiserror",
]

Each time i bump the pubgrub revision in Cargo.toml, cargo downgrades the rustc version, even though pubgrub's dependencies didn't change:

[[package]]
name = "pubgrub"
version = "0.2.1"
source = "git+https://github.com/astral-sh/pubgrub?rev=388685a8711092971930986644cfed152d1a1f6c#388685a8711092971930986644cfed152d1a1f6c"
dependencies = [
 "indexmap",
 "log",
 "priority-queue",
 "rustc-hash 1.1.0",
 "thiserror",
]

The only way to fix this is running cargo update -p rustc-hash@1.1.0 manually after each pubgrub update.

Steps

  • git clone https://github.com/astral-sh/uv && cd uv && git checkout 6bd677d60d15ab950ae5466197cab4f3f2405bf4
  • Update the git revision in Cargo.toml, e.g. to 388685a8711092971930986644cfed152d1a1f6c
  • Update the lockfile, e.g. cargo check
  • git diff:
diff --git a/Cargo.lock b/Cargo.lock
index d90529ebcf5e..15f283c3788c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2777,12 +2777,12 @@ dependencies = [
 [[package]]
 name = "pubgrub"
 version = "0.2.1"
-source = "git+https://github.com/astral-sh/pubgrub?rev=aaef464c1b0d8eea4ff9ffaee4f3458c236d10da#aaef464c1b0d8eea4ff9ffaee4f3458c236d10da"
+source = "git+https://github.com/astral-sh/pubgrub?rev=388685a8711092971930986644cfed152d1a1f6c#388685a8711092971930986644cfed152d1a1f6c"
 dependencies = [
  "indexmap",
  "log",
  "priority-queue",
- "rustc-hash 2.0.0",
+ "rustc-hash 1.1.0",
  "thiserror",
 ]
 
diff --git a/Cargo.toml b/Cargo.toml
index 94a65c8d0168..933484fe9740 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -112,7 +112,7 @@ pathdiff = { version = "0.2.1" }
 petgraph = { version = "0.6.4" }
 platform-info = { version = "2.0.2" }
 proc-macro2 = { version = "1.0.86" }
-pubgrub = { git = "https://github.com/astral-sh/pubgrub", rev = "aaef464c1b0d8eea4ff9ffaee4f3458c236d10da" }
+pubgrub = { git = "https://github.com/astral-sh/pubgrub", rev = "388685a8711092971930986644cfed152d1a1f6c" }
 pyo3 = { version = "0.21.0" }
 pyo3-log = { version = "0.10.0" }
 quote = { version = "1.0.36" }

Possible Solution(s)

During version resolution, cargo should use the version previously used for the package as preference, not another version in the lockfile, or if it has to use a version from the lockfile, it should use the higher version.

Notes

No response

Version

cargo 1.80.1 (376290515 2024-07-16)
release: 1.80.1
commit-hash: 37629051518c3df9ac2c1744589362a02ecafa99
commit-date: 2024-07-16
host: x86_64-unknown-linux-gnu
libgit2: 1.7.2 (sys:0.18.3 vendored)
libcurl: 8.6.0-DEV (sys:0.4.72+curl-8.6.0 vendored ssl:OpenSSL/1.1.1w)
ssl: OpenSSL 1.1.1w  11 Sep 2023
os: Ubuntu 24.4.0 (noble) [64-bit]
@konstin konstin added C-bug Category: bug S-triage Status: This issue is waiting on initial triage. labels Aug 23, 2024
@weihanglo
Copy link
Member

weihanglo commented Aug 23, 2024

Haven't checked what is wrong, but here is the minimal repo in Cargo-flavored test code:

#[cargo_test]
fn git_downgrade_with_duplicate_packages() {
    Package::new("rustc-hash", "1.1.0").publish();
    Package::new("rustc-hash", "2.0.0").publish();
    let (git_project, repo) = git::new_repo("pubgrub", |project| {
        project
            .file(
                "Cargo.toml",
                r#"
                    [package]
                    name = "pubgrub"
                    edition = "2021"

                    [dependencies]
                    rustc-hash = ">=1.0.0, <3.0.0"
                "#,
            )
            .file("src/lib.rs", "")
    });
    let rev1 = repo.revparse_single("HEAD").unwrap().id();
    let p = project()
        .file(
            "Cargo.toml",
            &format!(
                r#"
                    [package]
                    name = "foo"

                    [dependencies]
                    rustc-hash1 = {{ version = "1", package = "rustc-hash" }}
                    rustc-hash2 = {{ version = "2", package = "rustc-hash" }}
                    pubgrub = {{ git = "{}", rev = "{rev1}" }}
                "#,
                git_project.url(),
            ),
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("fetch").run();

    assert_e2e().eq(p.read_lockfile(), str![[r##"
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3

[[package]]
name = "foo"
version = "0.0.0"
dependencies = [
 "pubgrub",
 "rustc-hash 1.1.0",
 "rustc-hash 2.0.0",
]

[[package]]
name = "pubgrub"
version = "0.0.0"
source = "git+[ROOTURL]/pubgrub?rev=de416b2ad7717e09e79a34de70330a07c8b9a0fb#de416b2ad7717e09e79a34de70330a07c8b9a0fb"
dependencies = [
 "rustc-hash 2.0.0",
]

[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1981f6ee594df09828a9d95ce56ebac0ee354f40d684bec2f14bd3f4e54356a3"

[[package]]
name = "rustc-hash"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bff208de0b08da920f89e127a4a0f70d2053783efc65d9e398907d1e127cda41"

"##]]);

    git_project.change_file("src/lib.rs", "pub fn hello()");
    git::add(&repo);
    let rev2 = git::commit(&repo);

    p.change_file(
        "Cargo.toml",
        &format!(
            r#"
                [package]
                name = "foo"

                [dependencies]
                rustc-hash1 = {{ version = "1", package = "rustc-hash" }}
                rustc-hash2 = {{ version = "2", package = "rustc-hash" }}
                pubgrub = {{ git = "{}", rev = "{rev2}" }}
            "#,
            git_project.url(),
        ),
    );

    p.cargo("fetch").run();

    assert_e2e().eq(p.read_lockfile(), str![[r##"
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3

[[package]]
name = "foo"
version = "0.0.0"
dependencies = [
 "pubgrub",
 "rustc-hash 1.1.0",
 "rustc-hash 2.0.0",
]

[[package]]
name = "pubgrub"
version = "0.0.0"
source = "git+[ROOTURL]/pubgrub?rev=b5883bacc43c4055a9b1261f77f0c4dd9c2ceae3#b5883bacc43c4055a9b1261f77f0c4dd9c2ceae3"
dependencies = [
 "rustc-hash 1.1.0",
]

[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1981f6ee594df09828a9d95ce56ebac0ee354f40d684bec2f14bd3f4e54356a3"

[[package]]
name = "rustc-hash"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bff208de0b08da920f89e127a4a0f70d2053783efc65d9e398907d1e127cda41"

"##]]);
}

This seems to only happen with Git dependencies. Editing a registry dependency with a wide version requirement doesn't have the same buggy behavior.

@weihanglo weihanglo added A-git Area: anything dealing with git A-dependency-resolution Area: dependency resolution and the resolver labels Aug 23, 2024
@ehuss
Copy link
Contributor

ehuss commented Aug 23, 2024

I suspect this is similar to #5529. I don't remember the explanation why when there is a dependency range across multiple major semver versions that the resolver tends to downgrade to older versions.

@epage
Copy link
Contributor

epage commented Aug 23, 2024

I suspect this is related to #14115.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-dependency-resolution Area: dependency resolution and the resolver A-git Area: anything dealing with git C-bug Category: bug S-triage Status: This issue is waiting on initial triage.
Projects
None yet
4 participants