Rust Release Notes
43 release notes curated from 28 sources by the Releasebot Team. Last updated: Sep 4, 2026
- Sep 3, 2026
- Date parsed from source:Sep 3, 2026
- First seen by Releasebot:Sep 4, 2026
Rust 1.98.1
Rust fixes a miscompilation in vtable generation.
rustc: fix miscompilation in generating vtables
Original source - Sep 3, 2026
- Date parsed from source:Sep 3, 2026
- First seen by Releasebot:Sep 3, 2026
Announcing Rust 1.98.1
Rust releases 1.98.1, a point update that fixes a miscompilation in vtable generation and helps prevent undefined behavior from incorrect trait object code. It’s a stability-focused maintenance release for users updating via rustup.
The Rust team has published a new point release of Rust, 1.98.1. Rust is a programming language that is empowering everyone to build reliable and efficient software.
If you have a previous version of Rust installed via rustup, getting Rust 1.98.1 is as easy as:
rustup update stableIf you don't have it already, you can get rustup from the appropriate page on our website.
What's in 1.98.1
Rust 1.98.1 fixes a miscompilation in vtable generation.
In Rust 1.98.0, in some circumstances, rustc would incorrectly generate a trait object vtable with a null pointer where a function pointer should be. This leads to undefined behavior in the emitted code. In some cases this may 'just' cause segfaults due to the null pointer being loaded, but it is possible for it to be justification for arbitrary effects (as is typical for UB).
If you'd like to help us out by testing future releases, you might consider using the beta (rustup default beta) and nightly (rustup default nightly) channels locally and in your CI. Please report any bugs you might come across!
Contributors to 1.98.1
Many people came together to create Rust 1.98.1. We couldn't have done it without all of you. Thanks!
Original source All of your release notes in one feed
Join Releasebot and get updates from Rust and hundreds of other software products.
- Aug 20, 2026
- Date parsed from source:Aug 20, 2026
- First seen by Releasebot:Aug 20, 2026
Rust 1.98.0
Rust releases a broad language and library update with new lifetime coercion behavior, fresh lints, expanded platform support, and many stabilized APIs. It also tightens compatibility checks, improves formatting and diagnostics, and makes several target and platform changes.
Language
Allow shortening lifetime of &mut when unsize-coercing, even in an invariant position. For example, you can now coerce a Cell<&'long mut i32> to a Cell<&'short mut dyn Send>. Such shortenings were already previously allowed when coercing a &mut to a &, or coercing a & to a &.
Add deny-by-default invalid_runtime_symbol_definitions lint and warn-by-default suspicious_runtime_symbol_definitions lint
The lints currently specifically targets core runtime symbols like memcmp, memset, strlen, ... and is planned to be expanded in the next few releases.
Add warn-by-default c_void_returns lint to check core::ffi::c_void as a return type
Platform Support
Add powerpc64-unknown-linux-gnuelfv2 as Tier 3
Add aarch64-unknown-linux-pauthtest as Tier 3 target
Promote thumbv7a-none-eabi to Tier 2
Promote thumbv7a-none-eabihf to Tier 2
Promote thumbv7r-none-eabi to Tier 2
Promote thumbv7r-none-eabihf to Tier 2
Promote thumbv8r-none-eabihf to Tier 2
Refer to Rust's platform support page for more information on Rust's tiered platform support.
Libraries
Change Location<'_> lifetime to 'static in Panic[Hook]Info
Document panic in RangeInclusive::from(legacy::RangeInclusive)
Document that ManuallyDrop's Box interaction has been fixed
Stabilize LoongArch CRC Intrinsics
The derive macro is available at {core,std}::derive. This was previously unintentionally stabilized in 1.96, but is now explicitly accepted as a stabilized API.
Please note that the MSRV for {core,std}::derive will be 1.96, and not 1.98.
Stabilized APIs
str::substr_range
core::fmt::NumBuffer
<{integer}>::format_into
Send/Sync for std::process::CommandArgs
{fN}::algebraic_add
{fN}::algebraic_sub
{fN}::algebraic_mul
{fN}::algebraic_div
{fN}::algebraic_rem
NonZero<{integer}>::from_str_radix
String::from_utf16le
String::from_utf16le_lossy
String::from_utf16be
String::from_utf16be_lossy
str::strip_circumfix
Atomic<T>::from_mut
Atomic<T>::get_mut_slice
Atomic<T>::from_mut_slice
std::range::legacy
Compatibility Notes
If fully elided, lifetime bounds of trait object types may now resolve differently or even get rejected in very specific niche scenarios
Error in more cases of ambiguous imports
Switch the destructors implementation for thread locals on Windows to use Fiber Local Storage (FLS)
Convert some cases of the ambiguous_glob_imports lint into a hard error
Where-bounds of the form Type = Type and Type == Type are no longer syntactically allowed
Ensure Send/Sync is not implemented for std::env::Vars{,Os}
Fix that in some attributes, arguments were not properly rejected
repr(transparent) is now more strict about which fields have "trivial" layout and hence can be ignored: repr(C) types, types with private fields, and #[non_exhaustive] types are no longer considered "trivial"
Correctly check whether types have equal size in transmute() when some repr attributes are involved.
More characters are escaped when printing strings and chars
Implement fast path for derive(PartialOrd) when deriving Ord This can break crates in practice where a type's PartialOrd and Ord impls were inconsistent with each other.
Add temporary scope to assert_eq and assert_ne
Closed a hole in the pattern matching structural equality check, preventing cases where a match of a constant would be allowed, despite disagreeing with a manually written PartialEq implementation, when a derive(PartialEq) implementation for that type also exists.
On Emscripten the WASM exception handling ABI is now unconditionally used The -Zemscripten-wasm-eh=false flag to switch back to JS exceptions has been removed.
The UNSAFE_CODE lint is now consistently emitted for all unsafe attributes
Solaris: remove File::lock implementation, it has the wrong semantics (return "unsupported" instead)
Windows-gnu targets now specify baseline tools versions
rustfmt now discovers module files that are defined in cfg_select! This may cause more code to be formatted which was previously ignored.
Original source - Aug 20, 2026
- Date parsed from source:Aug 20, 2026
- First seen by Releasebot:Aug 20, 2026
Announcing Rust 1.98.0
Rust releases 1.98.0 with algebraic floating-point methods, faster buffered integer formatting, and updated ManuallyDrop and Box safety docs, alongside a wide set of stabilized APIs and language improvements.
The Rust team is happy to announce a new version of Rust, 1.98.0. Rust is a programming language empowering everyone to build reliable and efficient software.
If you have a previous version of Rust installed via rustup, you can get 1.98.0 with:
$ rustup update stableIf you don't have it already, you can get rustup from the appropriate page on our website, and check out the detailed release notes for 1.98.0.
If you'd like to help us out by testing future releases, you might consider updating locally to use the beta channel (
rustup default beta) or the nightly channel (rustup default nightly). Please report any bugs you might come across!What's in 1.98.0 stable
Algebraic floating-point methods
The floating-point types f32 and f64 now have "algebraic" methods for addition, subtraction, multiplication, division, and remainder. These allow optimizations on these operations using the algebraic properties of real numbers, even though these properties do not hold with the limitations of floating-point representations. The exact set of optimizations is not specified, but may be similar to the kind of optimization you would see with the -ffast-math option in other languages.
For example, floating-point addition is not associative, so a sum like a + b + c + d must be evaluated in the left-associative order in which it is parsed, like ((a + b) + c) + d. If you write the same sum as a chain of algebraic_add calls, then the compiler is free to reorder it, perhaps like (a + b) + (c + d) to evaluate the partial sums simultaneously. Broader loop-vectorization is often enabled by using these algebraic methods as well.
These methods are non-deterministic, since the compiler is free to choose different optimizations, but they never cause undefined behavior. See the library documentation and the original API change proposal for more details.
Buffered integer formatting
All of the primitive integer types now have a format_into method that takes a &mut NumBuffer parameter, which is a buffer that is large enough to hold the decimal format of any value of that type. The buffer itself is opaque, but the method returns the formatted &str with a lifetime borrowed from that buffer.
This method also bypasses much of the dynamic dispatch that you would get with buffered write! formatting, which can be a boon to performance. The itoa-benchmark repo now shows that format_into performs similarly to itoa itself, so this could serve as a standard replacement for that dependency and others like it.
Fix interaction between ManuallyDrop and Box
Prior to Rust 1.96.0, there was a bug in the Rust compiler, which made the following code undefined behavior:
let mut x = ManuallyDrop::new(Box::new(1)); unsafe { ManuallyDrop::drop(&mut x) } let x = x; // UB!This is because the compiler considers it undefined behavior to move a Box that has been dropped (deallocated), and ManuallyDrop used to propagate that, such that moving ManuallyDrop<Box<_>> where the box has been dropped would also be considered UB.
In Rust 1.96.0 we fixed this, so this code was no longer UB. In this release we have updated the ManuallyDrop documentation, providing a stable guarantee that this code will continue to not be UB in the future. See ManuallyDrop docs and the related RFC 3336 for more information.
Stabilized APIs
- str::substr_range
- core::fmt::NumBuffer
- <{integer}>::format_into
- Send/Sync for std::process::CommandArgs
- {fN}::algebraic_add
- {fN}::algebraic_sub
- {fN}::algebraic_mul
- {fN}::algebraic_div
- {fN}::algebraic_rem
- NonZero<{integer}>::from_str_radix
- String::from_utf16le
- String::from_utf16le_lossy
- String::from_utf16be
- String::from_utf16be_lossy
- str::strip_circumfix
- Atomic::from_mut
- Atomic::get_mut_slice
- Atomic::from_mut_slice
- std::range::legacy
Other changes
Check out everything that changed in Rust, Cargo, and Clippy.
Contributors to 1.98.0
Many people came together to create Rust 1.98.0. We couldn't have done it without all of you. Thanks!
Original source - Jul 16, 2026
- Date parsed from source:Jul 16, 2026
- First seen by Releasebot:Jul 17, 2026
Announcing Rust 1.97.1
Rust releases 1.97.1, a point update that fixes an LLVM-related miscompilation and backports a safeguard in generated IR, improving compiler reliability for users on stable.
The Rust team has published a new point release of Rust, 1.97.1. Rust is a programming language that is empowering everyone to build reliable and efficient software.
If you have a previous version of Rust installed via rustup, getting Rust 1.97.1 is as easy as:
rustup update stableIf you don't have it already, you can get rustup from the appropriate page on our website.
What's in 1.97.1
Rust 1.97.1 fixes a miscompilation in an LLVM optimization.
We have backported both an LLVM fix and a disable of the underlying change in Rust 1.97.0 of Rust's generated IR that increased the likelihood of this happening. However, note that the underlying miscompilation has been present since at least Rust 1.87.
If you'd like to help us out by testing future releases, you might consider running your code's CI or locally using the beta channel (rustup default beta) or the nightly channel (rustup default nightly). Please report any bugs you might come across!
Contributors to 1.97.1
Many people came together to create Rust 1.97.1. We couldn't have done it without all of you. Thanks!
Original source Similar to Rust with recent updates:
- Figma release notes155 release notes · Latest Sep 3, 2026
- Perplexity release notes30 release notes · Latest Aug 24, 2026
- Ollama release notes99 release notes · Latest Sep 5, 2026
- Smokeball release notes144 release notes · Latest Sep 4, 2026
- Salesforce release notes71 release notes · Latest Sep 1, 2026
- Microsoft release notes820 release notes · Latest Sep 4, 2026
- Jul 16, 2026
- Date parsed from source:Jul 16, 2026
- First seen by Releasebot:Jul 17, 2026
Rust 1.97.1
Rust fixes a rustc miscompilation by backporting an LLVM fix and reverting a trigger change.
rustc: Fix miscompilation in LLVM optimization
This backports an LLVM submodule bump to include the LLVM-side fix and a revert of the rustc change that is one known trigger for the bug. The rustc side revert should not be strictly necessary but is done out of abundance of caution.
Original source - Jul 9, 2026
- Date parsed from source:Jul 9, 2026
- First seen by Releasebot:Jul 10, 2026
Announcing Rust 1.97.0
Rust releases 1.97.0 with default v0 symbol mangling, Cargo warning controls, and linker messages now shown by default. It also stabilizes several APIs and expands const support, making this a practical update focused on cleaner builds and better diagnostics.
The Rust team is happy to announce a new version of Rust, 1.97.0. Rust is a programming language empowering everyone to build reliable and efficient software.
If you have a previous version of Rust installed via rustup, you can get 1.97.0 with:
$ rustup update stableIf you don't have it already, you can get rustup from the appropriate page on our website, and check out the detailed release notes for 1.97.0.
If you'd like to help us out by testing future releases, you might consider updating locally to use the beta channel (rustup default beta) or the nightly channel (rustup default nightly). Please report any bugs you might come across!
What's in 1.97.0 stable
Symbol mangling v0 enabled by default
When Rust is compiled into object files and binaries, each item (functions, statics, etc) must have a globally unique "symbol" identifying it. To avoid conflicts when linking together different Rust programs, Rust mangles the original name of items to include additional context such as the module path, defining crate, generics, and more. Historically, this mangling was based on the Itanium ABI, also (sometimes) used by C++.
The new mangling scheme resolves a number of drawbacks from the previous one:
- Generic parameter instantiations preserve their values, rather than being tracked solely behind a hash
- Inconsistencies: not all parts used the Itanium ABI, meaning that custom demangling was still necessary
Since Rust 1.59, the compiler has supported opting into a Rust-specific mangling scheme via -Csymbol-mangling-version=v0. Since November 2025, this scheme has been enabled by default on nightly, and 1.97 is now enabling it on stable Rust. The legacy mangling scheme can only be enabled on nightly, and the current plan is to fully remove it.
See the previous blog post for more details.
Cargo support for denying warnings
It's common practice to deny warnings in CI. Historically, doing so is typically done through RUSTFLAGS=-Dwarnings. With Rust 1.97, Cargo controls how warnings interact with build success: either silencing them (via allow level), rendering without failing (default, warn), or denying them (via deny).
As a result of Cargo configuration determining the behavior, using this feature doesn't invalidate the underlying build cache, meaning that it's easy to temporarily opt-in. For example, if warnings are adding unwanted noise while working through fixing errors after a refactor, you can run CARGO_BUILD_WARNINGS=allow cargo check, temporarily silencing them.
In CI, jobs can instead set CARGO_BUILD_WARNINGS=deny to deny warnings. This can be combined with --keep-going to collect all errors and warnings rather than stopping on the first failing package.
See the documentation for more details.
Linker output no longer hidden by default
rustc invokes a linker on behalf of users. Historically, rustc has silenced linker output by default if the link completes successfully. This can mask real problems, though, so in Rust 1.97 we are enabling linker messages by default. These are emitted as a warning lint, for example:
warning: linker stderr: ignoring deprecated linker optimization setting '1' = note: `#[warn(linker_messages)]` on by defaultCommon linker messages that have been diagnosed as false positives or intentional behavior are filtered out by rustc. Several defects have already been fixed as a result of no longer hiding this output on nightly.
Note that currently, linker_messages is a special lint that is not affected by the warnings lint group. This is intentional as rustc generally doesn't control linker output as precisely, and it's not uncommon for output to only appear on some platforms. If you are seeing what you think is a false positive output from the linker, please file an issue.
To silence the warning in the mean time, you can configure the lint level to allow. This can be done through Cargo.toml by adding a lints section like this:
[lints.rust] linker_messages = "allow"Stabilized APIs
- Default for RepeatN
- Copy for ffi::FromBytesUntilNulError
- Send for std::fs::File on UEFI
- <{integer}>::isolate_highest_one
- <{integer}>::isolate_lowest_one
- <{integer}>::highest_one
- <{integer}>::lowest_one
- <{uN}>::bit_width
- NonZero<{integer}>::isolate_highest_one
- NonZero<{integer}>::isolate_lowest_one
- NonZero<{integer}>::highest_one
- NonZero<{integer}>::lowest_one
- NonZero<{uN}>::bit_width
These previously stable APIs are now stable in const contexts:
- char::is_control
Other changes
Check out everything that changed in Rust, Cargo, and Clippy.
Contributors to 1.97.0
Many people came together to create Rust 1.97.0. We couldn't have done it without all of you. Thanks!
Original source - Jul 9, 2026
- Date parsed from source:Jul 9, 2026
- First seen by Releasebot:Jul 10, 2026
Rust 1.97.0
Rust releases a broad toolchain update with new lint and Cargo controls, more stabilized APIs and target features, Rustdoc flag support, and platform tweaks. It also tightens diagnostics, fixes pin! coercions, and updates symbol mangling and Windows socket behavior.
Language
Consider Result<T, Uninhabited> and ControlFlow<Uninhabited, T> to be equivalent to T for must use lint
Add allow-by-default dead_code_pub_in_binary lint for unused pub items in binary crates
Stabilize the div32, lam-bh, lamcas, ld-seq-sa and scq target features
Stabilize cfg(target_has_atomic_primitive_alignment)
Allow trailing self in imports in more cases
Platform Support
nvptx64-nvidia-cuda: drop support for old architectures and old ISAs
Refer to Rust's platform support page for more information on Rust's tiered platform support.
Stabilized APIs
Default for RepeatN
Copy for ffi::FromBytesUntilNulError
Send for std::fs::File on UEFI
<{integer}>::isolate_highest_one
<{integer}>::isolate_lowest_one
<{integer}>::highest_one
<{integer}>::lowest_one
<{integer}>::bit_width
NonZero<{integer}>::isolate_highest_one
NonZero<{integer}>::isolate_lowest_one
NonZero<{integer}>::highest_one
NonZero<{integer}>::lowest_one
NonZero<{integer}>::bit_width
These previously stable APIs are now stable in const contexts:
char::is_control
Cargo
Stabilize build.warnings config. This controls how lint warnings from local packages are treated. Useful for enforcing a warning-free build in CI, replacing -Dwarnings. docs
Stabilize resolver.lockfile-path config. This allows specifying the path to the lockfile to use when resolving dependencies. Useful when working with read-only source directories. docs
cargo-clean: Error when --target-dir doesn't look like a Cargo target directory. This prevents accidental deletion of non-target directories.
Add -m shorthand for --manifest-path
Remove curl dependency from crates-io crate
Rustdoc
Stabilize --emit flag
Stabilize --remap-path-prefix
Compatibility Notes
Emit a future-compatibility warning when relying on f32: From<{float}> to constrain {float}
Rust will use the v0 symbol mangling scheme by default. This may cause some tools (such as debuggers or profilers, especially with old versions) to fail to demangle symbols emitted by Rust. It may also cause the formatting of text in backtraces to change.
Prevent deref coercions in pin!, in order to prevent unsoundness. The most likely case where this might impact users is: writing pin!(x) where x has type &mut T will now always correctly produce a value of type Pin<&mut &mut T>, instead of sometimes allowing a coercion that produces a value of type Pin<&mut T>. This coercion was previously incorrectly allowed since Rust 1.88.0.
Deprecate std::char constants and functions
Warn on linker output by default
Remove hidden f64 methods which have been deprecated since 1.0
report the varargs_without_pattern lint in deps
Forbid passing generic arguments to module path segments even if the module reexports a generic enum variant
Error on invalid macho link_section specifier
The encoding of certain enums have changed. This is not a breaking change, as it only applies to enums without layout guarantees, but is noted here as we've seen people impacted from having made assumptions about the layout algorithm.
Error on #[export_name = "..."] where the name is empty
Syntactically reject tuple index shorthands in struct patterns
validate #[link_name = "..."] & #[link(name = "...")] parameters
On Windows, after calling shutdown on a socket to shut down the write side, attempting to write to the socket will now produce a BrokenPipe error rather than Other. Map WSAESHUTDOWN to io::ErrorKind::BrokenPipe
Original source - Jul 5, 2026
- Date parsed from source:Jul 5, 2026
- First seen by Releasebot:Jul 6, 2026
Rust 1.96.1
Rust fixes Cargo timeout retries, patches libssh2 CVEs, and repairs a rustc MIR miscompilation.
Cargo
Cargo: fix timeout/retry behavior
Cargo: apply patches for CVE-2025-15661, CVE-2026-55199, and CVE-2026-55200 to libssh2
rustc
rustc: fix miscompilation in MIR optimization
Original source - Jun 30, 2026
- Date parsed from source:Jun 30, 2026
- First seen by Releasebot:Jun 30, 2026
Announcing Rust 1.96.1
Rust ships a new point release, 1.96.1, with fixes for Cargo HTTP client retries and timeouts, a MIR optimization miscompilation, and three libssh2 CVEs affecting Cargo. It is a focused stability and security update for users on the stable channel.
The Rust team has published a new point release of Rust, 1.96.1. Rust is a programming language that is empowering everyone to build reliable and efficient software.
If you have a previous version of Rust installed via rustup, getting Rust 1.96.1 is as easy as:
rustup update stableIf you don't have it already, you can get rustup from the appropriate page on our website.
What's in 1.96.1
Rust 1.96.1 fixes:
- Missing retries / timeouts in Cargo's HTTP client
- Miscompilation in a MIR optimization
It also fixes three CVEs affecting libssh2 (which is compiled into Cargo):
- CVE-2025-15661
- CVE-2026-55199
- CVE-2026-55200
Contributors to 1.96.1
Many people came together to create Rust 1.96.1. We couldn't have done it without all of you. Thanks!
Original source - Jun 30, 2026
- Date parsed from source:Jun 30, 2026
- First seen by Releasebot:Jun 30, 2026
- May 28, 2026
- Date parsed from source:May 28, 2026
- First seen by Releasebot:May 29, 2026
Announcing Rust 1.96.0
Rust releases 1.96.0 with stable new range types, helpful assert_matches macros, and a WebAssembly linking change that catches undefined symbols earlier. It also includes Cargo security fixes for third-party registries and other stabilization updates.
The Rust team is happy to announce a new version of Rust, 1.96.0. Rust is a programming language empowering everyone to build reliable and efficient software.
If you have a previous version of Rust installed via rustup, you can get 1.96.0 with:
$ rustup update stableIf you don't have it already, you can get rustup from the appropriate page on our website, and check out the detailed release notes for 1.96.0.
If you'd like to help us out by testing future releases, you might consider updating locally to use the beta channel (rustup default beta) or the nightly channel (rustup default nightly). Please report any bugs you might come across!
What's in 1.96.0 stable
New Range* types
Many users expect Range and related core::ops types to be Copy, but this is not the case: they implement Iterator directly, and it is a footgun to implement both Iterator and Copy on the same type so this has been avoided. RFC3550 proposed a set of replacement range types that implement IntoIterator rather than Iterator, meaning they can also be Copy. The standard library portion of that RFC is now stable, introducing:
- core::range::Range
- core::range::RangeFrom
- core::range::RangeInclusive
- Associated iterators
A Rust version in the near future will also add core::range::RangeFull and core::range::RangeTo as re-exports from core::ops (these do not implement Iterator and already implement Copy), and core::range::legacy::* as the new home for the current ranges. Range syntax like 0..1 still produces the legacy types for now, but will be updated to core::range types in a future edition.
With these stabilizations, it is now possible to store slice accessors in Copy types without splitting start and end:
use core::range::Range; # [derive(Clone, Copy)] pub struct Span(Range<usize>); impl Span { pub fn of(self, s: &str) -> &str { &s[self.0] } }The new RangeInclusive also makes its fields public, unlike the legacy version which avoided exposing the exhausted iterator state. This isn't a concern with the new type since it must be converted to begin iteration.
Library authors should consider making use of impl RangeBounds in public API, which accepts both legacy and new range types. If a concrete type is needed, prefer using new ranges as this will eventually become the default.
Assert matching patterns
The new macros assert_matches! and debug_assert_matches! check that a value matches a given pattern, panicking with a Debug representation of the value otherwise. These are essentially the same as assert!(matches!(..)) and debug_assert!(matches!(..)), but the printed value improves the possibility of diagnosing the failure.
These new macros have not been added to the standard prelude, because they would collide with popular third-party crates that provide macros with the same name. Instead, they should be manually imported from core or std before use.
use core::assert_matches!; /// [Random Number](https://xkcd.com/221/) fn get_random_number() -> u32 { // chosen by a fair dice roll. // guaranteed to be random. 4 } fn main() { assert_matches!(get_random_number(), 1..=6); }Changes to WebAssembly targets
WebAssembly targets no longer pass --allow-undefined to the linker which means that undefined symbols when linking are now a linker error instead of being converted to WebAssembly imports from the "env" module. This change prevents modules from linking unless all linking-related symbols are defined to catch bugs earlier and prevent accidental issues with symbol naming or similar.
Undefined linking-related symbols are often indicative of build-time related bugs or misconfiguration. If, however, the old behavior is intended then it can be re-enabled with RUSTFLAGS=-Clink-arg=--allow-undefined or by editing the source code and using #[link(wasm_import_module = "env")] on the block defining the symbol.
This change was previously announced on this blog, and now takes effect in Rust 1.96.
Stabilized APIs
- assert_matches!
- debug_assert_matches!
- From for AssertUnwindSafe
- From for LazyCell<T, F>
- From for LazyLock<T, F>
- core::range::RangeToInclusive
- core::range::RangeToInclusiveIter
- core::range::RangeFrom
- core::range::RangeFromIter
- core::range::Range
- core::range::RangeIter
Two Cargo advisories
Rust 1.96 contains fixes for two vulnerabilities for users of third-party registries.
- CVE-2026-5223 is a medium severity vulnerability regarding extraction of crate tarballs with symlinks.
- CVE-2026-5222 is a low severity vulnerability regarding authentication with normalized URLs.
Users of crates.io are not affected by either vulnerability.
Other changes
Check out everything that changed in Rust, Cargo, and Clippy.
Contributors to 1.96.0
Many people came together to create Rust 1.96.0. We couldn't have done it without all of you.
Thanks!
Original source - May 28, 2026
- Date parsed from source:May 28, 2026
- First seen by Releasebot:May 29, 2026
Rust 1.96.0
Rust ships a broad release with compiler, Cargo, rustdoc, and library improvements, including new stabilized APIs, better target and assembly support, dependency publishing flexibility, security fixes, and several compatibility and diagnostics updates.
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 ManuallyDrop as patterns (fixing a regression introduced in 1.94.0)
Compiler
- Enable link relaxation feature for LoongArch Linux targets
- Update riscv64gc-unknown-fuchsia baseline to RVA22 + vector
Libraries
- Support iterating over ranges of NonZero integers
- refactor 'valid for read/write' definition: exclude null; add that as an exception on individual methods instead
- Fix SGX delayed host lookup via ToSocketAddr
Stabilized APIs
- assert_matches!
- debug_assert_matches!
- From<T> for AssertUnwindSafe<T>
- From<T> for LazyCell<T, F>
- From<T> for LazyLock<T, F>
- core::range::RangeToInclusive
- core::range::RangeToInclusiveIter
- core::range::RangeFrom
- core::range::RangeFromIter
- core::range::Range
- core::range::RangeIter
Cargo
- Allow a dependency to specify both a git repository and an alternate registry. Just like with crates.io, the git repository will be used locally, but the registry version will be used when published.
- Added target.'cfg(..)'.rustdocflags support in configuration.
- Fixed CVE-2026-5222 and CVE-2026-5223.
Rustdoc
- Deprecation notes are now rendered like any other documentation. Previously they used the css white-space: pre-wrap; property and stripped any <p> elements from the rendered html, however this caused issues and unintuitive behavior. The new behavior should be more predictable, however some multi-line deprecation notes will now be rendered as as single lines. If this is undesirable, you can use the standard markdown method of forcing a linebreak, which is two spaces followed by a newline ("\n").
- Don't emit rustdoc missing_doc_code_examples lint on impl items
- Seperate methods and associated functions in sidebar
Compatibility Notes
- Fix layout of #[repr(Int)] enums in some edge cases involving fields of uninhabited zero-sized types
- Prevent unsize-coercing into Pin<Foo> where Foo doesn't implement Deref. Some such coercions were previously allowed, but produce a type with no useful public API.
- rustc: Stop passing --allow-undefined on wasm targets
- Gate the accidentally stabilized #![reexport_test_harness_main] attribute
- Error on return-position-impl-trait-in-traits whose types are too private
- Report the uninhabited_static lint in dependencies and make it deny-by-default
- Distributed builds now contain non-split debuginfo for windows-gnu This appears to improve the quality of backtraces. This change has no effect on the defaults for the output of rustc/cargo on these targets.
- Check const generic arguments are correctly typed in more positions
- Remove -Csoft-float
- Importing structs with ::{self [as name]}, e.g., struct S {}; use S::{self as Other};, is now no longer permitted because {self} imports require a module parent.
- For export_name, link_name, and link_section attributes, if multiple of the same attribute is present, the first one now takes precedence.
- Update the minimum external LLVM to 21
- On avr targets, C's double type is 32-bit by default, so change c_double to f32 on avr targets to match. This is a breaking change, but necessary to make c_double match C's double.
Internal Changes
These changes do not affect any public interfaces of Rust, but they represent significant improvements to the performance or internals of rustc and related tools.
- JSON targets: aarch64 softfloat targets now have to have rustc_abi set to "softfloat"
- target specs: stricter checks for LLVM ABI values, and correlate that with cfg(target_abi)
- Apr 16, 2026
- Date parsed from source:Apr 16, 2026
- First seen by Releasebot:May 23, 2026
Announcing Rust 1.95.0
Rust releases 1.95.0 with new cfg_select! macro, if-let guards in match expressions, and a broad set of stabilized APIs. It also expands const-context support and removes stable support for custom JSON target specs.
The Rust team is happy to announce a new version of Rust, 1.95.0. Rust is a programming language empowering everyone to build reliable and efficient software.
If you have a previous version of Rust installed via rustup, you can get 1.95.0 with:
$ rustup update stableIf you don't have it already, you can get rustup from the appropriate page on our website, and check out the detailed release notes for 1.95.0.
If you'd like to help us out by testing future releases, you might consider updating locally to use the beta channel (rustup default beta) or the nightly channel (rustup default nightly). Please report any bugs you might come across!
What's in 1.95.0 stable
cfg_select!
Rust 1.95 introduces a cfg_select! macro that acts roughly similar to a compile-time match on cfgs. This fulfills the same purpose as the popular cfg-if crate, although with a different syntax. cfg_select! expands to the right-hand side of the first arm whose configuration predicate evaluates to true. Some examples:
cfg_select! { unix => { fn foo() { /* unix specific functionality */ } } target_pointer_width = "32" => { fn foo() { /* non-unix, 32-bit functionality */ } } _ => { fn foo() { /* fallback implementation */ } } } let is_windows_str = cfg_select! { windows => "windows", _ => "not windows", };if-let guards in matches
Rust 1.88 stabilized let chains. Rust 1.95 brings that capability into match expressions, allowing for conditionals based on pattern matching.
match value { Some(x) if let Ok(y) = compute(x) => { // Both `x` and `y` are available here println!("{},{}", x, y); } _ => {} }Note that the compiler will not currently consider the patterns matched in if let guards as part of the exhaustiveness evaluation of the overall match, just like if guards.
Stabilized APIs
- MaybeUninit<[T; N]>: From<[MaybeUninit; N]>
- MaybeUninit<[T; N]>: AsRef<[MaybeUninit; N]>
- MaybeUninit<[T; N]>: AsRef<[MaybeUninit]>
- MaybeUninit<[T; N]>: AsMut<[MaybeUninit; N]>
- MaybeUninit<[T; N]>: AsMut<[MaybeUninit]>
- [MaybeUninit; N]: From<MaybeUninit<[T; N]>>
- Cell<[T; N]>: AsRef<[Cell; N]>
- Cell<[T; N]>: AsRef<[Cell]>
- Cell<[T]>: AsRef<[Cell]>
- bool: TryFrom<{integer}>
- AtomicPtr::update
- AtomicPtr::try_update
- AtomicBool::update
- AtomicBool::try_update
- AtomicIn::update
- AtomicIn::try_update
- AtomicUn::update
- AtomicUn::try_update
- cfg_select!
- mod core::range
- core::range::RangeInclusive
- core::range::RangeInclusiveIter
- core::hint::cold_path
- <*const T>::as_ref_unchecked
- <*mut T>::as_ref_unchecked
- <*mut T>::as_mut_unchecked
- Vec::push_mut
- Vec::insert_mut
- VecDeque::push_front_mut
- VecDeque::push_back_mut
- VecDeque::insert_mut
- LinkedList::push_front_mut
- LinkedList::push_back_mut
- Layout::dangling_ptr
- Layout::repeat
- Layout::repeat_packed
- Layout::extend_packed
These previously stable APIs are now stable in const contexts:
- fmt::from_fn
- ControlFlow::is_break
- ControlFlow::is_continue
Destabilized JSON target specs
Rust 1.95 removes support on stable for passing a custom target specification to rustc. This should not affect any Rust users using a fully stable toolchain, as building the standard library (including just core) already required using nightly-only features.
We're also gathering use cases for custom targets on the tracking issue as we consider whether some form of this feature should eventually be stabilized.
Other changes
Check out everything that changed in Rust, Cargo, and Clippy.
Contributors to 1.95.0
Many people came together to create Rust 1.95.0. We couldn't have done it without all of you. Thanks!
Original source - Apr 16, 2026
- Date parsed from source:Apr 16, 2026
- First seen by Releasebot:May 23, 2026
Rust 1.95.0
Rust releases a broad language and tooling update with new stabilized APIs, const-eval and pattern-matching improvements, rustdoc search and deprecation settings, platform support expansions, performance boosts, and security fixes for vendored musl and compiler behavior.
Language
Stabilize if let guards on match arms
irrefutable_let_patterns lint no longer lints on let chains
Support importing path-segment keywords with renaming
Stabilize inline assembly for PowerPC and PowerPC64
const-eval: be more consistent in the behavior of padding during typed copies
Const blocks are no longer evaluated to determine if expressions involving fallible operations can implicitly be constant-promoted.. Expressions whose ability to implicitly be promoted would depend on the result of a const block are no longer implicitly promoted.
Make operational semantics of pattern matching independent of crate and module
Compiler
Stabilize --remap-path-scope for controlling the scoping of how paths get remapped in the resulting binary
Apply patches for CVE-2026-6042 and CVE-2026-40200 to vendored musl
Platform Support
Promote powerpc64-unknown-linux-musl to Tier 2 with host tools
Promote aarch64-apple-tvos to Tier 2
Promote aarch64-apple-tvos-sim to Tier 2
Promote aarch64-apple-watchos to Tier 2
Promote aarch64-apple-watchos-sim to Tier 2
Promote aarch64-apple-visionos to Tier 2
Promote aarch64-apple-visionos-sim to Tier 2
Refer to Rust's platform support page for more information on Rust's tiered platform support.
Libraries
thread::scope: document how join interacts with TLS destructors
Speed up str::contains on aarch64 targets with neon target feature enabled by default
Stabilized APIs
MaybeUninit<[T; N]>: From<[MaybeUninit<T>; N]>
MaybeUninit<[T; N]>: AsRef<[MaybeUninit<T>; N]>
MaybeUninit<[T; N]>: AsRef<[MaybeUninit<T>]>
MaybeUninit<[T; N]>: AsMut<[MaybeUninit<T>; N]>
MaybeUninit<[T; N]>: AsMut<[MaybeUninit<T>]>
[MaybeUninit<T>; N]: From<MaybeUninit<[T; N]>>
Cell<[T; N]>: AsRef<[Cell<T>; N]>
Cell<[T; N]>: AsRef<[Cell<T>]>
Cell<[T]>: AsRef<[Cell<T>]>
bool: TryFrom<{integer}>
AtomicPtr::update
AtomicPtr::try_update
AtomicBool::update
AtomicBool::try_update
AtomicIn::update
AtomicIn::try_update
AtomicUn::update
AtomicUn::try_update
cfg_select!
mod core::range
core::range::RangeInclusive
core::range::RangeInclusiveIter
core::hint::cold_path
<*const T>::as_ref_unchecked
<*mut T>::as_ref_unchecked
<*mut T>::as_mut_unchecked
Vec::push_mut
Vec::insert_mut
VecDeque::push_front_mut
VecDeque::push_back_mut
VecDeque::insert_mut
LinkedList::push_front_mut
LinkedList::push_back_mut
Layout::dangling_ptr
Layout::repeat
Layout::repeat_packed
Layout::extend_packed
These previously stable APIs are now stable in const contexts:
fmt::from_fn
ControlFlow::is_break
ControlFlow::is_continue
Rustdoc
In search results, rank unstable items lower
Add new "hide deprecated items" setting in rustdoc
Compatibility Notes
Array coercions may now result in less inference constraints than before
Importing $crate without renaming, i.e. use $crate::{self};, is now no longer permitted due to stricter error checking for self imports.
const-eval: be more consistent in the behavior of padding during typed copies. In very rare cases, this may cause compilation errors due to bytes from parts of a pointer ending up in the padding bytes of a const or static.
A future-incompatibility warning lint ambiguous_glob_imported_traits is now reported when using an ambiguously glob imported trait
Check lifetime bounds of types mentioning only type parameters
Report more visibility-related ambiguous import errors
Deprecate Eq::assert_receiver_is_total_eq and emit future compatibility warnings on manual impls
powerpc64: Use the ELF ABI version set in target spec instead of guessing (fixes the ELF ABI used by the OpenBSD target)
Matching on a #[non_exhaustive] enum now reads the discriminant, even if the enum has only one variant. This can cause closures to capture values that they previously wouldn't.
mut ref and mut ref mut patterns, part of the unstable Match Ergonomics 2024 RFC, were accidentally allowed on stable within struct pattern field shorthand. These patterns are now correctly feature-gated as unstable in this position.
Add future-compatibility warning for derive helper attributes which conflict with built-in attributes
JSON target specs have been destabilized and now require -Z unstable-options to use. Previously, they could not be used without the standard library, which has no stable build mechanism. In preparation for the build-std project adding that support, JSON target specs are being proactively gated to ensure they remain unstable even if build-std is stabilized. Cargo now includes the -Z json-target-spec CLI flag to automatically pass -Z unstable-options to the compiler when needed. See #150151, #151534, and rust-lang/cargo#16557.
The arguments of #[feature] attributes on invalid targets are now checked
Internal Changes
These changes do not affect any public interfaces of Rust, but they represent significant improvements to the performance or internals of rustc and related tools.
Update to LLVM 22
Original source
Curated by the Releasebot team
Releasebot is an aggregator of official release notes from hundreds of software vendors and thousands of sources.
Our editorial process involves the manual review and audit of release notes procured with the help of automated systems.