Series: The Rust Annals
Vol. I Issue 74 nlopes.dev
Announcing Rust 1.73.0
Routine monthly release focusing on standard library ergonomics, integer math methods, and panic message formatting without core language or ecosystem impact.
Cleaner panic messages
The output produced by the default panic handler has been changed to put the panic message on its own line instead of wrapping it in quotes. This can make panic messages easier to read, as shown in this example:
fn main() {
let file = "ferris.txt";
panic!("oh no! {file:?} not found!");
}
Output before Rust 1.73:
thread 'main' panicked at 'oh no! "ferris.txt" not found!', src/main.rs:3:5
Output starting in Rust 1.73:
thread 'main' panicked at src/main.rs:3:5:
oh no! "ferris.txt" not found!This is especially useful when the message is long, contains nested quotes, or spans multiple lines.
Additionally, the panic messages produced by assert_eq and assert_ne have
been modified, moving the custom message (the third argument)
and removing some unnecessary punctuation, as shown below:
fn main() {
assert_eq!("🦀", "🐟", "ferris is not a fish");
}
Output before Rust 1.73:
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `"🦀"`,
right: `"🐟"`: ferris is not a fish', src/main.rs:2:5
Output starting in Rust 1.73:
thread 'main' panicked at src/main.rs:2:5:
assertion `left == right` failed: ferris is not a fish
left: "🦀"
right: "🐟"Thread local initialization
As proposed in RFC 3184, LocalKey<Cell<T>> and LocalKey<RefCell<T>> can now be directly manipulated with get(), set(), take(), and replace() methods, rather than jumping through a with(|inner| ...) closure as needed for general LocalKey work. LocalKey<T> is the type of thread_local! statics.
The new methods make common code more concise and avoid running the extra initialization code for the default value specified in thread_local! for new threads.
thread_local! {
static THINGS: Cell<Vec<i32>> = Cell::new(Vec::new());
}
fn f() {
// before:
THINGS.with(|i| i.set(vec![1, 2, 3]));
// now:
THINGS.set(vec![1, 2, 3]);
// ...
// before:
let v = THINGS.with(|i| i.take());
// now:
let v: Vec<i32> = THINGS.take();
}