What’s New & Edition Migration
|
This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. The reference material consulted while preparing these pages is listed in the section bibliography. |
This page is written against Rust 1.99.0 (stable since 2026-10-01), checked on 2026-10-06; Rust 1.100 is due on 2026-11-12. It collects in one place what has changed since the material most tutorials and books are based on: the 2024 edition, each stable release from 1.75 onwards, and, at the end, every place where the books consulted for this section describe an older form. Each change is explained in depth on the page linked from it.
The 2024 edition
The 2024 edition was stabilised in Rust 1.85 (2025-02-20). New Cargo projects use it by default. Its changes, grouped as in the Edition Guide:
Language
| Change | What it means | Page |
|---|---|---|
RPIT lifetime capture |
|
|
|
temporaries in the |
|
Tail-expression temporary scope |
temporaries in a block’s tail expression are dropped before its locals |
|
Match ergonomics reservations |
explicit |
|
Unsafe |
|
|
Unsafe attributes |
|
|
|
unsafe operations inside |
|
References to |
|
|
Never-type fallback |
unconstrained |
— |
Macro fragment specifiers |
|
|
|
reserved for future generator blocks |
|
Reserved syntax |
|
— |
// 2024: let chains (1.88), unsafe attribute and the if-let temporary scope in one place.
use std::sync::Mutex;
#[unsafe(no_mangle)] // 2021: #[no_mangle]
pub extern "C" fn shelf_version() -> u32 {
3
}
fn take(stock: &Mutex<Vec<&'static str>>) -> &'static str {
if let Some(t) = stock.lock().unwrap().pop()
&& !t.is_empty()
{
t
} else {
stock.lock().unwrap().push("Dune"); // 2021: deadlock, the first guard was still alive here
"restocked"
}
}
fn main() {
let stock = Mutex::new(vec![]);
println!("{} {} v{}", take(&stock), take(&stock), shelf_version());
}
Source: The Edition Guide: Rust 2024
Standard library
-
FutureandIntoFutureare in the prelude. -
Box<[T]>implementsIntoIteratorby value (boxed_slice.into_iter()yieldsT). -
std::env::set_var,std::env::remove_varandCommandExt::before_execareunsafe(see I/O, Files, Processes & Environment).
Cargo
-
The MSRV-aware resolver (
resolver = "3") is the default for 2024 packages. -
Manifests reject the old underscore key spellings (
dev_dependencies,build_dependencies,crate_types,default_features,proc_macro). -
An unused
default-features = falseon an inherited workspace dependency is an error.
See Cargo & Workspaces.
rustdoc and rustfmt
-
Combined doctests: rustdoc compiles all doctests of a crate into one binary where possible, which is much faster; mark a test
standalone_crateto opt out. Nestedinclude!in doctests resolves paths relative to the including file. -
rustfmt has a style edition independent of the language edition (
style_edition = "2024"): version sorting of identifiers, formatting fixes, and a different sort order for raw identifiers.
See Documentation with rustdoc and Tooling.
Migrating a crate with cargo fix --edition
rustup update stable
cargo update && cargo test # start green on the old edition
cargo fix --edition --all-targets --all-features # apply the migration lints while still on 2021
# edit Cargo.toml: edition = "2024" (and in [workspace.package] for workspaces)
cargo build --all-targets && cargo test # fix whatever the lints could not
cargo fmt # reformat with the 2024 style edition
cargo clippy --all-targets -- -D warnings
cargo fix --edition is conservative: it may add use<..> bounds, rewrite if let into match to preserve old drop
order, change expr to expr_2021 in macros and wrap set_var calls in unsafe blocks. Review those rewrites; most can
be simplified once you have checked that the new behaviour is what you want. Migrate one crate of a workspace at a time — crates of different editions interoperate freely.
Release by release: 1.75 to 1.99
Rust ships every six weeks. The table lists headline features per release; each was compiled against that release’s toolchain while writing this section where it is used in an example.
| Release | Date | Headline features |
|---|---|---|
1.75 |
2023-12 |
|
1.76 |
2024-02 |
|
1.77 |
2024-03 |
C-string literals |
1.78 |
2024-05 |
|
1.79 |
2024-06 |
inline |
1.80 |
2024-07 |
|
1.81 |
2024-09 |
|
1.82 |
2024-10 |
precise capturing |
1.83 |
2024-11 |
|
1.84 |
2025-01 |
MSRV-aware resolver; strict provenance APIs; |
1.85 |
2025-02 |
Rust 2024 edition; async closures and |
1.86 |
2025-04 |
trait upcasting; |
1.87 |
2025-05 |
|
1.88 |
2025-06 |
let chains (2024 edition); naked functions; boolean literals in |
1.89 |
2025-08 |
inferred const arguments |
1.90 |
2025-09 |
LLD as the default linker on |
1.91 |
2025-10 |
|
1.92 |
2025-12 |
|
1.93 |
2026-01 |
|
1.94 |
2026-03 |
|
1.95 |
2026-04 |
|
1.96 |
2026-05 |
|
1.97 |
2026-07 |
v0 symbol mangling by default |
1.98 |
2026-08 |
|
1.99 |
2026-10 |
C-variadic function definitions; |
Source: Rust release notes
The Rust blog (https://blog.rust-lang.org/) announces each release with examples, and https://releases.rs lists every stabilised API and change per version, including the upcoming beta.
Work in progress (nightly only)
Several long-running efforts are visible on nightly but not part of stable Rust:
-
Polonius, a more precise borrow checker that accepts some programs NLL rejects (notably conditional returns of borrows), being integrated as a location-sensitive analysis;
-
the next-generation trait solver, already used for coherence checking, being extended to all trait solving;
-
generators and
genblocks (the keyword is reserved), specialisation, const generic expressions (generic_const_exprs), the!type in all positions, and async drop; -
Cranelift as a faster code-generation backend for debug builds.
A 2027 edition has been discussed by the project but is not announced; treat any list of its contents as speculative. The project’s goals for each half-year are published at https://goals.rust-lang.org/.
Outdated in the books
The books consulted for this section (listed in the section bibliography) were used for concept coverage; where they show an older form, the pages present the current one. The complete list:
| Area | In the books | Current |
|---|---|---|
Editions |
Mara & Holmes use 2018; Yoon and Crossley et al. use 2021 |
2024 (1.85): RPIT capture, |
Missing language features |
— |
let chains (1.88), |
Terminology |
"object safety" (Azam ch. 7) |
dyn compatibility |
Downcasting |
the |
trait upcasting to |
Drop check |
|
nightly-only ( |
Globals |
|
|
FFI |
|
|
FFI safety |
a safe |
|
PyO3 |
0.14 GIL-ref API: |
0.29: |
WebAssembly |
|
|
Build scripts |
|
|
Benchmarks |
criterion 0.3/0.4, |
criterion 0.8, |
Random numbers |
rand 0.8 |
rand 0.10:
|
Numeric crates |
ndarray 0.15, rayon 1.7 (Crossley et al.) |
ndarray 0.17, rayon 1.12 |
GUI |
Druid (Crossley et al.) |
discontinued; its successor project is Xilem |
Memory leaks |
"Rust catches memory leaks at compile time" (Yoon ch. 1) |
leaks are memory-safe; |
Async state |
|
|
Errata |
"Rust 1.8 or later" for 1.80 (Gangappa & Rangaraj preface); unterminated strings in |
— |
The web-framework items (axum 0.6/0.7 APIs, tower-http 0.6, sqlx 0.8, SeaORM 1, jsonwebtoken 9, bcrypt in handlers) are collected on Axum: Migration & Framework Comparison.