Yes, this is exactly the purpose of editions.
Rust has strong backwards-compatibility guarantees. This means that in regular new releases of the language, no breaking changes are allowed. Any improvements to the language that come with a new version of Rust have to not break any existing code.
However, editions are the major milestones for the language. They can introduce breaking changes. However, they are opt-in. All future compiler versions can compile code in both the new and the older editions. Old code continues to compile in the old edition compatibility mode of the compiler. Only code that explicitly opts in to using a newer edition will get the breaking changes.
However, to be specific, editions are not allowed to break just anything. They are allowed to turn compiler warnings into errors, and that’s it.
This means that as new features come to Rust and some old syntax is considered obsolete, a warning can be added to the current edition of Rust. This means that people who write code using the obsolete syntax will see a warning encouraging them to learn how to do things the new way, but their code will still compile.
In the new edition, that deprecation warning can be turned into an error.
This allows people to have a gradual transition from the old edition into the new. They can keep using the old edition with the latest versions of the compiler (as newer editions are opt-in and old editions are still supported by new compiler versions) and they will only see warnings. They can work on fixing those warnings, or they can hide them to not get in the way and stay on the old edition. When they fix all the warnings, they can just change the compiler flag and start using the new edition to get the latest and greatest in Rust. When they switch over to the new edition, any such warnings turn into errors.
However, when creating a new project, Cargo will default to the newest edition. New projects should be in the new edition from the start.
Also, projects in the new edition are fully compatible with libraries written in the old edition, so using the new rust doesn’t stop you from using any of the existing old libraries.
Overall, the editions system is a fairly clean and elegant way for Rust to rid itself of legacy baggage every once in a while and avoid ending up being like C++.
An example of such a change is the new
dyn Trait syntax for trait objects. In Rust 2018, the syntax for trait-generic code will be
impl Trait vs.
dyn Trait, for static (monomorphisation) vs. dynamic (vtables / trait objects) dispatch, respectively. This is to make the syntax clearer. The old bare
Trait syntax for trait objects will get a deprecation warning when compiling in Rust2015 mode and will be a syntax error when compiling in Rust2018 mode.
There are also other changes to the language that deprecate and obsolete old syntax. Similarly, you can keep compiling old code with the latest Rust compilers and get warnings, but if you pass the Rust2018 edition flag to the compiler, you will get errors and it will not compile.