The 'some degree' is pretty important, though. The Rust language undergoes backwards incompatible changes sometimes, but the Rust tools do not. The 2024 edition has breaking changes since the 2021 edition, but all compilers can compile all historical editions and will do so forever, and new language features are available in as many editions as possible, and editions can be mixed in a dependency tree, so you do not ever have to update your 2015 edition code for anything.
No you’re misunderstanding the ecosystem. Rust 2024 code can call 2021 code without issue (and vice versa I think although could be wrong on the vice versa). So you can progressively update code of individual components as you want or not at all and still continue using it just fine in new code using later editions. Thats the very definition of back compat, something you really really shouldn’t do with C++ (every file should be compiled with the same language version target although practically that may be less of an issue depending on the specific stdlib implementation and if they break ABI)
There’s also automated migration tools to convert 2021 code to 2024. It might fail on some translations but generally it’s pretty automatic.
So huge difference both in the migration mechanism and the bc story.
Right. A good mental model would be to imagine every crate of Rust source has an associated Edition and there's a sort of "pre-processing" step where we translate that into the latest version of Rust seamlessly, preserving its exact meaning.
So e.g. 2018 Edition said r# at the start of an identifier now marks a "raw" identifier. Keywords promise never to start this way, so r#foo is the same as foo but r#foo even works if some lunatic makes foo a keyword whereas just foo would become a keyword if that happened. As a result if you write
let async = 5;
... in Rust 1.0 that translator treats it exactly as though you'd written
let r#async = 5;
... in a modern Rust edition because these days the keyword async exists.
The equivalent in python-metaphor-land would be that python files clearly designate whether they are py2 or py3, and a single python interpreter can run both py2 and py3 scripts, as well as cross-include files of each version without issue.
Rust editions only (and rarely!) break your code when you decide to upgrade your project's edition. Your public API stays the same as well (IIRC), so upgrading edition doesn't break your dependents either -unless they don't have a new enough version of the compiler to support said newer edition.
what would be the difference with a binary that's has both a py2 and py3 interpreter and a flag --edition=2 or =3 redirects to either file?
If I have Rust code from 2021, can I add a feature from 2024 and run it with --edition=2021 or 2024? Wouldn't adding a 2024 feature then possibly break the 2021 code?
I think the fact that rust is compiled has a big impact in terms of bc for dependencies. py2 must use py2 dependencies, but rust24 could use rust21 binaries as long as there were no API bc breaks, the code itself is already compiled away.
> what would be the difference with a binary that's has both a py2 and py3 interpreter and a flag --edition=2 or =3 redirects to either file?
The difference is that it's not the entire compiler. Rust's editions are only allowed to change the frontend. At the middle part of the compiler, it's all the same thing, and the differences are completely gone. This is the core of how the interop works, and it also means that you can't just change anything in an edition, only smaller things. But completely changing the language every few years wouldn't be good either, so it's fine in practice.
Rust is not‡ dynamically linked. The whole tree is compiled from source every time. The same compiler compiles all editions of the language together, and it is exactly the same as py3 interpreting a py2 script and allowing a py3 script to call it or vice versa.
Very few features are restricted to the 2024 edition; only those that actively introduce or leverage breaking changes. Most things released since 2024 are available in 2015 edition. If you want to upgrade to 2024 edition, that is a manifest flag; your code may break when you change it, and there's incompatibility lints available on the lower editions to tell you what will break when that happens and how to fix it.