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 vs rustc

vs Should we add additional checks?

What MSRV value should cargo init use, current toolchain or edition min-version?

use, current toolchain or edition min-version? Better description of versions resolution algorithm.

How handle crate features which bump MSRV?

Previous proposals