Question about semver and editions of language

As far as I understand, the semver for rustlang(built-in libraries, compiller,...) is realized by editions, or do the editions work by another way? and if I'm right, are the editions some analogue of LTS(you can use innovations that are compatible for your edition)

Editions are intended to be an escape hatch from semver. Without moving to "rust 2.0.0" breaking changes would technically be forbidden by semver. Editions allow you to opt in to potentially breaking changes on your time and on a crate by crate basis.

1 Like

does this mean that rust(std,core,compiller...) does not support semver?

Editions are not versions. Rust's versions are following semver, currently at version 1.71.0 and the compiler is backwards-compatible all the way to 1.0.0 (except perhaps for bug fixes, especially if they were memory safety relevant, or fixes for prior unintentional breakage/regressions; or occasionally there have been a few very minor changes that were well-tested throughout the ecosystem that they would not affect many people in practice, ideally no-one at all).

Editions are a flag you pass to the compiler to make it interpret a few details of Rust syntax in a different manner. Without this behavior being controlled by a new, opt-in flag, they would've been breaking changes, but they aren't breaking changes because behavior does not change, unless you change your compiler input yourself to use the newer flag. (The --edition flag is commonly passed tonrustc for you by cargo following the information configured in the Cargo.toml file, and for convenience, creating a new crate with cargo new always chooses by default to use the latest available edition at that time.)


The choice of edition is also made at a crate-by-crate level, and crates compiled with different editions still interoperate.

You can read more about the motivations and intentions here.


An illustrative example for a change that happened over an edition: Rust introduced the async keyword in edition 2018. Introducing a keyword breaks code that previously used the name for e variable. If you don't opt into edition 2018 or 2021, you can still call your variables "async", but defining an async fn might be difficult (I'm not sure off the top of my head if there exists any syntax for it in edition 2015 mode).

If you use e. g. edition 2021, that on affects your code. Your dependencies may still use other editions - the compiler interprets the source code syntax of every crate with it's own editon. (By the way - The mechanisms involved to make the work decently with macros, too, are somewhat interesting, too.)

To make migrating code to a newer edition easy, there is usually even an automated process, and it's usually possible to re-write older-edition code in a way that works in both the old and the new edition. (I forgot the precise motivation for allowing this, but I suppose it's making the transition easy: fix code, it still works; switch the edition flag, it still works; then you can make subsequent changes if you like that would no longer work in the old edition). For new keywords for example, like async, there's a new fallback syntax to still - logically - name your variables async by writing r#async instead. So the automatic tooling for going from 2015 to 2018 would automatically rewrite the async-named variables in your code this way.


In particular because that can be done across commits, too.

You can update files slowly to the way that works on both in lots of different changes done by lots of different people, and only flip the edition flag once everything is in the "works in both" state, then again piecemeal out the changes to move to the new-edition way.


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.