Skip to content

Provide a way to describe why newer versions are not selected #7929

Open

Description

@ehuss

Describe the problem you are trying to solve
Sometimes it can be confusing why newer versions of a package are not selected by the resolver. It would be nice to have some way for Cargo to tell you that there is a newer version available, but it is not able to select it due to some requirement.

There are different reasons this can happen. Some I can think of:

  • Multiple version constraints of different styles. For example one package has "1.0.*", and another has "^1.0".
  • Features were removed in an otherwise semver-compatible release. Packages probably shouldn't do that, but it can still be silently confusing. See cargo update should print warnings for incompatible candidates #7167 for more details.
  • Cargo fails to parse the newer version index entry.
  • Newer version is yanked.
  • New links collision (I think?)

This is in spirit with #6199 and #5284, but this is not for errors but for when otherwise compatible versions are skipped.

Describe the solution you'd like
I'm not sure of the best way to convey this information. Maybe cargo update -v could include a detailed message? Or maybe make it part of CARGO_LOG? Or something else?

It could say something like:

info: a newer version of package `bar` is available, 
but it is unable to be selected due to restricted requirements
  `bar` 1.1.0 is available, but
    `somedep`'s requirement `^1.0` selected older version `1.0.0` because
    `restrictor` has the requirement `1.0.*` which prevents the newer version from being selected    

Example
Some examples using Cargo's test notation:

#[cargo_test]
fn describe_restricted_dep() {
    // Example showing a newer version not selected due to an unrelated
    // package's over-restrictive requirements.
    Package::new("dep", "1.0.0").publish();
    Package::new("dep", "1.1.0").publish();
    Package::new("restrictor", "1.0.0")
        .dep("dep", "1.0.*")
        .publish();

    let p = project()
        .file(
            "Cargo.toml",
            r#"
            [package]
            name = "foo"
            version = "1.0.0"

            [dependencies]
            restrictor = "1.0"
            dep = "1.0"
            "#,
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("update -v").with_stderr("[UPDATING] [..]").run();
}

#[cargo_test]
fn describe_misfeatured_dep() {
    // Example showing a newer version not selected due to missing features.
    Package::new("dep", "1.0.0").feature("f1", &[]).publish();
    Package::new("dep", "1.0.1").publish();

    let p = project()
        .file(
            "Cargo.toml",
            r#"
            [package]
            name = "foo"
            version = "1.0.0"

            [dependencies]
            dep = { version = "1.0", features = ["f1"] }
            "#,
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("update -v").with_stderr("[UPDATING] [..]").run();
}

Activity

  1. added
    C-feature-requestCategory: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted`
    on Feb 25, 2020
  2. epage commented on Oct 31, 2023

    @epage
    Contributor

    #6666 also asked for this (among other things) but it was closed for #12903 which at least tells people how to enable logging to get the details they want. If we can directly tell them, that'd be great. I worry anything we try will be a lot of work and will be information overload, making it not much better than the logging solution.

  3. added
    S-needs-team-inputStatus: Needs input from team on whether/how to proceed.
    S-triageStatus: This issue is waiting on initial triage.
    S-needs-designStatus: Needs someone to work further on the design for the feature or fix. NOT YET accepted.
    and removed
    S-needs-team-inputStatus: Needs input from team on whether/how to proceed.
    S-triageStatus: This issue is waiting on initial triage.
    S-needs-designStatus: Needs someone to work further on the design for the feature or fix. NOT YET accepted.
    on Oct 31, 2023
  4. added
    S-needs-designStatus: Needs someone to work further on the design for the feature or fix. NOT YET accepted.
    and removed
    S-needs-team-inputStatus: Needs input from team on whether/how to proceed.
    on Dec 2, 2024
  5. epage commented on Jan 13, 2025

    @epage
    Contributor

    With the MSRV work, we added hints to cargo updates output about some version constraints but

    • It is a guess as this is done after dependency resolution
    • It is limited in what it says for space purposes
    • It is incomplete, not covering every case

    As for bad index entries, we've now made those accessible to report them on failed resolutions. It just requires an extra query or two.

  6. djugei commented on Jun 18, 2025

    @djugei

    i have just hit this issue where i wanted to cargo update my dependencies (version = "*") and one did not update with no clear indication as to why. setting version = "" then revealed that a feature had been renamed .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-dependency-resolutionArea: dependency resolution and the resolverC-feature-requestCategory: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted`S-needs-designStatus: Needs someone to work further on the design for the feature or fix. NOT YET accepted.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions