The Rust team is happy to announce a new version of Rust, 1.61.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.61.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.61.0 on GitHub.
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.61.0 stable
main
Custom exit codes from In the beginning, Rust main
functions could only return the unit type ()
(either implicitly or explicitly), always indicating success
in the exit status, and if you wanted otherwise you had to call process::exit(code)
. Since Rust
1.26, main
has been allowed to return a Result
, where Ok
translated to a C EXIT_SUCCESS
and
Err
to EXIT_FAILURE
(also debug-printing the error). Under the hood, these alternate return
types were unified by an unstable Termination
trait.
In this release, that Termination
trait is finally stable, along with a more general ExitCode
type that wraps platform-specific return types. That has SUCCESS
and FAILURE
constants, and also
implements From<u8>
for more arbitrary values. The Termination
trait can also be implemented for
your own types, allowing you to customize any kind of reporting before converting to an ExitCode
.
For example, here's a type-safe way to write exit codes for a git bisect run
script:
use std::process::{ExitCode, Termination};
#[repr(u8)]
pub enum GitBisectResult {
Good = 0,
Bad = 1,
Skip = 125,
Abort = 255,
}
impl Termination for GitBisectResult {
fn report(self) -> ExitCode {
// Maybe print a message here
ExitCode::from(self as u8)
}
}
fn main() -> GitBisectResult {
std::panic::catch_unwind(|| {
todo!("test the commit")
}).unwrap_or(GitBisectResult::Abort)
}
const fn
More capabilities for Several incremental features have been stabilized in this release to enable more functionality in
const
functions:
-
Basic handling of
fn
pointers: You can now create, pass, and cast function pointers in aconst fn
. For example, this could be useful to build compile-time function tables for an interpreter. However, it is still not permitted to callfn
pointers. -
Trait bounds: You can now write trait bounds on generic parameters to
const fn
, such asT: Copy
, where previously onlySized
was allowed. -
dyn Trait
types: Similarly,const fn
can now deal with trait objects,dyn Trait
. -
impl Trait
types: Arguments and return values forconst fn
can now be opaqueimpl Trait
types.
Note that the trait features do not yet support calling methods from those traits in a const fn
.
See the Constant Evaluation section of
the reference book to learn more about the current capabilities of const
contexts, and future
capabilities can be tracked in rust#57563.
Static handles for locked stdio
The three standard I/O streams -- Stdin
, Stdout
, and Stderr
-- each have a lock(&self)
to
allow more control over synchronizing read and writes. However, they returned lock guards with a
lifetime borrowed from &self
, so they were limited to the scope of the original handle. This was
determined to be an unnecessary limitation, since the underlying locks were actually in static
storage, so now the guards are returned with a 'static
lifetime, disconnected from the handle.
For example, a common error came from trying to get a handle and lock it in one statement:
// error[E0716]: temporary value dropped while borrowed
let out = std::io::stdout().lock();
// ^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
// |
// creates a temporary which is freed while still in use
Now the lock guard is 'static
, not borrowing from that temporary, so this works!
Stabilized APIs
The following methods and trait implementations are now stabilized:
Pin::static_mut
Pin::static_ref
Vec::retain_mut
VecDeque::retain_mut
Write
forCursor<[u8; N]>
std::os::unix::net::SocketAddr::from_pathname
std::process::ExitCode
std::process::Termination
std::thread::JoinHandle::is_finished
The following previously stable functions are now const
:
<*const T>::offset
and<*mut T>::offset
<*const T>::wrapping_offset
and<*mut T>::wrapping_offset
<*const T>::add
and<*mut T>::add
<*const T>::sub
and<*mut T>::sub
<*const T>::wrapping_add
and<*mut T>::wrapping_add
<*const T>::wrapping_sub
and<*mut T>::wrapping_sub
<[T]>::as_mut_ptr
<[T]>::as_ptr_range
<[T]>::as_mut_ptr_range
Other changes
There are other changes in the Rust 1.61.0 release. Check out what changed in Rust, Cargo, and Clippy.
In a future release we're planning to increase the baseline requirements for the Linux kernel to version 3.2, and for glibc to version 2.17. We'd love your feedback in rust#95026.
Contributors to 1.61.0
Many people came together to create Rust 1.61.0. We couldn't have done it without all of you. Thanks!