Rust 1.96.0 release notes landed on May 28, 17:50 UTC. This maintenance release packs backend improvements and critical security fixes. It ships two CVEs patched in Cargo. Language updates include better macro handling and s390x vector register support. Stabilized APIs like assert_matches! make your code cleaner. Upgrade now to keep your toolchain safe and modern.
This maintenance release is recommended for all Rust developers and DevOps engineers. The upgrade delivers critical CVE fixes, new stabilized APIs, and improved compiler performance for LoongArch and Fuchsia targets.
What Changed
- Language: Allow passing expr metavariable to cfg. Always coerce never types in tuple expressions. Avoid incorrect inference guidance of function arguments in rare cases. Support s390x vector registers in inline assembly. Allow using constants of type
ManuallyDropas patterns (fixing a regression introduced in 1.94.0). - Compiler: Enable link relaxation for LoongArch Linux targets. Update riscv64gc-unknown-fuchsia baseline to RVA22 + vector.
- Libraries: Support iterating over ranges of
NonZerointegers. Refactor ‘valid for read/write’ definition: exclude null; add that as an exception on individual methods instead. Fix SGX delayed host lookup viaToSocketAddr. - Stabilized APIs:
assert_matches!,debug_assert_matches!,From<T>forAssertUnwindSafe<T>,From<T>forLazyCell<T, F>,From<T>forLazyLock<T, F>, and severalcore::rangetypes. - Cargo: Allow a dependency to specify both a git repository and an alternate registry. Added
target.'cfg(..)'.rustdocflagssupport in configuration. Fixed CVE-2026-5222 and CVE-2026-5223. - Rustdoc: Deprecation notes now render like any other docs. Don’t emit missing_doc_code_examples lint on impl items. Separate methods and associated functions in sidebar.
Why It Matters
- Security first: Cargo fixes two CVEs. Attackers could exploit these to compromise your builds. Update now.
- Code simplicity:
assert_matches!anddebug_assert_matches!land as stable macros. Write pattern-matching assertions in one line. - Better ergonomics: Lazily initialize values with
LazyCellandLazyLockusingFrom<T>. Builders and configs get simpler. - Cross-platform gains: LoongArch link relaxation and Fuchsia RVA22 baseline boost performance on these platforms.
- Clearer docs: Rustdoc separates methods from associated functions. Deprecation notes no longer break your page layout.
Who Should Upgrade
This release targets every Rust developer and team managing Rust deployments. If you maintain open-source libraries, secure your supply chain with the CVE fixes. If you work on embedded systems or cross-compile for LoongArch, Fuchsia, or s390x, the compiler and library improvements directly benefit you. The stabilized APIs are valuable for anyone writing tests, lazy initializers, or range iterators.
How to Upgrade
- Update your toolchain with
rustup update stable. - Verify the new version:
rustc --version. Expect output likerustc 1.96.0 (ac68faa20 2026-05-28). - Run
cargo checkon your projects to catch any regressions. - Review the Compatibility Notes in the changelog. Pay attention to the removal of
-Csoft-floatand the new double type for AVR targets. - If your project uses CI, update the base image or toolchain spec to 1.96.0.
Usage Examples
- Pattern asserts: In test code, replace
match some_value { Some(x) => assert_eq!(x, 42), _ => panic!() }withassert_matches!(some_value, Some(42)). It reads as a single, clear assertion. - Lazy configs: Use
LazyLock::from(expensive_computation)to defer initialization until the first access. No more manual OnceCell boilerplate. - Range over NonZero: Iterate over spacings like
for i in NonZeroU8::MIN..=NonZeroU8::MAX. The compiler guarantees no zeros appear in the iteration. - Git + registry deps: Specify
foo = { git = "https://...", registry = "my-registry" }inCargo.toml. Locally Cargo pulls from git, but publishes to the registry. - Target-specific rustdoc: Add
[target.'cfg(target_os = "linux")'.rustdocflags]to pass flags only for Linux doc builds.
Breaking Changes
- Layout fix for
#[repr(Int)]enums: Edge cases with uninhabited zero-sized types changed layout. Check if your code relies on enum memory layout. - Prevent unsize-coercing into
Pin<Foo>: Coercions that produced a type with no public API are now errors. - Stop passing
--allow-undefinedon wasm targets: If your WebAssembly code relies on undefined symbols at link time, update your linker script. - Gate accidentally stabilized
#![reexport_test_harness_main]: This attribute now requires explicit opt-in. - Check const generic arguments in more positions: Code that previously compiled may now produce errors for malformed const generics.
- Remove
-Csoft-float: Use target selection to choose soft-float ABI instead. - Importing structs with
::{self as name}no longer permitted: Remove such imports that used a module parent pattern incorrectly. - For duplicate
export_name/link_name/link_sectionattributes: The first attribute now takes precedence. Previously the last one won. - Minimum external LLVM bumped to 21: If you compile rustc from source, update your LLVM.
c_doublechanged tof32on AVR targets: Match C’s 32-bit double. This breaks FFI code that assumed 64-bit.
Known Issues
- No known issues reported in official release notes.
Feature Flow
Official Release Notes
π οΈ Try These Free Tools
Paste your dependency file to check for end-of-life packages.
Plan your upgrade path with breaking change warnings and step-by-step guidance.
Get Docker base image recommendations for your requirements.
Track These Releases