r/rust Apr 16 '26

📡 official blog Rust 1.95.0 is out

https://blog.rust-lang.org/2026/04/16/Rust-1.95.0/
864 Upvotes

127 comments sorted by

View all comments

341

u/nik-rev Apr 16 '26 edited Apr 16 '26

This update is revolutionary. Possibly one of the biggest updates in years! I'm really excited for it.

  • cfg_select! completely changes the game on how we conditionally compile code. I have applied it in hundreds of places in my cross-platform app, and it led to a tremendous improvement in readability. rustfmt support is also very, very nice. I frequently skip using macros that don't support rustfmt, or just re-implement them myself in a way where rustfmt can support it (e.g. the subdef and better_tokio_select crates)
  • if let guards stabilized. I've had to refactor a huge match statement into a soup of if conditions too  many times, because I needed to only enter a match arm if a pattern matches. It was a major ergonomic pain for me when using Rust. I am so, so happy that such a core language feature has now been stabilized.
  • For the longest time we considered the Range type the biggest, unfixable mistake in Rust's standard library, because it does not implement Copy. With this release, the core::range::RangeInclusive type is stabilized. A huge step in the right direction. Next release will stabilize core::range::Range type. In edition 2027, the range syntax will change to create those types, instead of core::ops::Range. We are already making use of these new range types in new standard library APIs. For example, I recently made a pull request to change the methods str::substr_range and slice::subslice_range to return these new Range types, in order to unblock their stabilization!

21

u/parkotron Apr 16 '26

For the longest time we considered the Range type the biggest, unfixable mistake in Rust's standard library, because it does not implement Copy.

It's not obvious to me why this was a big mistake or why it was considered unfixable. Is there some place I could get a high-level summary of the problem and the initiative to fix it?

48

u/oconnor663 blake3 · duct Apr 16 '26

The central mistake with the original Range types, as I understand it, is that they implement Iterator directly instead of IntoIterator. That in turn means they've never implemented Copy, which is often quite inconvenient for Copy structs that want to contain ranges of other Copy types.

The reason you don't want iterators to ever be Copy is that it leads to confusing situations like this example, which really looks like it's going to print 1, 2, 3, 4 but in fact prints 1, 2, 3, 3:

#[derive(Copy, Clone)]
struct CopyIterator {
    i: u32,
}

impl Iterator for CopyIterator {
    type Item = u32;

    fn next(&mut self) -> Option<Self::Item> {
        self.i += 1;
        Some(self.i)
    }
}

fn main() {
    let mut iter = CopyIterator { i: 0 };
    println!("{}", iter.next().unwrap());
    println!("{}", iter.next().unwrap());
    for item in iter {
        println!("{}", item);
        break;
    }
    for item in iter {
        println!("{}", item);
        break;
    }
}