Crate Edition / MSRV

I've been trying, although admittedly not with a lot of effort, to keep the edition in my crates as old as possible. My reasoning has been to "maximize compatibility" [as long as it doesn't come at the cost of missing out on features]. I used to think this was generally the idea behind editions.

However, cargo new defaults to the latest edition, which makes me think that the Crab Elders™️ want us to stick with the latest editions unless there's a compelling reason not to.

As far as I know, when compilation reaches down to MIR any "editioness" is erased, so there's no codegen-level reason to stick to the latest edition.

So what are the arguments for sticking with the oldest possible (i.e. without sacrificing features one wants/needs) edition? I read someone argue that there are rust developers who use their system's native package manager to install rust, and if one uses RedHat/Debian stable, this could mean sticking with very, very, old versions, and forcing later editions in crates could be an issue for such developers. But .. does this actually happen in practice?

I want to emphasize that I'm not talking about skipping useful features for the sake of being backwards compatible -- I'm specifically talking about cases where the switching between edition = 2018 and 2021 makes no difference, because the source code does not use any post-2018 features. What I'm starting to think is that a reason to choose the latter is to make it clear to contributors that they do not need to worry about backward compatibility.

I took a peek at some of the common crates I use (some of which are high up on the most downloaded list), and there's a mix of being edition = "2021", 2018 and not specifying edition at all.

It seems some projects omit the edition and specify rust-version instead. This seems compelling to me (because of the finer granularity), except for the fact that it can be sort-of a pain to determine the exact MSRV. (Has someone developed a binary search tool to empirically find out what the minimum supported version is?).

Should I keep striving for "oldest possible edition" or should I just stick with the latest one possible? And is the effort to find out the rust-version worth it?

1 Like

AFAIK the only case where it makes sense to not use the latest edition is when you want to support older versions of the compiler that didn't have support for the current edition yet, but that also implies skipping newer features.

Note that there's a difference between them because the edition will enable breaking changes in the compiler, mainly to the syntax, while rust-version is just a hint to cargo of what's the MSRV.

Note that the MSRV is not just the minimum version your crate works on, but the one you plan to support. Changing it to a newer version is considered a breaking change.

A quick search brought up GitHub - foresterre/cargo-msrv: 🦀 Find the minimum supported Rust version (MSRV) for your project


Overall, I would always go for the latest edition your MSRV compiler supports. If I don't plan to support older compilers yet then I would go for the latest stable and consider support older versions if someone asks for it.

3 Likes

I would stick with the most recent edition unless you have a good reason not to.

In terms of MSRV, I don't bother to figure out the oldest possible Rust version my crate will still compile with. Instead, I'll create a project using a particular version, write it to rust-toolchain.toml and make sure CI uses it for everything. Later on when I want to use a feature that requires a newer version of Rust, I'll bump to just that version. Rinse & repeat.

I've heard that argument too, however unless you are the author of something ubiquitous like ripgrep or tokei I feel like it's made out to be a bigger deal than it really is.

Essentially everyone uses Docker for deploying to production these days, so that means your target audience no longer includes server applications. Most Rust CLI tools are targeted towards developers that almost certainly already use rustup for managing their Rust installation. Quite a lot of GUI applications will distribute pre-compiled binaries themselves (possibly with some sort of auto-updating mechanism) rather than pushing to get their stuff into the main repositories for "slower" distros like Ubuntu or Debian.

Once you cut out all of those groups, the number of actual people that will want to install a Rust app from the official repos for a distro that uses super old versions of Rust becomes pretty small.

I haven't got any numbers to back that up, but as one data point, I work at Wasmer and we have our own independent mechanism for installing and updating the main CLI tool and associated toolchain. We have a "stable-minus-two" policy when it comes to MSRV and in the time I've been with the company, I've never heard any chatter from distro maintainers or users that want us to support an older MSRV.

2 Likes

No it isn't. There are a minority of people who believe this and even fewer that actually put it into practice with a popular crate.

Ideally this doesn't start a tangent and derail the topic. If you want to discuss this, I'd suggest making a new thread or bringing your arguments here: Minimum Supported Rust Version (MSRV) Policies · rust-lang/api-guidelines · Discussion #231 · GitHub

I asked distro maintainers what they thought about this, and all of them were totally cool with tracking the latest stable Rust. Because if you want to support an older version of Rust, then you should be okay with using an older version of ripgrep to go along with it. See: RFC: do you care which version of the Rust compiler ripgrep targets? · Issue #1019 · BurntSushi/ripgrep · GitHub

8 Likes

That's true, current Debian stable comes with RustC 1.63.0 and that prohibits using the latest version of about half the crates out there. Workaround is to force an older version, which usually works, but not always.

It's news to me somebody does this. Yet another gigabyte-sized chunk of files which needs custom maintenance. Not my favorite, there's a reason why OS-wide package management was invented.

Also Debian maintainers? Packaged RustC (1.63) there is quite a bit older than was the latest when current Stable still was Unstable. I'd appreciate a more recent version, of course.

One solution is to offer a custom package archive. For example, WineHQ does this and Ubuntu has an entire project dedicated to this, PPAs. These PPAs and custom archives can be imported into the packaging system, from there on it just works.

Yeah, I have some stuff I've written, which depends on c code which itself targets ubuntu LTS, I try not to exceed that just so I don't have to fork the installation instructions, and keeping it easy to build alongside the upstream stuff... The libraries I've written for it I have just kept at MSRV 1.3 since it works and I haven't actually found any features that would lead to substantial improvement by bumping it. But it also doesn't have any rust dependencies beyond using some derive macros which could easily be replaced if those ever stopped working with the old compilers.

Overall though it probably not a typical situation where you are expecting all people using it to be running on old build system installation & upgrading that in lockstep.

Distro package managers are for end-user applications.

I am an end-user of RustC :slight_smile:

I just think that changine MSRV should be a breaking change in crates semver.

2 Likes

Yes... See the thread. They chime in too.

Presumably you're using Debian. If so, one of the key features of Debian is that they pin the versions of their software. If you're okay using an older version of rustc, then from my perspective as the maintainer of ripgrep, you're also okay with using an older version of ripgrep. And if you're not, you have options. Many of them. You can download a release binary I publish. Or a dpkg. Or use rustup to install a newer version of Rust to compile ripgrep. You might have reasons against all of those options. But that's your choice.

There ain't no way in hell I'm doing the extra work to maintain a custom package archive just so you don't have to install rustup or use one of my release binaries. If I were a business and you were a customer paying me for my time to do shit I don't like to do, maybe I would.

Again, it's not, and it doesn't scale. See my links above.

3 Likes

Assume thing A depends on thing B. An incredibly large number of other things also depend on B. B gets a minor version bump. A future version of A depends on that new minor version; it's now incompatible with the previous minor version of B. Should that force A to get a major version bump because of B's minor version bump?