rust-lang / cargo

The Rust package manager
https://doc.rust-lang.org/cargo
Apache License 2.0
12.75k stars 2.42k forks source link

MSRV-dependent dependency version resolution #9930

Open newpavlov opened 3 years ago

newpavlov commented 3 years ago

Based on RFC 2495 Rust now supports the rust-version 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 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


This has been approved as RFC #3537.

Implementation by stabilization milestone

Changes from RFC

Unresolved questions

Deferred

remram44 commented 1 year ago

the rate of bugs being fixed should be higher than the rate at which bugs are introduced for any given project

If that were true there wouldn't be any bugs. Projects are born with no code and no bugs.

jonhoo commented 1 year ago

They're also born with no features. Hence the carve-out in my statement that this doesn't apply to new feature development. Over time though, the rate of new features in a project tends to go down (or when they are introduced, most users mainly rely on the old features).

Anyway, this is starting to veer off-topic. My point was simply that I think newer-versions-are-better is a fairly true statement. There are instances where it's not true, but on balance it's more true than not. And I would contend by a solid margin, especially if you're comparing with a quite-old version (say, one that builds with a 2 year old Rust compiler).

epage commented 1 year ago

rust-lang/crates.io#6267 is now in production!

djc commented 1 year ago

@epage, in that PR you wrote:

The reason we haven't moved forward with it yet is we didn't think it was possible to do it well with the current resolver but now we think we have a plan

As far as I can see you have not detailed that plan here? At least I just skimmed your recent comments again to find it and didn't really find anything that seems like it comprises a plan.

epage commented 1 year ago

My comment is now hidden by default.

epage commented 1 year ago

killercup/cargo-edit#851 applies the coalescing idea to cargo-upgrade

CC @djc

YellowOnion commented 11 months ago

Does this fix cargo not making a backwards compatible lock file? I've been banging my head against the wall trying to figure out how to generate a lock file that works with older versions.

epage commented 11 months ago

@YellowOnion could you clarify what you mean by a backwards compatible lockfile?

For myself in reading that, I would consider that to apply to the format and not the dependencies picked for that format (which is what this issue is about). #12861 is exploring adding more checks on the format we use.

YellowOnion commented 11 months ago

@epage I have rust-version = 1.65 in the toml of bcachefs-tools, but cargo 1.69, will generate a lock file that won't even compile without 1.70, I spent like 6 hours trying to patch latest bcachefs-tools to compile on my OS's default rust, cargo and rust-analyzer just hates anything older than 1.7.

epage commented 11 months ago

Sounds like the file format is backwards compatible but the dependencies selected are not compatible which is what this issue addresses. If you install a nightly, you can run cargo generate-lockfile -Zmsrv-policy.

Is there a reason you are developing on 1.69 rather than the latest rust or your MSRV?

YellowOnion commented 11 months ago

@epage I'm not developing, I'm packaging it, and the OS only has 1.69 in the package manager / CI system, next stable release is this month sometime, surprised I can't use a ~5 month old cargo without things going wrong.

epage commented 11 months ago

Thanks for the explanation! Its useful to know what cases people are running into problems as it helps us better understand solutions, like the work I'm doing on the pre-rfc for this: https://internals.rust-lang.org/t/pre-rfc-msrv-aware-resolver/19871

epage commented 11 months ago

RFC is live: rust-lang/rfcs#3537

The "Implementation" list has been updated for what the RFC proposes

epage commented 8 months ago

rust-lang/rfcs#3537 proposed the following resolver precedence

Initially, dependencies without package.rust-version will be preferred over MSRV-incompatible packages but less than those that are compatible.

This was reflected in code in #13066.

For cargo add, we currently treat unset MSRVs as compatible, see https://github.com/rust-lang/cargo/blob/9e6288efe0bbccc53d95080070524e4640769339/src/cargo/ops/cargo_add/mod.rs#L703-L713

I suspect we should be consistent, if for no other reason that its easier to explain to the user. I had considered changing cargo add to match the proposed resolver behavior but I was worried users might not want us to select an older semver-incompatible version just for positive confirmation of msrv-compatibility. We could update the logic to say "pick the latest major version with a compatible MSRV or no MSRV set, then pick the highest compatible MSRV, falling back to no MSRV, then falling back to incompatible". However, I hesitated with the complexity, not just to implement but to explain to the user.