|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "Announcing Rust 1.64.0" |
| 4 | +author: Josh Triplett |
| 5 | +team: The Release Team <https://www.rust-lang.org/governance/teams/release> |
| 6 | +release: true |
| 7 | +--- |
| 8 | + |
| 9 | +The Rust team is happy to announce a new version of Rust, 1.64.0. Rust is a |
| 10 | +programming language empowering everyone to build reliable and efficient |
| 11 | +software. |
| 12 | + |
| 13 | +If you have a previous version of Rust installed via rustup, you can get 1.64.0 |
| 14 | +with: |
| 15 | + |
| 16 | +```console |
| 17 | +rustup update stable |
| 18 | +``` |
| 19 | + |
| 20 | +If you don't have it already, you can [get |
| 21 | +`rustup`](https://www.rust-lang.org/install.html) from the appropriate page on |
| 22 | +our website, and check out the [detailed release notes for |
| 23 | +1.64.0](https://github.com/rust-lang/rust/blob/stable/RELEASES.md#version-1640-2022-09-22) |
| 24 | +on GitHub. |
| 25 | + |
| 26 | +If you'd like to help us out by testing future releases, you might consider |
| 27 | +updating locally to use the beta channel (`rustup default beta`) or the nightly |
| 28 | +channel (`rustup default nightly`). Please |
| 29 | +[report](https://github.com/rust-lang/rust/issues/new/choose) any bugs you |
| 30 | +might come across! |
| 31 | + |
| 32 | +## What's in 1.64.0 stable |
| 33 | + |
| 34 | +### C-compatible ffi types in core and alloc |
| 35 | + |
| 36 | +When calling or being called by C ABIs, Rust code can use types like `c_uint` |
| 37 | +or `c_ulong` to match the corresponding types from C on any target, without |
| 38 | +requiring target-specific code or conditionals. |
| 39 | + |
| 40 | +Previously, these types were only available in `std`, so code written for |
| 41 | +embedded targets and other scenarios that could only use `core` or `alloc` |
| 42 | +could not use these types. |
| 43 | + |
| 44 | +Rust 1.64 now provides all of the `c_*` types in |
| 45 | +[`core::ffi`](https://doc.rust-lang.org/core/ffi/index.html), as well as |
| 46 | +[`core::ffi::CStr`](https://doc.rust-lang.org/core/ffi/struct.CStr.html) for |
| 47 | +working with C strings. Rust 1.64 also provides |
| 48 | +[`alloc::ffi::CString`](https://doc.rust-lang.org/alloc/ffi/struct.CString.html) |
| 49 | +for working with owned C strings using only the `alloc` crate, rather than the |
| 50 | +full `std` library. |
| 51 | + |
| 52 | +### New internal layout for network structures |
| 53 | + |
| 54 | +The standard library network data structures |
| 55 | +[`Ipv4Addr`](https://doc.rust-lang.org/std/net/struct.Ipv4Addr.html), |
| 56 | +[`Ipv6Addr`](https://doc.rust-lang.org/std/net/struct.Ipv6Addr.html), |
| 57 | +[`SocketAddrV4`](https://doc.rust-lang.org/std/net/struct.SocketAddrV4.html), |
| 58 | +and |
| 59 | +[`SocketAddrV6`](https://doc.rust-lang.org/std/net/struct.SocketAddrV6.html) |
| 60 | +now use a more compact, memory-efficient layout, rather than using the memory |
| 61 | +layout of the underlying OS data structure. |
| 62 | + |
| 63 | +Normally, such a change would be an entirely internal detail of the standard |
| 64 | +library, with the only user-visible effect being less memory usage. However, |
| 65 | +some crates relied on the internal implementation details of the standard |
| 66 | +library, by using |
| 67 | +[`std::mem::transmute`](https://doc.rust-lang.org/std/mem/fn.transmute.html) or |
| 68 | +similar to access the internal representation and pass it directly to OS |
| 69 | +functions. |
| 70 | + |
| 71 | +Such internal implementation details of the standard library are *never* |
| 72 | +considered a stable interface. Nonetheless, because multiple crates relied on |
| 73 | +this, we first worked with the authors of all of the still-maintained crates |
| 74 | +doing so to arrange for the release of new versions, and to yank the old ones, |
| 75 | +before making this change. |
| 76 | + |
| 77 | +See <https://github.com/rust-lang/rust/pull/78802> for more details. |
| 78 | + |
| 79 | +### Warning about unused tuple-struct fields |
| 80 | + |
| 81 | +If you define a struct containing fields that are never used, rustc will warn |
| 82 | +about the unused fields. Now, in Rust 1.64, you can enable the |
| 83 | +`unused_tuple_struct_fields` lint to get the same warnings about unused fields |
| 84 | +in a tuple struct. In future versions, we plan to make this lint warn by |
| 85 | +default. |
| 86 | + |
| 87 | +Fields of type unit (`()`) do not produce a warning, to make it easier to |
| 88 | +migrate existing code without having to change tuple indices. |
| 89 | + |
| 90 | +### Enhancing `.await` with `IntoFuture` |
| 91 | + |
| 92 | +Rust 1.64 stabilizes the |
| 93 | +[`IntoFuture`](https://doc.rust-lang.org/std/future/trait.IntoFuture.html) |
| 94 | +trait. `IntoFuture` is a trait similar to |
| 95 | +[`IntoIterator`](https://doc.rust-lang.org/std/iter/trait.IntoIterator.html), |
| 96 | +but rather than supporting `for ... in ...` loops, `IntoFuture` changes how |
| 97 | +`.await` works. With `IntoFuture`, the `.await` keyword can await mor ethan |
| 98 | +just futures; it can await _anything which can be converted into a `Future` via |
| 99 | +`IntoFuture`_ - which can help make your APIs more user-friendly! |
| 100 | + |
| 101 | +Take for example a builder which constructs requests to some storage provider |
| 102 | +over the network: |
| 103 | + |
| 104 | +```rust |
| 105 | +pub struct Error { ... } |
| 106 | +pub struct StorageResponse { ... }: |
| 107 | +pub struct StorageRequest(bool); |
| 108 | + |
| 109 | +impl StorageRequest { |
| 110 | + /// Create a new instance of `StorageRequest`. |
| 111 | + pub fn new() -> Self { ... } |
| 112 | + /// Decide whether debug mode should be enabled. |
| 113 | + pub fn set_debug(self, b: bool) -> Self { ... } |
| 114 | + /// Send the request and receive a response. |
| 115 | + pub async fn send(self) -> Result<StorageResponse, Error> { ... } |
| 116 | +} |
| 117 | +``` |
| 118 | + |
| 119 | +Typical usage would likely look something like this: |
| 120 | + |
| 121 | +```rust |
| 122 | +let response = StorageRequest::new() // 1. create a new instance |
| 123 | + .set_debug(true) // 2. set some option |
| 124 | + .send() // 3. construct the future |
| 125 | + .await?; // 4. run the future + propagate errors |
| 126 | +``` |
| 127 | + |
| 128 | +This is not bad, but we can do better here. Using `IntoFuture` we can combine |
| 129 | +_"construct the future"_ (line 3) and _"run the future"_ (line 4) into a single |
| 130 | +step: |
| 131 | +```rust |
| 132 | +let response = StorageRequest::new() // 1. create a new instance |
| 133 | + .set_debug(true) // 2. set some option |
| 134 | + .await?; // 3. construct + run the future + propagate errors |
| 135 | +``` |
| 136 | + |
| 137 | +We can do this by implementing `IntoFuture` for `StorageRequest`. `IntoFuture` |
| 138 | +requires us to have a named future we can return, which we can do by creating a |
| 139 | +"boxed future" and defining a type alias for it: |
| 140 | + |
| 141 | +```rust |
| 142 | +// First we must import some new types into the scope. |
| 143 | +use std::pin::Pin; |
| 144 | +use std::future::{Future, IntoFuture}; |
| 145 | + |
| 146 | +pub struct Error { ... } |
| 147 | +pub struct StorageResponse { ... } |
| 148 | +pub struct StorageRequest(bool); |
| 149 | + |
| 150 | +impl StorageRequest { |
| 151 | + /// Create a new instance of `StorageRequest`. |
| 152 | + pub fn new() -> Self { ... } |
| 153 | + /// Decide whether debug mode should be enabled. |
| 154 | + pub fn set_debug(self, b: bool) -> Self { ... } |
| 155 | + /// Send the request and receive a response. |
| 156 | + pub async fn send(self) -> Result<StorageResponse, Error> { ... } |
| 157 | +} |
| 158 | + |
| 159 | +// The new implementations: |
| 160 | +// 1. create a new named future type |
| 161 | +// 2. implement `IntoFuture` for `StorageRequest` |
| 162 | +pub type StorageRequestFuture = Pin<Box<dyn Future<Output = Result<StorageResponse, Error> + Send + 'static>> |
| 163 | +impl IntoFuture for StorageRequest { |
| 164 | + type IntoFuture = StorageRequestFuture; |
| 165 | + type Output = <StorageRequestFuture as Future>::Output; |
| 166 | + fn into_future(self) -> Self::IntoFuture { |
| 167 | + Box::pin(self.send()) |
| 168 | + } |
| 169 | +} |
| 170 | +``` |
| 171 | +This takes a bit more code to implement, but provides a simpler API for users. |
| 172 | + |
| 173 | +In the future, the Rust Async WG hopes to simplify the creating new named |
| 174 | +futures by supporting [`impl Trait` in `type` aliases (Type Alias Impl Trait or |
| 175 | +TAIT)](https://rust-lang.github.io/impl-trait-initiative/explainer/tait.html). |
| 176 | +This should make implementing `IntoFuture` easier by simplifying the type |
| 177 | +alias' signature, and make it more performant by removing the `Box` from the |
| 178 | +type alias. |
| 179 | + |
| 180 | +### Stabilizing `ready!` and `poll_fn` |
| 181 | + |
| 182 | +When working with the low-level details of futures, you'll currently often |
| 183 | +encounter the [`Poll`](https://doc.rust-lang.org/std/task/enum.Poll.html) type. |
| 184 | +We've stabilized a few helpers for working with this type: |
| 185 | + |
| 186 | +- [`ready!`](https://doc.rust-lang.org/std/task/macro.ready.html) takes a |
| 187 | + `Poll` and returns from the containing function for `Poll::Pending`, or |
| 188 | + returns the contained value in a `Poll::Ready`. This can be useful when |
| 189 | + implementing futures manually using `Poll`. |
| 190 | +- [`poll_fn`](https://doc.rust-lang.org/std/future/fn.poll_fn.html) turns a |
| 191 | + function returning `Poll` into a future. |
| 192 | + |
| 193 | +In the future, we hope to provide simpler APIs that require less use of |
| 194 | +low-level details like `Poll` and `Pin`, but in the meantime, these helpers |
| 195 | +make it easier to write such code. |
| 196 | + |
| 197 | +### Minimum required kernel and glibc versions increased |
| 198 | + |
| 199 | +As [previously |
| 200 | +announced](https://blog.rust-lang.org/2022/08/01/Increasing-glibc-kernel-requirements.html), |
| 201 | +`linux` targets now require at least Linux kernel 3.2 (except for targets which |
| 202 | +already required a newer kernel), and `linux-gnu` targets now require glibc |
| 203 | +2.17 (except for targets which already required a newer glibc). |
| 204 | + |
| 205 | +### Profile-guided optimization (PGO) for Windows targets |
| 206 | + |
| 207 | +Windows builds of the Rust compiler now use profile-guided optimization, |
| 208 | +providing performance improvements of 10-20% for compiling Rust code on |
| 209 | +Windows. |
| 210 | + |
| 211 | +### `rust-analyzer` now available via `rustup`, no longer in preview |
| 212 | + |
| 213 | +Users of `rust-analyzer` can now obtain it via `rustup` on the stable and beta |
| 214 | +channels, not just on nightly. |
| 215 | + |
| 216 | +### Cargo workspace inheritance |
| 217 | + |
| 218 | +When working with collections of related libraries or binary crates in one |
| 219 | +Cargo workspace, you can now avoid duplication of common field values between |
| 220 | +crates, such as common version numbers, repository URLs, or `rust-version`. |
| 221 | +This also helps keep these values in sync between crates when updating them. |
| 222 | +For more details, see |
| 223 | +[`workspace.package`](https://doc.rust-lang.org/cargo/reference/workspaces.html#the-workspacepackage-table), |
| 224 | +[`workspace.dependencies`](https://doc.rust-lang.org/cargo/reference/workspaces.html#the-workspacedependencies-table), |
| 225 | +and ["inheriting a dependency from a |
| 226 | +workspace"](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#inheriting-a-dependency-from-a-workspace). |
| 227 | + |
| 228 | +### Cargo multi-target builds |
| 229 | + |
| 230 | +When building for multiple targets, you can now pass multiple `--target` |
| 231 | +options to `cargo build`, to build all of those targets at once. You can also |
| 232 | +set [`build.target`](https://doc.rust-lang.org/cargo/reference/config.html#buildtarget) to an array of multiple targets in `.cargo/config.toml` to |
| 233 | +build for multiple targets by default. |
| 234 | + |
| 235 | +### Stabilized APIs |
| 236 | + |
| 237 | +The following methods and trait implementations are now stabilized: |
| 238 | + |
| 239 | +- ... |
| 240 | + |
| 241 | +These APIs are now usable in const contexts: |
| 242 | + |
| 243 | +- ... |
| 244 | + |
| 245 | +### Other changes |
| 246 | + |
| 247 | +There are other changes in the Rust 1.64.0 release. Check out what changed in |
| 248 | +[Rust](https://github.com/rust-lang/rust/blob/stable/RELEASES.md#version-1640-2022-09-22), |
| 249 | +[Cargo](https://github.com/rust-lang/cargo/blob/master/CHANGELOG.md#cargo-164-2022-09-22), |
| 250 | +and [Clippy](https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#rust-164). |
| 251 | + |
| 252 | +### Contributors to 1.64.0 |
| 253 | + |
| 254 | +Many people came together to create Rust 1.64.0. |
| 255 | +We couldn't have done it without all of you. |
| 256 | +[Thanks!](https://thanks.rust-lang.org/rust/1.64.0/) |
0 commit comments