The MSRV (Minimum Supported Rust [toolchain] Version) policy of my crates for a semver-compatible bump is the following:
stable - 9
More precisely:
-
Patch1 bump ⇒ same MSRV
-
Minor2 bump ⇒ MSRV may increase, but not beyond 1-year-old stable (stable - 9)
This means that technically (based on a fixed interpretation of MSRV), I may break MSRV!
If this is a problem, use a.lock
file (or, worse, a~
tildeCargo.toml
version requirement)
Note: the initial MSRV of a new major
bump or newly created crate may be more recent than stable - 9
- For instance, as of May 2023, I am using Rust 1.65 (6-month old stable) for new crates / major semver bumps, since I find GATs to be a major milestone of the language.
-
🐣 If you keep your toolchain lagging less than a year behind
stable
(i.e.,stable - 9
), you can let Cargo semver pick whichever specific version it wants, it won't break you -
👴 If you are using a "very old" (more than 1 year old) Rust toolchain, then:
you should have your
Cargo.lock
file tracked bygit
/your repository!
This, much like formatting and linting, thus requires an extra CI step that enforces it being done, by running, for instance, cargo update -w -v --locked
(dev-wise / git hook
-wise, run it without the --locked
to actually update the .lock
files so that they are up-to-date with the .toml
files).
You may be tempted not to do so due to some misguided advice from the official Rust/Cargo guidelines. They are wrong! A Cargo.toml
does NOT define a dependency tree, it just constrains the range of possible ones! The one actually picked is "arbitrary" (depends on the exact state of the crates.io at the time Cargo resolves it): without a .lock
file, your builds will not be reproducible:
- thereby breaking
git bisect
or any other form of "travel back to time" functionality, - and in case a semver-compatible dependency breaks something (due to a genuine semver error, or due to "acceptable semver breakage", such as MSRV itself), which will happen, or in case of
yank
ing, your build will break, and may also be annoying for you to fix back. - Eventually, you may even be tempted to start using
=
-pinned versions in yourCargo.toml
, which in the long run does way more harm than good. - (if you have many
Cargo.lock
files in your repo you may need to adjust/fix your[workspace]
)
If you really want to avoid keeping the .lock
file tracked, then you can kind of get away with it if my crate is on a major.minor.patch
version. In that case, you could use a tilde requirement, which shall only allow patch bumps, instead of the default (implicit-caret requirement, which allows patch and minor bumps).
-
I do not recommend this since any kind of non-(caret-)semver constraint in a
Cargo.toml
file can make your crate incompatible with other ones for (downstream) dependents; and these dependents may not have the same Rust compiler constraints that you have, so the whole resulting situation becomes quite silly.