Edition and Version: Thoughts and Request for Feedback

I’d like to check whether this understanding is sound, and whether there are any other important aspects worth knowing.


In the reference for cargo.toml / manifest there is the distinction between Version and Edition that I overlooked as a newcomer. Reading the individual descriptions for version, and edition didn't fully clarify the distinction for me.

However, I found the forum discussion, which I'd summarise as follows:

  1. Rust Edition: Introduces breaking changes in the language —that is, non backward-compatible changes.
  2. Rust version: Introduces non-breaking changes and language features —backward-compatible changes.

An example of a breaking change (Edition) is given in The Rust Editions Guide where they explain how async would have broken code like let async = 1. So it's a change included in an edition. Code using lower editions can't use that functionality.

Code that isn't breaking, like the recent let chains would not be a breaking change.

Hence, projects using edition 2015 can use version 1.88 and let else chains.

I initially wrote this as a question about "Why not to use the major slot in rust-version to include such breaking changes?" But the answer is: the rust-version allows for any edition to use the non-breaking changes. Using a single version identifier would block some projects from using those non breaking changes.

Another interesting bit in the guide cited above is that neither version nor edition changes are ecosystem-breaking; any crate can use any version / edition combination without issues.

The version is the minimum toolchain version that is supported by that crate (ideally, the minimum version it's tested with), while the edition is the language used in the source code—but granted, the language also changes with the version, as you said.

For example, you could have code written for 2018 and wish to use exclusive range patterns, which are only supported from version 1.80 onward. The code written at the time for edition 2018 could benefit from exclusive ranges; for example if it's safer or much simpler than inclusive ranges, but rewriting the whole code for edition 2024 would perhaps be too tedious.

I don't know if that's a typical example, but many features take time to stabilize, and sometimes specific bugs are fixed, so it could be one reason to separate both parameters. You need at least some minimum version to support a given edition (e.g. 1.85 for 2024), but later versions are still able to compile earlier editions. So I think that's mostly what you wrote.

1 Like

Actually, let else chains depend on a breaking change to when temporaries are dropped which was made as part of edition 2024, so an edition 2015 project, even if it uses rustc 1.88, cannot use let else chains.

4 Likes

The corrections make sense.

Examples of how they interact

  • Local crate with version of rustc 1.88 and edition 2015 —and no let-chains: this should compile just fine.

  • Adds dependency requiring rustc 1.88 using let-chains (Edition 2024): the compiler just reads that dep and accounts for the edition; as long as they are in a dep it should be fine. For other cases, dependencies with rustc < 1.88 would be fine as well.

  • If a dependency needs rustc>1.88 however, the local crate would be blocked from using that dependency.

In that way, editions do not (directly) block us from using other crates, but versions do.

PS: by rustc I meant the toolchain.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.