UPD: This proposal is published as RFC 2495.
Summary
Add rust
field to package section which will be used to specify crate’s Minimum Supported Rust Version (MSRV):
[package]
name = "foo"
version = "0.1.0"
rust = "1.30"
Motivation
Currently crates have no way to formally specify MSRV. As a result users can’t be sure that crate can be built on their toolchain without building it. It also leads to the debate on how to handle crate version change on bumping MSRV, conservative approach is to consider such changes as breaking ones, which can hinder adoption of new features across ecosystem or result in version number inflation, which makes it harder to keep downstream crates up-to-date. More relaxed approach on another hand can result in broken crates for user of older compiler versions.
First stage: dumb field
We can start with the simple addition of rust
field which should respect minimal requirements:
- value should be a version in semver format or equal to “nigthly”
- version should not be bigger than the current stable toolchain
- version should not be smaller than 1.27 (version in which
package.rust
field became a warning instead of an error)
At first it can be simply a declarative field without any functionality behind it. The reason for it to reduce implementation cost of minimal viable version to the minimum and ideally ship it as part of Rust 2018. It will also allow crate authors who care about MSRV to start mark their crates early. Additionally cargo init
will add rust
field equal to a version of the used toolchain.
Using edition = "2018"
will imply rust = "1.30"
if not specified otherwise. In case of 2015 edition it will be rust="1.0"
. It will be an error to use rust="1.27"
and edition="2018"
, but rust="1.40"
and edition="2015"
is a valid combination.
Second stage: versions resolution
Cargo will add rust
field as a constraint to dependency versions resolution. If user uses e.g. Rust 1.20 and uses crate foo = "0.2"
, but all selected versions of foo
specify MSRV say equal 1.21 or bigger (or even nightly) cargo
will issue an error.
rust
field value will be checked as well, on crate build cargo
will check if all upstream dependencies can be built with the specified MSRV. (i.e. it will check if there is exists solution for given crates and Rust versions constraints)
Yanked crates will be ignored in this process.
Implementing this functionality will allow to close the debate regarding MSRV handling in crate versions and will allow crate authors to feel less restrictive about bumping their crate’s MSRV.
Third stage: better crate checks
Here we introduce two level checks for crates. First level will check if all used items were stabilised before or on given MSRV using #[stable(since=version)]
attribute, issuing compile errors otherwise.
Second level will try to build crate with the specified MSRV on cargo publish
, i.e. words it will be required to install MSRV toolchain. (this check can be disabled)
While these two checks will not replace proper CI testing, they will help to reduce number of improper MSRV configuration to the minimum.
Extension: nightly versions
For some bleeding-edge crates which experience frequent breaks on Nightly updates (e.g. rocket
) it can be useful to specify exact Nigthly version(s) on which crate can be built. One way to achieve this is by using the following syntax:
- single version: `rust = “nightly: 2018-01-01”
- enumeration: “nightly: 2018-01-01, 2018-01-15”
- (inclusive) range: “nightly: 2018-01-01…2018-01-15”
- enumeration+range: “nightly: 2018-01-01, 2018-01-08…2018-01-15”
Such restrictions can be quite severe, but hopefully this functionality will be used only by handful of crates.
Backward compatibility
Since Rust 1.27 (or maybe earlier?) cargo issues only warning on unknown fields in Cargo.toml
, so impact of introducing rust
field will be minimal.
Unresolved questions
- Naming:
rust
vsrustc
- Should we add additional checks?
- What MSRV value should
cargo init
use, current toolchain or edition min-version? - Better description of versions resolution algorithm.
- How handle crate features which bump MSRV?