Overview
Editions are Rust's answer to the question every language eventually faces: how do you
fix early mistakes without a Python-3 schism? An edition is a per-crate opt-in dialect
(edition = "2021" in Cargo.toml) that may change syntax, keywords and defaults —
and crates on different editions link together freely, forever, because every edition
compiles to the same internal representation in the same compiler. Java answers this
with near-total stasis plus preview gates, Go with the Go 1 promise plus GODEBUG;
editions are the third design: breaking changes made routine, scoped, and automated.
Key points
- Per-crate, not per-program: your 2024-edition binary can depend on 2015-edition crates without anyone noticing; there is no ecosystem flag-day. This interop guarantee is the load-bearing promise — an edition may never change what a crate's interface means to other crates.
- What editions may change: keyword additions (
async/awaitreserved in 2018,genin 2024), default lints becoming errors, prelude contents, closure capture rules, syntax meaning. What they may not: anything requiring coordinated upgrades — no ABI, no stdlib removals. - Migration is tooled:
cargo fix --editionapplies mechanical rewrites, then you flip theeditionkey; the compiler'srust_2024_compatibilitylint group warns ahead of time. Real projects migrate in an afternoon; that this is boring is the design's success metric. - The train: editions ship roughly every three years — 2015, 2018, 2021, 2024 (stabilized in Rust 1.85) — deliberately small; features land continuously in ordinary releases, and an edition only bundles the changes that need an opt-in.
- 2018:
async/awaitkeywords, uniform paths, NLL rollout era,dyn Traitsyntax; the module-system cleanup that removedextern crate. - 2021: disjoint closure captures (closures capture fields, not whole structs),
IntoIteratorfor arrays, the new prelude (TryIntoet al.). - 2024: RPIT lifetime-capture rules,
unsafe_op_in_unsafe_fnby default, references tostatic mutdisallowed,genreserved — the largest edition yet, still an afternoon's migration. - The limit case: editions can't fix everything — anything touching the stdlib's
actual types (an
Errorredesign, say) or coordinated semantics stays impossible; that pressure is what keeps "Rust 2.0" discussions alive and always rejected.
Details
The mechanics
The compiler front-end parses each crate according to its declared edition, then everything meets in the same HIR/MIR. A keyword in one edition is a plain identifier in another; a lint that is deny-by-default in 2024 is warn in 2021. Because the semantics of the compiled output are shared, the interop guarantee holds by construction rather than by discipline — the design insight the C++ epochs proposal tried and failed to import, largely because C++ lacks the single-implementation, single-build-system substrate Rust's editions lean on (cargo knows every crate's edition; C++ builds don't even agree on a manifest).
Contrast with the neighbours
| Java | Go | Rust | |
|---|---|---|---|
| Promise | Binary + source compat, decades | Go 1 promise since 2012 | Interop across editions, forever |
| Breaking mechanism | Almost never; deprecate + wait | GODEBUG-gated behaviour keyed to go.mod version |
Edition opt-in per crate |
| Migration tooling | — | go fix (rarely needed) |
cargo fix --edition |
| Cadence | Preview → final per feature | Per release | Edition every ~3 years |
Go's go directive in go.mod has converged on something edition-shaped (behaviour
keyed to a declared language version); editions remain the more general instrument —
they can change syntax, not just behaviour defaults.
Related
- Rust compilers & the language definition — parent note; the single implementation that makes editions tractable.
- How Rust evolves — the RFC-and-train process editions ride on.
- Cargo in depth — where the
editionkey lives and how the resolver honors it. - OpenJDK & the JEP process — Java's no-breaking-changes counterpoint.
- How Go evolves — the Go 1 promise and GODEBUG, the nearest mechanism to editions.
Citations
[1] The Edition Guide [2] Rust 2024 edition announcement (Rust 1.85)