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

Major wildcards in sub-dependencies result in unnecessary duplicate dependencies #13534

Closed
Nikita240 opened this issue Mar 5, 2024 · 2 comments
Labels
A-dependency-resolution Area: dependency resolution and the resolver C-bug Category: bug S-triage Status: This issue is waiting on initial triage.

Comments

@Nikita240
Copy link

Nikita240 commented Mar 5, 2024

Problem

When depending on a crate that specifies a major version wildcard (0.* or *), or a major version range (>0.1,<0.10 or >0, <10) for a dependency foo, if your root crate also has a dependency on foo, cargo will resolve duplicate dependencies when there are clear solutions with a single dependency (unless your root is just as loose on the requirement or the major version happens to match the maximum specified in the dependency crate).

How this surfaced

This problem has never surfaced before because crates.io does not allow crates with major-wildcards to be pushed. Now with the advent of private registries, we have a new wild west with no rules, allowing this problem to present itself.

Why would you possibly want to use a major-wildcard??? 🤯

Well, the problem also applies to major-ranges too! It's quite possible for a crate to use only a very limited surface of an API from another crate and want to provide it to the user. A surface so small that you can guarantee that it works across SemVer incompatible versions of a crate.

An example: Say you want to provide a bevy_ecs feature on your crate, which simply adds #[derive(Component)] annotations to some of your structs. You can very easily test and assert that such a feature is compatible with bevy_ecs = ">0.1,<=0.13". And while this may be not kosher on crates.io, on private registries this can totally be okay.

Steps

Here is a failing test that you can plug into resolver-tests:

#[test]
fn test_wildcard_major() {
    let reg = registry(vec![
        pkg!("foo" => [dep_req("util", "0.*")]),
        pkg!(("util", "0.1.0")),
        pkg!(("util", "0.2.0")),
    ]);

    let res = resolve_and_validated(
        vec![dep_req("foo", "1.0.0"), dep_req("util", "=0.1.0")],
        &reg,
        None,
    )
    .unwrap();

    assert_same(
        &res,
        &names(&[("root", "1.0.0"), ("foo", "1.0.0"), ("util", "0.1.0")]),
    );
}

The current implementation will return a duplicate util:

    assert_same(
        &res,
        &names(&[("root", "1.0.0"), ("foo", "1.0.0"), ("util", "0.1.0"), ("util", "0.2.0")]),
    );

Possible Solution(s)

Proposed fix: #13535

Notes

No response

Version

cargo 1.76.0 (c84b36747 2024-01-18)
release: 1.76.0
commit-hash: c84b367471a2db61d2c2c6aab605b14130b8a31b
commit-date: 2024-01-18
host: x86_64-unknown-linux-gnu
libgit2: 1.7.1 (sys:0.18.1 vendored)
libcurl: 8.5.0-DEV (sys:0.4.70+curl-8.5.0 vendored ssl:OpenSSL/1.1.1w)
ssl: OpenSSL 1.1.1w  11 Sep 2023
os: Ubuntu 20.04 (focal) [64-bit]
@Nikita240 Nikita240 added C-bug Category: bug S-triage Status: This issue is waiting on initial triage. labels Mar 5, 2024
@epage epage added the A-dependency-resolution Area: dependency resolution and the resolver label Mar 5, 2024
@epage
Copy link
Contributor

epage commented Mar 5, 2024

Is this a duplicate of #9029?

@Nikita240
Copy link
Author

Is this a duplicate of #9029?

Yep, seems like it

@Nikita240 Nikita240 closed this as not planned Won't fix, can't repro, duplicate, stale Mar 5, 2024
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 C-bug Category: bug S-triage Status: This issue is waiting on initial triage.
Projects
None yet
Development

No branches or pull requests

2 participants