|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "Announcing Rust 1.61.0" |
| 4 | +author: The Rust Release Team |
| 5 | +release: true |
| 6 | +--- |
| 7 | + |
| 8 | +The Rust team is happy to announce a new version of Rust, 1.61.0. Rust is a programming language |
| 9 | +empowering everyone to build reliable and efficient software. |
| 10 | + |
| 11 | +If you have a previous version of Rust installed via rustup, you can get 1.61.0 with: |
| 12 | + |
| 13 | +```console |
| 14 | +rustup update stable |
| 15 | +``` |
| 16 | + |
| 17 | +If you don't have it already, you can [get `rustup`][install] |
| 18 | +from the appropriate page on our website, and check out the |
| 19 | +[detailed release notes for 1.61.0][notes] on GitHub. |
| 20 | + |
| 21 | +If you'd like to help us out by testing future releases, you might consider updating locally to use |
| 22 | +the beta channel (`rustup default beta`) or the nightly channel (`rustup default nightly`). |
| 23 | +Please [report] any bugs you might come across! |
| 24 | + |
| 25 | +[install]: https://www.rust-lang.org/install.html |
| 26 | +[notes]: https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1610-2022-05-19 |
| 27 | +[report]: https://github.com/rust-lang/rust/issues/new/choose |
| 28 | + |
| 29 | +## What's in 1.61.0 stable |
| 30 | + |
| 31 | +### Custom exit codes from `main` |
| 32 | + |
| 33 | +In the beginning, Rust `main` functions could only return the unit type `()` (either implicitly or explicitly), always indicating success |
| 34 | +in the exit status, and if you wanted otherwise you had to call `process::exit(code)`. Since Rust |
| 35 | +1.26, `main` has been allowed to return a `Result`, where `Ok` translated to a C `EXIT_SUCCESS` and |
| 36 | +`Err` to `EXIT_FAILURE` (also debug-printing the error). Under the hood, these alternate return |
| 37 | +types were unified by an unstable `Termination` trait. |
| 38 | + |
| 39 | +In this release, that `Termination` trait is finally stable, along with a more general `ExitCode` |
| 40 | +type that wraps platform-specific return types. That has `SUCCESS` and `FAILURE` constants, and also |
| 41 | +implements `From<u8>` for more arbitrary values. The `Termination` trait can also be implemented for |
| 42 | +your own types, allowing you to customize any kind of reporting before converting to an `ExitCode`. |
| 43 | + |
| 44 | +For example, here's a type-safe way to write exit codes for a [`git bisect run`] script: |
| 45 | + |
| 46 | +```rust |
| 47 | +use std::process::{ExitCode, Termination}; |
| 48 | + |
| 49 | +#[repr(u8)] |
| 50 | +pub enum GitBisectResult { |
| 51 | + Good = 0, |
| 52 | + Bad = 1, |
| 53 | + Skip = 125, |
| 54 | + Abort = 255, |
| 55 | +} |
| 56 | + |
| 57 | +impl Termination for GitBisectResult { |
| 58 | + fn report(self) -> ExitCode { |
| 59 | + // Maybe print a message here |
| 60 | + ExitCode::from(self as u8) |
| 61 | + } |
| 62 | +} |
| 63 | + |
| 64 | +fn main() -> GitBisectResult { |
| 65 | + std::panic::catch_unwind(|| { |
| 66 | + todo!("test the commit") |
| 67 | + }).unwrap_or(GitBisectResult::Abort) |
| 68 | +} |
| 69 | +``` |
| 70 | + |
| 71 | +[`git bisect run`]: https://git-scm.com/docs/git-bisect#_bisect_run |
| 72 | + |
| 73 | +### More capabilities for `const fn` |
| 74 | + |
| 75 | +Several incremental features have been stabilized in this release to enable more functionality in |
| 76 | +`const` functions: |
| 77 | + |
| 78 | +* **Basic handling of `fn` pointers**: You can now create, pass, and cast function pointers in a |
| 79 | + `const fn`. For example, this could be useful to build compile-time function tables for an |
| 80 | + interpreter. However, it is still not permitted to call `fn` pointers. |
| 81 | + |
| 82 | +* **Trait bounds**: You can now write trait bounds on generic parameters to `const fn`, such as |
| 83 | + `T: Copy`, where previously only `Sized` was allowed. |
| 84 | + |
| 85 | +* **`dyn Trait` types**: Similarly, `const fn` can now deal with trait objects, `dyn Trait`. |
| 86 | + |
| 87 | +* **`impl Trait` types**: Arguments and return values for `const fn` can now be opaque `impl Trait` |
| 88 | + types. |
| 89 | + |
| 90 | +Note that the trait features do not yet support calling methods from those traits in a `const fn`. |
| 91 | + |
| 92 | +See the [Constant Evaluation](https://doc.rust-lang.org/stable/reference/const_eval.html) section of |
| 93 | +the reference book to learn more about the current capabilities of `const` contexts, and future |
| 94 | +capabilities can be tracked in [rust#57563](https://github.com/rust-lang/rust/issues/57563). |
| 95 | + |
| 96 | +### Static handles for locked stdio |
| 97 | + |
| 98 | +The three standard I/O streams -- `Stdin`, `Stdout`, and `Stderr` -- each have a `lock(&self)` to |
| 99 | +allow more control over synchronizing read and writes. However, they returned lock guards with a |
| 100 | +lifetime borrowed from `&self`, so they were limited to the scope of the original handle. This was |
| 101 | +determined to be an unnecessary limitation, since the underlying locks were actually in static |
| 102 | +storage, so now the guards are returned with a `'static` lifetime, disconnected from the handle. |
| 103 | + |
| 104 | +For example, a common error came from trying to get a handle and lock it in one statement: |
| 105 | + |
| 106 | +```rust |
| 107 | +// error[E0716]: temporary value dropped while borrowed |
| 108 | +let out = std::io::stdout().lock(); |
| 109 | +// ^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement |
| 110 | +// | |
| 111 | +// creates a temporary which is freed while still in use |
| 112 | +``` |
| 113 | + |
| 114 | +Now the lock guard is `'static`, not borrowing from that temporary, so this works! |
| 115 | + |
| 116 | +### Stabilized APIs |
| 117 | + |
| 118 | +The following methods and trait implementations are now stabilized: |
| 119 | + |
| 120 | +- [`Pin::static_mut`](https://doc.rust-lang.org/1.61.0/std/pin/struct.Pin.html#method.static_mut) |
| 121 | +- [`Pin::static_ref`](https://doc.rust-lang.org/1.61.0/std/pin/struct.Pin.html#method.static_ref) |
| 122 | +- [`Vec::retain_mut`](https://doc.rust-lang.org/1.61.0/std/vec/struct.Vec.html#method.retain_mut) |
| 123 | +- [`VecDeque::retain_mut`](https://doc.rust-lang.org/1.61.0/std/collections/struct.VecDeque.html#method.retain_mut) |
| 124 | +- [`Write` for `Cursor<[u8; N]>`](https://doc.rust-lang.org/1.61.0/std/io/struct.Cursor.html#impl-Write-4) |
| 125 | +- [`std::os::unix::net::SocketAddr::from_pathname`](https://doc.rust-lang.org/1.61.0/std/os/unix/net/struct.SocketAddr.html#method.from_pathname) |
| 126 | +- [`std::process::ExitCode`](https://doc.rust-lang.org/1.61.0/std/process/struct.ExitCode.html) |
| 127 | +- [`std::process::Termination`](https://doc.rust-lang.org/1.61.0/std/process/trait.Termination.html) |
| 128 | +- [`std::thread::JoinHandle::is_finished`](https://doc.rust-lang.org/1.61.0/std/thread/struct.JoinHandle.html#method.is_finished) |
| 129 | + |
| 130 | +The following previously stable functions are now `const`: |
| 131 | + |
| 132 | +- [`<*const T>::offset`](https://doc.rust-lang.org/1.61.0/std/primitive.pointer.html#method.offset) |
| 133 | + and [`<*mut T>::offset`](https://doc.rust-lang.org/1.61.0/std/primitive.pointer.html#method.offset-1) |
| 134 | +- [`<*const T>::wrapping_offset`](https://doc.rust-lang.org/1.61.0/std/primitive.pointer.html#method.wrapping_offset) |
| 135 | + and [`<*mut T>::wrapping_offset`](https://doc.rust-lang.org/1.61.0/std/primitive.pointer.html#method.wrapping_offset-1) |
| 136 | +- [`<*const T>::add`](https://doc.rust-lang.org/1.61.0/std/primitive.pointer.html#method.add) |
| 137 | + and [`<*mut T>::add`](https://doc.rust-lang.org/1.61.0/std/primitive.pointer.html#method.add-1) |
| 138 | +- [`<*const T>::sub`](https://doc.rust-lang.org/1.61.0/std/primitive.pointer.html#method.sub) |
| 139 | + and [`<*mut T>::sub`](https://doc.rust-lang.org/1.61.0/std/primitive.pointer.html#method.sub-1) |
| 140 | +- [`<*const T>::wrapping_add`](https://doc.rust-lang.org/1.61.0/std/primitive.pointer.html#method.wrapping_add) |
| 141 | + and [`<*mut T>::wrapping_add`](https://doc.rust-lang.org/1.61.0/std/primitive.pointer.html#method.wrapping_add-1) |
| 142 | +- [`<*const T>::wrapping_sub`](https://doc.rust-lang.org/1.61.0/std/primitive.pointer.html#method.wrapping_sub) |
| 143 | + and [`<*mut T>::wrapping_sub`](https://doc.rust-lang.org/1.61.0/std/primitive.pointer.html#method.wrapping_sub-1) |
| 144 | +- [`<[T]>::as_mut_ptr`](https://doc.rust-lang.org/1.61.0/std/primitive.slice.html#method.as_mut_ptr) |
| 145 | +- [`<[T]>::as_ptr_range`](https://doc.rust-lang.org/1.61.0/std/primitive.slice.html#method.as_ptr_range) |
| 146 | +- [`<[T]>::as_mut_ptr_range`](https://doc.rust-lang.org/1.61.0/std/primitive.slice.html#method.as_mut_ptr_range) |
| 147 | + |
| 148 | +### Other changes |
| 149 | + |
| 150 | +There are other changes in the Rust 1.61.0 release. Check out what changed in |
| 151 | +[Rust](https://github.com/rust-lang/rust/blob/stable/RELEASES.md#version-1610-2022-05-19), |
| 152 | +[Cargo](https://github.com/rust-lang/cargo/blob/master/CHANGELOG.md#cargo-161-2022-05-19), |
| 153 | +and [Clippy](https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#rust-161). |
| 154 | + |
| 155 | +In a future release we're planning to increase the baseline requirements for |
| 156 | +the Linux kernel to version 3.2, and for glibc to version 2.17. We'd love |
| 157 | +your feedback in [rust#95026](https://github.com/rust-lang/rust/pull/95026). |
| 158 | + |
| 159 | +### Contributors to 1.61.0 |
| 160 | + |
| 161 | +Many people came together to create Rust 1.61.0. |
| 162 | +We couldn't have done it without all of you. |
| 163 | +[Thanks!](https://thanks.rust-lang.org/rust/1.61.0/) |
0 commit comments