Back to Devoured - August 21, 2026
DEVOURED
Announcing Rust 1.98.0

Announcing Rust 1.98.0

DevOps Rust
Rust 1.98.0 stabilizes algebraic floating-point operations, allowing compilers to reorder calculations for optimization while maintaining predictable, undefined-behavior-free results.
What: This release introduces 'algebraic' floating-point methods (like algebraic_add) that permit the compiler to optimize mathematical expressions similarly to the -ffast-math flag in C++. It also adds format_into for integers, which avoids dynamic dispatch to improve formatting performance to near-itoa levels.
Why it matters: The inclusion of algebraic methods shows a maturation in how Rust balances strict safety and determinism with the high-performance optimization requirements of scientific and graphics computing.
Takeaway: Replace your integer formatting logic with format_into to improve performance, and consider using algebraic methods in performance-critical numerical code where floating-point order does not change output correctness.
Deep dive
  • Adds algebraic methods (add, sub, mul, div, rem) for f32/f64 to allow compiler reordering.
  • New format_into method provides high-performance, non-allocating integer formatting.
  • Fixes a long-standing interaction issue between ManuallyDrop and Box.
  • Stabilizes numerous APIs including str::substr_range and Atomic::from_mut.
  • algebraic methods are non-deterministic but strictly avoid undefined behavior.
Decoder
  • Algebraic properties: Mathematical identities (like associativity) that allow an expression to be refactored into a more efficient form without changing its conceptual result.
  • Undefined behavior (UB): Code execution that violates language safety guarantees, leading to unpredictable results and potential security vulnerabilities.
Original article

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 stable

If 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<Self> 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

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!

Explore all 58 articles in today's digest

Fresh dev news, AI-digested daily. Never miss a trend at devoured.fyi