Why crates for Rust 2015 are still around?

Do you maintain any crates still using the old edition 2015?
  • No, all my current crates are on 2018 or 2021.
  • Yes, because I need compatibility with rustc 1.30 or older.
  • Yes, because I want the unprefixed try!() macro.
  • Yes, because I don't want to needlessly change code that works (too much hassle or churn)
  • Yes, for other reason…
  • I don't know which edition I'm using.

0 voters

There are still quite a few widely used crates that use the oldest Rust edition. I wonder what makes y'all stick with the ancient Rust version.

How far fetched would it be to upgrade all the crates to the point that future Rust implementations won't even need to support the 2015 edition?

The autocfg crate uses the 2015 edition.

1 Like

I'd rather see a Rust 2.0 than becoming something not actually backwards compatible while still pretending to be.


There's plenty: serde, pkg-config, spin, libloading, addr2line, rustc-demangle, static_assertions, rustc-hash, fixedbitset, shlex, linked-hash-map, clang-sys, multimap, mime_guess, core-foundation, lru, diff, scoped-tls, tap, colored, yansi, derive_builder, headers, chrono-tz, derive_builder_core, keccak, bytesize, downcast-rs, bzip2, openssl-src, ascii, seahash, typed-arena, globwalk, bigdecimal, ena, fraction, headers-core, psm, lalrpop, hash32, strip-ansi-escapes, serde_test, bit_field, triomphe, core-graphics, diesel_derives, slog-async, stacker, sys-info, derive_builder_macro, jsonpath_lib, migrations_internals, selectors, dlib, pretty-hex, android_logger, field-offset, atomicwrites, nonzero_ext, cocoa, unicode-id, curve25519-dalek-ng, dns-lookup, smart-default, khronos-egl, android_log-sys, core-graphics-types, devise_core, devise.


Because it supports Rust 1.0! That's an intentional outlier, as compatibility testing is its very purpose of existence.

I only use older editions in my crates as they correspond to MSRV.
(But I don't wish to debate MSRV policies here...)


Given the relatively little overhead that the edition system has, I don't know why one would want to do that even if you could, ignoring the inherent lack of back-compatibility.


There is one place where the edition system (considered widely) does have a significant ongoing cost: every so often, someone will try to write a Rust program “from scratch” one way or another (choosing not to use a project template, or writing a rustc invocation directly), and end up on edition 2015. They then experience various historical features of the language (extern crate, no async, no array IntoIterator, etc.) without necessarily understanding the assumption the compiler is making.

If rustc and cargo were to drop the implicit 2015 edition, requiring all programs to specify edition, then users would no longer be paying this cost.

I'm not recommending this course of action, but I thought it was worth mentioning that continuing to support implicit-2015 packages is not just a bit of rustc parser complication.


At least for diesel_derives that easy to explain: It relays on a name resolution feature for code generated by the proc macros in this crate that only works with the 2015 edition.
Other than that: It's additional work to update a crate to a new edition and at least for a proc macro crate there are no clear advantages of using rust 2018 or 2021 compared to the old 2015 edition, because most of the new functionality is not used there anyway.

1 Like

Hmm… maybe rustc invoked without any --edition information should display a huge warning informing the user of the default edition 2015 being chosen, that the recommended edition for new projects is 2021 and that the recommended way of interacting with rustc is through cargo. Displaying a huge warning is not a breaking change, right? (I.e. besides the warning, it’s still supposed to compile successfully, of course.)

(Of course, with such a change, the book should presumably be updated to show the command rustc --edition=2021 main.rs instead of rustc main.rs. Which might actually be an improvement anyways as it’s a “more proper” way of calling rustc.)

Edit: You mention the case of not choosing a project template. Maybe even in those cases there should be a (small!) note (from cargo) about edition 2015 being chosen.



Let's do it.


that would be kinda annoying on godbolt.

I actually think it would be particularly helpful in the godbolt.org Compiler Explorer. It's easy enough to add the --edition= argument, and in the common case where you're not currently comparing the compiler output of very old rust versions, edition 2015 is not actually what you want. godbolt.org is the place where I've been bitten by (i. e. gotten seriously confused by the results of) the implicit 2015 default the most by far. If adding the command line argument seems too tedious, maybe godbolt.org could add a dedicated GUI thing for it, possibly even choosing a default value different from 2015. (A similar thing could be said about the need to specify the optimization level manually on that website, which requires knowledge of the precise format of the relevant compile flag -C opt-level= in the first place, and would perhaps be nicer in the GUI.)


Note that -O works as well, for -C opt-level=2, which is often sufficient for what one needs on godbolt.

I've just managed to write a compiler warning that accomplishes this.

warning: language edition not specified
  = note: editions control which language features are available; for backwards compatibility, not specifying an edition defaults to the oldest edition, 2015, which is usually not desired except for legacy code
  = note: the latest edition is 2021
  = help: add the `package.edition` key to the `Cargo.toml` manifest to specify the crate's edition

PR maybe soon. Just need to figure out what to do with all the failing UI tests that now emit this warning.


Cargo doesn't supply --edition=2015 for edition 2015 crates (even with an explicit edition field). I feel that use case shouldn't warn (e.g. Cargo could start supplying the edition in that case).


I don’t want to discuss this in-depth in this thread, since it’s a bit off-topic, but I’ve got some ideas about the error message, too; and I would want to avoid that cargo ever triggers it. In particular: The issue that manifest files might not contain an edition field, when cargo war invoked seems separate and deserves, if any warning at all, a different message, perhaps originating from cargo itself; and what I’m talking about here is the case of manual (or via custom build tools) invocation of rustc directly. (I don’t suggest detecting whether cargo invoked it in any hacky direct way, but perhaps e.g. as suggested above, cargo could simply be made to always supply --edition= information, so the warning from rustc itself would never possibly appear through cargo invocations.)

In either case it also seems important to think about backwards-compatible ways of silencing the warning, for crates that want compatibility with very old rust versions that don’t know about editions. The warning that appears when rustc was “manually” invoked should talk about the --edition flag, inform about the default choice and recommended choice, perhaps even explain how the warning can be avoided without using the backwards-incompatible --edition argument, and perhaps recommend using cargo. Only the warning that appears when invoking cargo in a project without an edition entry in the Cargo.toml, if any warning is wanted at all, should mention the package.edition key, and possibly also explain a backwards-compatible way of silencing the warning.