# Is it really a good idea for Cargo to silently choose out-of-date versions of crates to avoid pulling in multiple compatible versions of another crate?

**URL:** <https://internals.rust-lang.org/t/is-it-really-a-good-idea-for-cargo-to-silently-choose-out-of-date-versions-of-crates-to-avoid-pulling-in-multiple-compatible-versions-of-another-crate/15490>\
**Category:** cargo\
**Created:** [October 23, 2021, 3:51am UTC](https://internals.rust-lang.org/t/is-it-really-a-good-idea-for-cargo-to-silently-choose-out-of-date-versions-of-crates-to-avoid-pulling-in-multiple-compatible-versions-of-another-crate/15490 "2021-10-23T03:51:18Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![autumnontape](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/autumnontape/32/9689_2.png) [@autumnontape](https://internals.rust-lang.org/u/autumnontape)\
**Post date:** [October 23, 2021, 3:51am UTC](https://internals.rust-lang.org/t/is-it-really-a-good-idea-for-cargo-to-silently-choose-out-of-date-versions-of-crates-to-avoid-pulling-in-multiple-compatible-versions-of-another-crate/15490/1 "2021-10-23T03:51:18Z")

</div>

I ran `cargo audit` in a project of mine today to discover that my Cargo.lock included version 0.22.0 of the nix crate, which has a memory corruption vulnerability ([RUSTSEC-2021-0119](https://rustsec.org/advisories/RUSTSEC-2021-0119)). This was strange, because a fix had been published in nix version 0.22.2 for almost a month; I'd run `cargo update` recently; and rustyline 9.0.0, the dependency that was pulling nix in, specified it as `nix = "0.22"`, not `nix = "=0.22.0"`.

It took me a while to figure out what was going on. An empty crate with only `rustyline = "9.0"` in its dependencies got nix 0.22.2, but I eventually found that if bitflags \>= 1.3.0 ended up somewhere in the dependency graph, nix got downgraded to 0.22.0.

[nix 0.22.0 had a dependency `bitflags = "1.1"`, and bitflags 1.3.0 broke compatibility with certain old versions of rustc that nix aimed to support, so the author added a "\< 1.3.0" version bound to bitflags in nix 0.22.1.](https://github.com/nix-rust/nix/issues/1491) Cargo therefore seems to see that if bitflags 1.3.x and nix 0.22.x are both needed, the only way to avoid pulling in a version of bitflags in the 1.1 to 1.2 range alongside one in the bitflags 1.3 range is to use the broken nix 0.22.0. It's clever, but it leads to a vulnerable version of nix being silently chosen.

I don't necessarily have solutions, and I'm not affected by the vulnerability, I just thought it might be wise to bring this case to the attention of the people who work on Cargo. A warning would be nice, and I wouldn't consider an error unreasonable here if the "no multiple versions of a crate within the same compatibility range" rule is non-negotiable. Cargo automatically downgrading crates to potentially buggy versions due to distant interactions with other crates just doesn't seem right to me.

---

<div class="post-metadata">

**Author:** ![ethindp](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ethindp/32/7505_2.png) [@ethindp](https://internals.rust-lang.org/u/ethindp)\
**Post date:** [October 23, 2021, 4:23am UTC](https://internals.rust-lang.org/t/is-it-really-a-good-idea-for-cargo-to-silently-choose-out-of-date-versions-of-crates-to-avoid-pulling-in-multiple-compatible-versions-of-another-crate/15490/2 "2021-10-23T04:23:24Z")

</div>

I agree with this. I would prefer to know when vulnerable or potentially buggy code is being inserted into my dependency graph because some version specification forced Cargo to do so. I'd even go so far as to make a Cargo.toml option that tells Cargo that if it encounters a situation like that it errors out and refuses to proceed until its resolved.

---

<div class="post-metadata">

**Author:** ![schungx](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/schungx/32/5926_2.png) [@schungx](https://internals.rust-lang.org/u/schungx)\
**Post date:** [October 23, 2021, 7:32am UTC](https://internals.rust-lang.org/t/is-it-really-a-good-idea-for-cargo-to-silently-choose-out-of-date-versions-of-crates-to-avoid-pulling-in-multiple-compatible-versions-of-another-crate/15490/3 "2021-10-23T07:32:30Z")

</div>

Can't you `nix = "0.22.1"`?

Since you're depending on the bug fix in `0.22.1`...

---

<div class="post-metadata">

**Author:** ![autumnontape](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/autumnontape/32/9689_2.png) [@autumnontape](https://internals.rust-lang.org/u/autumnontape)\
**Post date:** [October 23, 2021, 8:21am UTC](https://internals.rust-lang.org/t/is-it-really-a-good-idea-for-cargo-to-silently-choose-out-of-date-versions-of-crates-to-avoid-pulling-in-multiple-compatible-versions-of-another-crate/15490/4 "2021-10-23T08:21:28Z")

</div>

The bugfix is in 0.22.2. And depending on it explicitly just causes an error, for the same reason Cargo passes over 0.22.1 and 0.22.2 normally: its version requirements for bitflags conflict with `bitflags = "1.3"`.

Here's the error:

```nohighlight
    Updating crates.io index
error: failed to select a version for `bitflags`.
    ... required by package `nix v0.22.2`
    ... which satisfies dependency `nix = "^0.22.2"` of package `xyz v0.1.0 (/tmp/xyz)`
versions that meet the requirements `>=1.1.0, <1.3.0` are: 1.2.1, 1.2.0, 1.1.0

all possible versions conflict with previously selected packages.

  previously selected package `bitflags v1.3.1`
    ... which satisfies dependency `bitflags = "^1.3"` of package `xyz v0.1.0 (/tmp/xyz)`

failed to select a version for `bitflags` which could resolve this conflict

```

---

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matklad/32/12266_2.png) [@matklad](https://internals.rust-lang.org/u/matklad)\
**Post date:** [October 23, 2021, 8:53am UTC](https://internals.rust-lang.org/t/is-it-really-a-good-idea-for-cargo-to-silently-choose-out-of-date-versions-of-crates-to-avoid-pulling-in-multiple-compatible-versions-of-another-crate/15490/5 "2021-10-23T08:53:14Z")

</div>

I’d say there are two different root problems here.

First, cargo didn’t have first-class Minimal Supported Rust Version support. It has some of it now, so hopefully in the future Cargo would just handle all MSRV best practices automatically.

Second, cargo doesn’t warn on publish for non-default dependency specifications. Basically, if you publish a crate with `=` or `<` dependencies, you are adding very subtle problems downstream, but nothing signals about that. The problem here is that there are subtle cases where you _do_ want at least `=`, and it’s hard to automatically figure out if unusual dependency specification is used correctly.

In this specific case, `nix` library shouldn’t be adding `<` constraint to pin bitflags to older MSRV. Instead, the response to the issue should be “pin bitflags to older version in your end application _lockfile_ with `cargo update -p bitflags —precise`”. That way, people who use latest rustc could use latest bitflags and latest nix, and people who need older rustc can use it with latest nix and older bitflags. It also correctly puts maintainance burden to the party who needs old rust version.

---

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matklad/32/12266_2.png) [@matklad](https://internals.rust-lang.org/u/matklad)\
**Post date:** [October 23, 2021, 9:05am UTC](https://internals.rust-lang.org/t/is-it-really-a-good-idea-for-cargo-to-silently-choose-out-of-date-versions-of-crates-to-avoid-pulling-in-multiple-compatible-versions-of-another-crate/15490/6 "2021-10-23T09:05:02Z")

</div>

Tangential, but I just realized I can now formulate the core of MSRV debate:

MSRV of X for _library_ means that there **exists** a set of packages which satisfies constrains in Cargo.toml, and which can be compiled with X version of Rust.

MSRV of X doesn’t mean that **for all** sets of packages that satisfies constraints, that set can be compiled with X.

“Exists” formulation is more useful, as it gives more choices to the end application with a lockfile.

---

<div class="post-metadata">

**Author:** ![autumnontape](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/autumnontape/32/9689_2.png) [@autumnontape](https://internals.rust-lang.org/u/autumnontape)\
**Post date:** [October 23, 2021, 9:08am UTC](https://internals.rust-lang.org/t/is-it-really-a-good-idea-for-cargo-to-silently-choose-out-of-date-versions-of-crates-to-avoid-pulling-in-multiple-compatible-versions-of-another-crate/15490/7 "2021-10-23T09:08:01Z")

</div>

nix's maintainer seems to take a different view of who's responsible for ensuring compatibility with old Rust versions and is solving the problem by [vendoring bitflags into nix](https://github.com/nix-rust/nix/pull/1560) instead of depending on it. Regardless, this sort of situation could happen in any case where the maintainers of two crates with a dependency relation disagree on what changes require a major version bump.

---

<div class="post-metadata">

**Author:** ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)\
**Post date:** [October 23, 2021, 9:38am UTC](https://internals.rust-lang.org/t/is-it-really-a-good-idea-for-cargo-to-silently-choose-out-of-date-versions-of-crates-to-avoid-pulling-in-multiple-compatible-versions-of-another-crate/15490/8 "2021-10-23T09:38:56Z")

</div>

When cargo starts using the pubgrub dependency resolver, we should be able to give better explanations for why dependency resolution selects a specific version.

---

<div class="post-metadata">

**Author:** ![197g](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/197g/32/7276_2.png) [@197g](https://internals.rust-lang.org/u/197g)\
**Post date:** [October 23, 2021, 12:23pm UTC](https://internals.rust-lang.org/t/is-it-really-a-good-idea-for-cargo-to-silently-choose-out-of-date-versions-of-crates-to-avoid-pulling-in-multiple-compatible-versions-of-another-crate/15490/9 "2021-10-23T12:23:11Z")

</div>

> [@autumnontape](#):
>
> [so the author added a "\< 1.3.0" version bound to bitflags in nix 0.22.1.](https://github.com/nix-rust/nix/issues/1491)

Oh no. Indeed I agree with the view that msrv should mean that there _exists_ a set of dependencies. However, they have no power to help their users find that set **except by upper bounding dependencies**. So it's quite understandable that this occurs in practise. I believe we must either ship msrv-aware resolver fast or provide a separate tool to create such a lockfiles and popularize that quickly. Such a tool would also be quite useful for testing in CI pipelines of crates with lower msrv.

---

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matklad/32/12266_2.png) [@matklad](https://internals.rust-lang.org/u/matklad)\
**Post date:** [October 23, 2021, 1:26pm UTC](https://internals.rust-lang.org/t/is-it-really-a-good-idea-for-cargo-to-silently-choose-out-of-date-versions-of-crates-to-avoid-pulling-in-multiple-compatible-versions-of-another-crate/15490/10 "2021-10-23T13:26:56Z")

</div>

FWIW, `cargo +nightly generate-lockfile -Zminimal-versions` gives you that set, provided that you (and your deps) specified minimal versions correctly.

In general, while we don't have super-nice tooling in place here, it certainly isn't an insurmountable task to find lockfile that works for your Rust version -- you can iteratively downgrade dependencies which fail to compile using `cargo update --package dep-name --precise --vers major.minor.patch` until you find the set that works.

Similarly, for testing MSRV on CI you want to have `Cargo.lock.msrv` committed to the repo and substitute that for `Cargo.lock` during MSRV CI ([example](https://github.com/matklad/once_cell/blob/7b2943b3828867a58690165961424230ca423403/xtask/src/main.rs#L51-L56)).

---

<div class="post-metadata">

**Author:** ![197g](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/197g/32/7276_2.png) [@197g](https://internals.rust-lang.org/u/197g)\
**Post date:** [October 23, 2021, 2:26pm UTC](https://internals.rust-lang.org/t/is-it-really-a-good-idea-for-cargo-to-silently-choose-out-of-date-versions-of-crates-to-avoid-pulling-in-multiple-compatible-versions-of-another-crate/15490/11 "2021-10-23T14:26:10Z")

</div>

> [@matklad](#):
>
> In general, while we don't have super-nice tooling in place here, it certainly isn't an insurmountable task to find lockfile that works for your Rust version -- you can iteratively downgrade dependencies which fail to compile using `cargo update --package dep-name --precise --vers major.minor.patch` until you find the set that works.

For deeper dependency trees I highly doubt this approach works efficiently enough. Each compile will take a considerable time itself before even hitting an issue. Consider that your failure might be due to a dependency-of-a-dependency, so downgrading must begin with the leafs but then you can't differentiate between the different kinds of failures. But starting from below you must avoid all 'naturally' broken versions. It's really not an easy task at scale. I think this can easily require some hundreds of compile cycles in pathological cases.

Maybe with `rust-version` it will get us a lot closer but a) it's not _enforced_ so the info can just be wrong and then you run into the same issue b) it will only work with some future version c) it must be present in _all_ dependencies in the whole tree to be effective.

`cargo +nightly generate-lockfile -Zminimal-versions` is as bad as upper bounds, or worse. You don't get _feasible_ security updates. Of course it's maybe a good starting point for an iteration from below but it's _not_ a replacement for actual version selection based on msrv. But no sane crate author today publishes updates that only bump the minimal compatible version so this will give a strictly worse set of dependencies than an upper bound. And it's still not msrv aware.

---

<div class="post-metadata">

**Author:** ![eminence](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/eminence/32/4018_2.png) [@eminence](https://internals.rust-lang.org/u/eminence)\
**Post date:** [October 23, 2021, 4:10pm UTC](https://internals.rust-lang.org/t/is-it-really-a-good-idea-for-cargo-to-silently-choose-out-of-date-versions-of-crates-to-avoid-pulling-in-multiple-compatible-versions-of-another-crate/15490/12 "2021-10-23T16:10:39Z")

</div>

> [@matklad](#):
>
> Tangential, but I just realized I can now formulate the core of MSRV debate:
> 
> MSRV of X for _library_ means that there **exists** a set of packages which satisfies constrains in Cargo.toml, and which can be compiled with X version of Rust.

This sounds like a good formulation. To extend this, I think we can say that there is currently no mechanism to formally describe this set of packages. This is where some problems arise, because sometimes people try to use `Cargo.toml` for this.

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [October 23, 2021, 6:27pm UTC](https://internals.rust-lang.org/t/is-it-really-a-good-idea-for-cargo-to-silently-choose-out-of-date-versions-of-crates-to-avoid-pulling-in-multiple-compatible-versions-of-another-crate/15490/13 "2021-10-23T18:27:35Z")

</div>

> [@197g](#):
>
> `cargo +nightly generate-lockfile -Zminimal-versions` is as bad as upper bounds, or worse. You don't get _feasible_ security updates. Of course it's maybe a good starting point for an iteration from below but it's _not_ a replacement for actual version selection based on msrv. But no sane crate author today publishes updates that only bump the minimal compatible version so this will give a strictly worse set of dependencies than an upper bound.

To be quite honest: if the bug fix or security update impacts use of their crate, they should. Because it's then a bugfix/security update for their crate as well.

The problem with this is social; because there's no easy way (nightly `-Z` flag isn't easy) to check your minimal versions specification is correct, it's uncommon for authors to do so. When a dependency isn't minimal versions correct, it makes it quite difficult to actually check your own minimal version correctness.

I run into issues with this surprisingly often! I have an old lockfile, then add either a new dependency or upgrade one of my dependencies, and stuff breaks because I'm using old dependency-of-dependency versions. (I've had this happen with a `cargo upgrade`!) So far I've only had it cause compilation issues, but if unlucky, it could've caused buggy behavior or security issues.

I'm of half a mind to suggest that the `cargo publish` preflight checks should ignore your lockfile and test minimal versions instead, to encourage people to be more minimal versions correct. But because there are major dependencies out there that see minimal version correctness as a non-issue (there's no practical way to run into it with stable tooling, supposedly), actually trying to enforce minimal versions correctness is difficult. (And IIRC this is part of what's blocking stabilization; how useless the resolver is when major dependencies break under the flag.)

---

<div class="post-metadata">

**Author:** ![197g](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/197g/32/7276_2.png) [@197g](https://internals.rust-lang.org/u/197g)\
**Post date:** [October 23, 2021, 6:52pm UTC](https://internals.rust-lang.org/t/is-it-really-a-good-idea-for-cargo-to-silently-choose-out-of-date-versions-of-crates-to-avoid-pulling-in-multiple-compatible-versions-of-another-crate/15490/14 "2021-10-23T18:52:18Z")

</div>

> [@CAD97](#):
>
> To be quite honest: if the bug fix or security update impacts use of their crate, they should. Because it's then a bugfix/security update for their crate as well.

I think we might have to disagree here but as a maintainer I find that just silly. For any largeish crate they would pretty much do nothing but release patch versions bumping dependencies. And do you want any crate, no matter how complete, to release further bumps and bumps? Firstly that's not going to happen in practice and secondly having this expectation would be bind huge numbers of maintainer hours. The job of the `Cargo.toml` is to define compatibilities, the job of the resolver to find the best compatible version. Not the other way around.

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [October 23, 2021, 8:14pm UTC](https://internals.rust-lang.org/t/is-it-really-a-good-idea-for-cargo-to-silently-choose-out-of-date-versions-of-crates-to-avoid-pulling-in-multiple-compatible-versions-of-another-crate/15490/15 "2021-10-23T20:14:24Z")

</div>

Note that a majority of upstream fixes aren't going to impact your use to mean you should force a version bump, though! Most fixes are to edge case behavior; if you don't exercise that edge case, it's not important to your downstream which version of your upstream they're using.

Does the dependency update fix a user-facing bug? Then it's a meaningful update to publish to require the version which fixes the bug. A trivial and automatable update, but a meaningful one.

It doesn't necessarily have to be proactive updates (users get that from `cargo update`, obviously), but what I'm asking boils down to

- your test suite should pass with minimal version resolution, i.e. your `Cargo.toml` specifies sufficient dependency versions for your library to work (at least, assuming your upstream's latest is also minimal-versions correct; patching upstream to fix that is not possible), and
- any issue/bug report/etc fixed by a `cargo update` should be fixed by upgrading your dependency to always fix the issue, not just by telling the user to `cargo update`. (Ideally, a test is added, and the dependency update falls out of the above.)

A maintainer _can_ be more proactive than that, and watch their direct dependencies for updates that might impact use of their library.

`dep = "X.Y.Z"` in your Cargo.toml means you work with version X.Y.Z of dep (and any semver compatible version). All I'm asking is for that promise to actually be true. If your library has a bug when used with the dependency version(s) it says it works with, I consider that a bug worth a bugfix release.

Obviously the best experience will be with the latest improvements in upstream. But you should work with the versions you claim to work with.

---

<div class="post-metadata">

**Author:** ![197g](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/197g/32/7276_2.png) [@197g](https://internals.rust-lang.org/u/197g)\
**Post date:** [October 23, 2021, 9:35pm UTC](https://internals.rust-lang.org/t/is-it-really-a-good-idea-for-cargo-to-silently-choose-out-of-date-versions-of-crates-to-avoid-pulling-in-multiple-compatible-versions-of-another-crate/15490/16 "2021-10-23T21:35:58Z")

</div>

> [@CAD97](#):
>
> It doesn't necessarily have to be proactive updates (users get that from `cargo update` , obviously), but what I'm asking boils down to

I believe you are missing my point and I had misunderstood yours. I tried to understand _why crate authors may choose to add upper bounds_ (i.e. what process failure lead to OPs initial problem). Let me recap my understanding of the discussion:

- matclad suggested that `generate-lockfile -Z minimal-versions` could be used to deliver a set of msrv compatible dependencies 'if you specified minimal versions correctly'.
- I tried to convey that this generates a very different set of dependencies from `cargo update`, and it's not the usual workflow _for users_. I, now, acknowledge it could hopefully be useful for testing the existance of a set (i.e. msrv compliance). But it wasn't related to the point I was trying to make: you _can not_ rely on this as an eventual downstream users and packager because it does not provide the same deep update semantics that cargo's version resolution usually gives. And that it's indeed not easy or trivial to recreate those semantics with msrv constraints through an iterative process.
- You remarked that you could increase the version numbers of dependencies.
- And I think here we missed our points. You _probably_ said this in reference to `-Z minimal-versions` but I did not understand it that way. (Indeed, the library author should fix by publishing a new version). Because I had seen it from the PoV of the workflow of downstream users, it seemed to me like you were arguing that authors should bump their version specs to the most recent stable version downstream so as to help `-Z minimal-versions` do the equivalent of selecting an as-up-to-date-as-possible dependency set.

So, alas, I hope we can agree on two counts:

- We'd like more widespread use of correct minimal depency specification so that there is useful tooling to _test_ the msrv-specification (and this tooling can then _probably_ be provided by `-Z minimal-versions`).
- But the problem of selecting up-to-date dependencies under the constraint of msrv is separate. And `cargo update` is the usual workflow for packagers and other downstream users (even implicitly, as you've observed). And this 'does the wrong thing' \_except if there are upper bounds on dependencies; and since this interferes in the usual work flow of developers, it's tempting to introduce upper bounds; and if you don't know the nightly flag indeed even more so.

---

<div class="post-metadata">

**Author:** ![mathstuf](https://avatars.discourse-cdn.com/v4/letter/m/958977/32.png) [@mathstuf](https://internals.rust-lang.org/u/mathstuf)\
**Post date:** [October 24, 2021, 2:14pm UTC](https://internals.rust-lang.org/t/is-it-really-a-good-idea-for-cargo-to-silently-choose-out-of-date-versions-of-crates-to-avoid-pulling-in-multiple-compatible-versions-of-another-crate/15490/17 "2021-10-24T14:14:35Z")

</div>

> [@CAD97](#):
>
> `dep = "X.Y.Z"` in your Cargo.toml means you work with version X.Y.Z of dep (and any semver compatible version). All I'm asking is for that promise to actually be true. If your library has a bug when used with the dependency version(s) it says it works with, I consider that a bug worth a bugfix release.

Yep. Having done a number of "minvers" PRs to projects (with a lot of hit-or-miss merging nevermind actual deployment), the issues usually arise around the "core" libraries. Small features creeping in from newer libc that isn't properly declared, serde fixes or such, etc. I have a minvers CI pipeline for GitLab on my projects (which are already minvers-supported), but I haven't done one for GitHub Actions yet. Maybe if we could get a template workflow file put together that folks could use to actually _test_ their minvers, there'd be more traction?

---

<div class="post-metadata">

**Author:** ![djc](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/djc/32/1592_2.png) [@djc](https://internals.rust-lang.org/u/djc)\
**Post date:** [October 25, 2021, 11:59am UTC](https://internals.rust-lang.org/t/is-it-really-a-good-idea-for-cargo-to-silently-choose-out-of-date-versions-of-crates-to-avoid-pulling-in-multiple-compatible-versions-of-another-crate/15490/18 "2021-10-25T11:59:00Z")

</div>

> First, cargo didn’t have first-class Minimal Supported Rust Version support. It has some of it now, so hopefully in the future Cargo would just handle all MSRV best practices automatically.

FWIW, post-`rust-version` discussion on incorporating MSRV information in the dependency resolver:

> <https://github.com/rust-lang/cargo/issues/9930>
>
> Based on \[RFC 2495\](https://github.com/rust-lang/rfcs/pull/2495) Rust now suppor…ts the \[\`rust-version\`\](https://doc.rust-lang.org/nightly/cargo/reference/manifest.html#the-rust-version-field) field, which currently works as:
> 
> \>If the currently selected version of the Rust compiler is older than the stated version, cargo will exit with an error, telling the user what version is require
> 
> This behavior is not ideal. If a project depends on crate \`foo v0.1.0\` with MSRV 1.56, then releasing crate \`foo v0.1.1\` with MSRV 1.60 will break build of the project on older toolchains after simple \`cargo update\`. Ideally Cargo would select \`foo v0.1.0\` on older tolchains, thus preventing the breakage.
> 
> RFC 2495 has \[described\](https://github.com/rust-lang/rfcs/blob/master/text/2495-min-rust-version.md#influencing-version-resolution) MSRV-dependent version resolution as a potential future extension. This issue is intended for design discussions and tracking implementation progress of this feature.
> 
> Third-party support
> \- dependabot/dependabot-core#5423
> \- renovatebot/renovate#26060
> 
> \---
> 
> Implementation
> \- \[x\] Prototype (#12560)
> \- \[x\] Switch resolver to "prefer" rather than "enforce" (#12950)
> \- \[x\] De-prioritize dep versions without \`rust-version\` (#13066)
> \- \[x\] Improve the \`cargo install\` error (#12798)
> \- \[x\] \`cargo add\` support (#10653) 
> \- \[x\] Improve documentation around \`rust-version\` (#13056)
> \- \[\] Infer users rust-version from \`rustc -V\`
> \- \[\] Config support
> \- \[\] \`--ignore-rust-version\` support
> \- \[\] Keep user informed when using old versions
> 
> Deferred
> \- Determination for what \`cargo install\` should do, see also #10903

Maybe publishing a library crate with `<` or `=` dependencies should generate a warning from Cargo?

---

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matklad/32/12266_2.png) [@matklad](https://internals.rust-lang.org/u/matklad)\
**Post date:** [October 26, 2021, 10:41am UTC](https://internals.rust-lang.org/t/is-it-really-a-good-idea-for-cargo-to-silently-choose-out-of-date-versions-of-crates-to-avoid-pulling-in-multiple-compatible-versions-of-another-crate/15490/19 "2021-10-26T10:41:04Z")

</div>

> [@djc](#):
>
> Maybe publishing a library crate with `<` or `=` dependencies should generate a warning from Cargo?

See [Lint againt non semver-open dependencies · Issue #5340 · rust-lang/cargo · GitHub](https://github.com/rust-lang/cargo/issues/5340). Seems like a good idea at first, but it's hard to fully get rid of false errors.

---

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [October 26, 2021, 5:51pm UTC](https://internals.rust-lang.org/t/is-it-really-a-good-idea-for-cargo-to-silently-choose-out-of-date-versions-of-crates-to-avoid-pulling-in-multiple-compatible-versions-of-another-crate/15490/20 "2021-10-26T17:51:17Z")

</div>

I think authors who care about using latest versions should specify so, instead of relying on Cargo implicitly upgrading things. `cargo-edit` has `cargo upgrade` command that does it for all deps. I highly recommend it.

`-Zminimal-versions` is unusable, because crate authors don't see a problem with specifying `foo = "1"` as their dependency, rely on cargo picking the latest, and assume that version flexibility is a good thing. This breakage affects many crates, including uses of `cc` and `serde`. I've had push-back from crate authors against yanking old broken versions and using semver-minor versions correctly, so I think crate authors collectively have decided that `minimal-versions` is going to die.

[Rust versions older than 3-6 months are problematic, 1-year old rustc is a nightmare](https://lib.rs/stats#rustc). This needs a real fix in Cargo, otherwise crate authors who try to support old Rust are IMHO just wasting their time. It takes only one incompatible crate in the entire crate graph to break compilation, so it's not enough that some authors care. Few crates push MSRV up for everyone.

Registry source replacement feature is viable for simulating MSRV-dependent version resolution in Cargo. [LTS — Rust/Cargo add-on // Lib.rs](https://lib.rs/crates/lts)

[Next page](https://internals.rust-lang.org/t/is-it-really-a-good-idea-for-cargo-to-silently-choose-out-of-date-versions-of-crates-to-avoid-pulling-in-multiple-compatible-versions-of-another-crate/15490.md?page=2)
