Recent Rust Changes
In May last year I wrote a blog post on how Rust had evolved from the 1.0 release to 1.78. I found it really interesting to group all the changes together by topic, rather than seeing the language evolve one release at a time. We're now at 1.90, so I thought it was time for another update. It's only been a year and a half, but quite a lot has happened (much more than I realised before writing this post). As well as a bunch of new features (listed below), there was the 2024 edition (released in February 2025), Rust had it's 10th birthday in May, and Rust now has an official language specification in the form of the FLS.
I've picked the most exciting stuff (IMO) and summarised it below. Of course it's only a fraction of everything which has happened; in particular, there's been more std library stabilisations and const-ifications than I could possibly list. Check the release announcements on the Rust blog for full summaries of each version and for future updates.
Language
- Async closures
async |...| { ... }(1.85). letchains, i.e., usingletwith any&&clause in aniforwhileexpression (not just the first, as inif let) (1.88 and 2024).- Naked functions (1.88).
- Changes to rules around lifetimes with
impl Traitin return position (2024), and use<..>` syntax for lifetime bounds (see the chapter in the edition guide or the RFC for details) (1.82, 1.87 for trait functions). &raw ...oeprator to create a raw pointer (and to take a reference to a mutable or extern static without an unsafe block) (1.82, using non-raw&is an error in 2024).- Trait object upcasting (implicit coercion) (1.86).
unsafe externblocks andsafekeyword (1.82).unsafein attributes (1.82, error to use unsafe attributes withoutunsafein 2024).- Unsafe code inside an unsafe function requires an unsafe block (2024).
_to infer const generics arguments (1.89).- Inline const blocks, e.g.,
const { std::mem::size_of::<T>() + 1 }(1.79). - inline assembly:
constimmediates (1.82) and jumps to Rust code (1.87). - Exclusive ranges in patterns, e.g.,
match i { 0..10 => println!("9 or under"), ... }(1.80). expectlint level, e.g.,#[expect(unused)](as a better alternative to#[allow(dead_code)]) andreasonin lint attributes (1.81).- Bounds on associated types in bounds, e.g.,
trait CopyIterator: Iterator<Item: Copy> {}(1.79). #[diagnostic::do_not_recommend]attribute (1.85).- Unwinding inside an
extern(C)function now aborts (1.81). - Dereferencing or reborrowing a null raw pointer will panic rather than being undefined behaviour in debug builds (1.86).
- Lifetime extension from inside
ifandmatchblocks, e.g.,let x = if ... { &new() } ... ;is legal because the lifetime of the reference is extended to the enclosing scope, rather than being restricted to the block which is part of theifexpression (1.79). Changes to rules around temporary lifetimes forif letand the last expression in a block (2024). - No need for pattern matching branches for impossible variants (e.g, using
!orInfallible) (1.82). - Restrictions on using explicit referencing in patterns with match ergonomics (2024).
Standard library
LazyCellandLazyLock, alternatives to the lazy_static and once_cell crates (1.80).io::pipeand associated types (1.87).File::lock, etc. (1.89).Errortrait moved from std to core (1.81).- Most of the API for
NonNull(1.80, 1.84). get_disjoint_muton slices and hashmaps (1.86).Option::take_if(1.80),Option::is_none_or(1.82),Option::get_or_insert_default(1.83).collectiterators into tuples (1.85).Vec::into_flattenedandas_flattenedon arrays (1.80).Vec::pop_if(1.86) andVec::extract_if(1.87, for hashmaps in 1.88).is_sortedon various types (1.82).Cell::update(1.88).str::from_utf8(1.87).- API for uninitialised memory in
Box,Rc, andArc(1.82). next_downandnext_upon floats (1.86).- More
ControlFlowAPI (1.83). Entry::insert_entry(1.83).hint::assert_unchecked(1.81).hint::select_unpredictable(1.88).waitonOnceandOnceLock(1.86).- Rename
PanicInfotoPanicHookInfoand some panic message changes (1.81). - API for deconstructing
Wakers (1.83). - More
io::ErrorKindvariants (1.83 and 1.85). - More
proc_macro::SpanAPI (1.88). - Strict provenance for pointers (1.84).
- Improvements to sort algorithms (1.81).
FutureandIntoFutureadded to the prelude (2024).
Tooling
cargo infoto display information about a crate (1.82).- Cargo MSRV-aware resolver (1.84, default in 2024).
- Cargo automatically cleans up its cache (1.88).
cargo publish --workspace(1.90).- Checking of
cfgnames and values (1.80). - Apple ARM is a tier 1 target (1.82) and Apple intel demoted to tier 2 (1.90).
- Standard library is built with frame pointers (great for profiling!) (1.79).
- Delete crates from crates.io.
- 'Report crate' on crates.io.
- Trusted publishing and alerts in README.md on crates.io.
- rustc on Linux uses lld by default (1.90).
I currently have availability for Rust coaching, adoption, or development; from a single call to ongoing 3 days/week. I can help your team get things done, adopt Rust and use it more effectively, or to accurately evaluate Rust as a new technology.
If you're adopting Rust, I can help make that a success with advice, 1:1 or group mentoring, design and code review, or online support. Coaching.
If you're building with Rust and need a short or medium-term boost, I can join your team, quickly get up to speed, and deliver value. I have expertise with async and unsafe code, database implementation, distributed systems, dev tools, and language implementation. Consulting.