|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "Announcing Rust 1.64.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.64.0. Rust is a |
| 9 | +programming language empowering everyone to build reliable and efficient |
| 10 | +software. |
| 11 | + |
| 12 | +If you have a previous version of Rust installed via rustup, you can get 1.64.0 |
| 13 | +with: |
| 14 | + |
| 15 | +```console |
| 16 | +rustup update stable |
| 17 | +``` |
| 18 | + |
| 19 | +If you don't have it already, you can [get |
| 20 | +`rustup`](https://www.rust-lang.org/install.html) from the appropriate page on |
| 21 | +our website, and check out the [detailed release notes for |
| 22 | +1.64.0](https://github.com/rust-lang/rust/blob/stable/RELEASES.md#version-1640-2022-09-22) |
| 23 | +on GitHub. |
| 24 | + |
| 25 | +If you'd like to help us out by testing future releases, you might consider |
| 26 | +updating locally to use the beta channel (`rustup default beta`) or the nightly |
| 27 | +channel (`rustup default nightly`). Please |
| 28 | +[report](https://github.com/rust-lang/rust/issues/new/choose) any bugs you |
| 29 | +might come across! |
| 30 | + |
| 31 | +## What's in 1.64.0 stable |
| 32 | + |
| 33 | +### Enhancing `.await` with `IntoFuture` |
| 34 | + |
| 35 | +Rust 1.64 stabilizes the |
| 36 | +[`IntoFuture`](https://doc.rust-lang.org/std/future/trait.IntoFuture.html) |
| 37 | +trait. `IntoFuture` is a trait similar to |
| 38 | +[`IntoIterator`](https://doc.rust-lang.org/std/iter/trait.IntoIterator.html), |
| 39 | +but rather than supporting `for ... in ...` loops, `IntoFuture` changes how |
| 40 | +`.await` works. With `IntoFuture`, the `.await` keyword can await more than |
| 41 | +just futures; it can await *anything which can be converted into a `Future` via |
| 42 | +`IntoFuture`* - which can help make your APIs more user-friendly! |
| 43 | + |
| 44 | +Take for example a builder which constructs requests to some storage provider |
| 45 | +over the network: |
| 46 | + |
| 47 | +```rust |
| 48 | +pub struct Error { ... } |
| 49 | +pub struct StorageResponse { ... }: |
| 50 | +pub struct StorageRequest(bool); |
| 51 | + |
| 52 | +impl StorageRequest { |
| 53 | + /// Create a new instance of `StorageRequest`. |
| 54 | + pub fn new() -> Self { ... } |
| 55 | + /// Decide whether debug mode should be enabled. |
| 56 | + pub fn set_debug(self, b: bool) -> Self { ... } |
| 57 | + /// Send the request and receive a response. |
| 58 | + pub async fn send(self) -> Result<StorageResponse, Error> { ... } |
| 59 | +} |
| 60 | +``` |
| 61 | + |
| 62 | +Typical usage would likely look something like this: |
| 63 | + |
| 64 | +```rust |
| 65 | +let response = StorageRequest::new() // 1. create a new instance |
| 66 | + .set_debug(true) // 2. set some option |
| 67 | + .send() // 3. construct the future |
| 68 | + .await?; // 4. run the future + propagate errors |
| 69 | +``` |
| 70 | + |
| 71 | +This is not bad, but we can do better here. Using `IntoFuture` we can combine |
| 72 | +_"construct the future"_ (line 3) and _"run the future"_ (line 4) into a single |
| 73 | +step: |
| 74 | + |
| 75 | +```rust |
| 76 | +let response = StorageRequest::new() // 1. create a new instance |
| 77 | + .set_debug(true) // 2. set some option |
| 78 | + .await?; // 3. construct + run the future + propagate errors |
| 79 | +``` |
| 80 | + |
| 81 | +We can do this by implementing `IntoFuture` for `StorageRequest`. `IntoFuture` |
| 82 | +requires us to have a named future we can return, which we can do by creating a |
| 83 | +"boxed future" and defining a type alias for it: |
| 84 | + |
| 85 | +```rust |
| 86 | +// First we must import some new types into the scope. |
| 87 | +use std::pin::Pin; |
| 88 | +use std::future::{Future, IntoFuture}; |
| 89 | + |
| 90 | +pub struct Error { ... } |
| 91 | +pub struct StorageResponse { ... } |
| 92 | +pub struct StorageRequest(bool); |
| 93 | + |
| 94 | +impl StorageRequest { |
| 95 | + /// Create a new instance of `StorageRequest`. |
| 96 | + pub fn new() -> Self { ... } |
| 97 | + /// Decide whether debug mode should be enabled. |
| 98 | + pub fn set_debug(self, b: bool) -> Self { ... } |
| 99 | + /// Send the request and receive a response. |
| 100 | + pub async fn send(self) -> Result<StorageResponse, Error> { ... } |
| 101 | +} |
| 102 | + |
| 103 | +// The new implementations: |
| 104 | +// 1. create a new named future type |
| 105 | +// 2. implement `IntoFuture` for `StorageRequest` |
| 106 | +pub type StorageRequestFuture = Pin<Box<dyn Future<Output = Result<StorageResponse, Error> + Send + 'static>> |
| 107 | +impl IntoFuture for StorageRequest { |
| 108 | + type IntoFuture = StorageRequestFuture; |
| 109 | + type Output = <StorageRequestFuture as Future>::Output; |
| 110 | + fn into_future(self) -> Self::IntoFuture { |
| 111 | + Box::pin(self.send()) |
| 112 | + } |
| 113 | +} |
| 114 | +``` |
| 115 | + |
| 116 | +This takes a bit more code to implement, but provides a simpler API for users. |
| 117 | + |
| 118 | +In the future, the Rust Async WG hopes to simplify the creating new named |
| 119 | +futures by supporting [`impl Trait` in `type` aliases (Type Alias Impl Trait or |
| 120 | +TAIT)](https://rust-lang.github.io/impl-trait-initiative/explainer/tait.html). |
| 121 | +This should make implementing `IntoFuture` easier by simplifying the type |
| 122 | +alias' signature, and make it more performant by removing the `Box` from the |
| 123 | +type alias. |
| 124 | + |
| 125 | +### C-compatible FFI types in core and alloc |
| 126 | + |
| 127 | +When calling or being called by C ABIs, Rust code can use type aliases like |
| 128 | +`c_uint` or `c_ulong` to match the corresponding types from C on any target, |
| 129 | +without requiring target-specific code or conditionals. |
| 130 | + |
| 131 | +Previously, these type aliases were only available in `std`, so code written |
| 132 | +for embedded targets and other scenarios that could only use `core` or `alloc` |
| 133 | +could not use these types. |
| 134 | + |
| 135 | +Rust 1.64 now provides all of the `c_*` type aliases in |
| 136 | +[`core::ffi`](https://doc.rust-lang.org/core/ffi/index.html), as well as |
| 137 | +[`core::ffi::CStr`](https://doc.rust-lang.org/core/ffi/struct.CStr.html) for |
| 138 | +working with C strings. Rust 1.64 also provides |
| 139 | +[`alloc::ffi::CString`](https://doc.rust-lang.org/alloc/ffi/struct.CString.html) |
| 140 | +for working with owned C strings using only the `alloc` crate, rather than the |
| 141 | +full `std` library. |
| 142 | + |
| 143 | +### rust-analyzer is now available via rustup |
| 144 | + |
| 145 | +[rust-analyzer](https://rust-analyzer.github.io/) is now included as part of |
| 146 | +the collection of tools included with Rust. This makes it easier to download |
| 147 | +and access rust-analyzer, and makes it available on more platforms. It is |
| 148 | +available as a [rustup |
| 149 | +component](https://rust-lang.github.io/rustup/concepts/components.html) which |
| 150 | +can be installed with: |
| 151 | + |
| 152 | +``` |
| 153 | +rustup component add rust-analyzer |
| 154 | +``` |
| 155 | + |
| 156 | +At this time, to run the rustup-installed version, you need to invoke it this |
| 157 | +way: |
| 158 | + |
| 159 | +``` |
| 160 | +rustup run rust-analyzer |
| 161 | +``` |
| 162 | + |
| 163 | +The next release of rustup will provide a built-in proxy so that running the |
| 164 | +executable `rust-analyzer` will launch the appropriate version. |
| 165 | + |
| 166 | +Most users should continue to use the releases provided by the rust-analyzer |
| 167 | +team (available on the [rust-analyzer releases |
| 168 | +page](https://github.com/rust-lang/rust-analyzer/releases)), which are |
| 169 | +published more frequently. Users of the [official VSCode |
| 170 | +extension](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer) |
| 171 | +are not affected since it automatically downloads and updates releases in the |
| 172 | +background. |
| 173 | + |
| 174 | +### Cargo improvements: workspace inheritance and multi-target builds |
| 175 | + |
| 176 | +When working with collections of related libraries or binary crates in one |
| 177 | +Cargo workspace, you can now avoid duplication of common field values between |
| 178 | +crates, such as common version numbers, repository URLs, or `rust-version`. |
| 179 | +This also helps keep these values in sync between crates when updating them. |
| 180 | +For more details, see |
| 181 | +[`workspace.package`](https://doc.rust-lang.org/cargo/reference/workspaces.html#the-package-table), |
| 182 | +[`workspace.dependencies`](https://doc.rust-lang.org/cargo/reference/workspaces.html#the-dependencies-table), |
| 183 | +and ["inheriting a dependency from a |
| 184 | +workspace"](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#inheriting-a-dependency-from-a-workspace). |
| 185 | + |
| 186 | +When building for multiple targets, you can now pass multiple `--target` |
| 187 | +options to `cargo build`, to build all of those targets at once. You can also |
| 188 | +set |
| 189 | +[`build.target`](https://doc.rust-lang.org/cargo/reference/config.html#buildtarget) |
| 190 | +to an array of multiple targets in `.cargo/config.toml` to build for multiple |
| 191 | +targets by default. |
| 192 | + |
| 193 | +### Stabilized APIs |
| 194 | + |
| 195 | +The following methods and trait implementations are now stabilized: |
| 196 | + |
| 197 | +- [`future::IntoFuture`](https://doc.rust-lang.org/stable/std/future/trait.IntoFuture.html) |
| 198 | +- [`num::NonZero*::checked_mul`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.checked_mul) |
| 199 | +- [`num::NonZero*::checked_pow`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.checked_pow) |
| 200 | +- [`num::NonZero*::saturating_mul`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.saturating_mul) |
| 201 | +- [`num::NonZero*::saturating_pow`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.saturating_pow) |
| 202 | +- [`num::NonZeroI*::abs`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.abs) |
| 203 | +- [`num::NonZeroI*::checked_abs`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.checked_abs) |
| 204 | +- [`num::NonZeroI*::overflowing_abs`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.overflowing_abs) |
| 205 | +- [`num::NonZeroI*::saturating_abs`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.saturating_abs) |
| 206 | +- [`num::NonZeroI*::unsigned_abs`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.unsigned_abs) |
| 207 | +- [`num::NonZeroI*::wrapping_abs`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.wrapping_abs) |
| 208 | +- [`num::NonZeroU*::checked_add`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.checked_add) |
| 209 | +- [`num::NonZeroU*::checked_next_power_of_two`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.checked_next_power_of_two) |
| 210 | +- [`num::NonZeroU*::saturating_add`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.saturating_add) |
| 211 | +- [`os::unix::process::CommandExt::process_group`](https://doc.rust-lang.org/stable/std/os/unix/process/trait.CommandExt.html#tymethod.process_group) |
| 212 | +- [`os::windows::fs::FileTypeExt::is_symlink_dir`](https://doc.rust-lang.org/stable/std/os/windows/fs/trait.FileTypeExt.html#tymethod.is_symlink_dir) |
| 213 | +- [`os::windows::fs::FileTypeExt::is_symlink_file`](https://doc.rust-lang.org/stable/std/os/windows/fs/trait.FileTypeExt.html#tymethod.is_symlink_file) |
| 214 | + |
| 215 | +These types were previously stable in `std::ffi`, but are now also available in |
| 216 | +`core` and `alloc`: |
| 217 | + |
| 218 | +- [`core::ffi::CStr`](https://doc.rust-lang.org/stable/core/ffi/struct.CStr.html) |
| 219 | +- [`core::ffi::FromBytesWithNulError`](https://doc.rust-lang.org/stable/core/ffi/struct.FromBytesWithNulError.html) |
| 220 | +- [`alloc::ffi::CString`](https://doc.rust-lang.org/stable/alloc/ffi/struct.CString.html) |
| 221 | +- [`alloc::ffi::FromVecWithNulError`](https://doc.rust-lang.org/stable/alloc/ffi/struct.FromVecWithNulError.html) |
| 222 | +- [`alloc::ffi::IntoStringError`](https://doc.rust-lang.org/stable/alloc/ffi/struct.IntoStringError.html) |
| 223 | +- [`alloc::ffi::NulError`](https://doc.rust-lang.org/stable/alloc/ffi/struct.NulError.html) |
| 224 | + |
| 225 | +These types were previously stable in `std::os::raw`, but are now also |
| 226 | +available in `core::ffi` and `std::ffi`: |
| 227 | + |
| 228 | +- [`ffi::c_char`](https://doc.rust-lang.org/stable/std/ffi/type.c_char.html) |
| 229 | +- [`ffi::c_double`](https://doc.rust-lang.org/stable/std/ffi/type.c_double.html) |
| 230 | +- [`ffi::c_float`](https://doc.rust-lang.org/stable/std/ffi/type.c_float.html) |
| 231 | +- [`ffi::c_int`](https://doc.rust-lang.org/stable/std/ffi/type.c_int.html) |
| 232 | +- [`ffi::c_long`](https://doc.rust-lang.org/stable/std/ffi/type.c_long.html) |
| 233 | +- [`ffi::c_longlong`](https://doc.rust-lang.org/stable/std/ffi/type.c_longlong.html) |
| 234 | +- [`ffi::c_schar`](https://doc.rust-lang.org/stable/std/ffi/type.c_schar.html) |
| 235 | +- [`ffi::c_short`](https://doc.rust-lang.org/stable/std/ffi/type.c_short.html) |
| 236 | +- [`ffi::c_uchar`](https://doc.rust-lang.org/stable/std/ffi/type.c_uchar.html) |
| 237 | +- [`ffi::c_uint`](https://doc.rust-lang.org/stable/std/ffi/type.c_uint.html) |
| 238 | +- [`ffi::c_ulong`](https://doc.rust-lang.org/stable/std/ffi/type.c_ulong.html) |
| 239 | +- [`ffi::c_ulonglong`](https://doc.rust-lang.org/stable/std/ffi/type.c_ulonglong.html) |
| 240 | +- [`ffi::c_ushort`](https://doc.rust-lang.org/stable/std/ffi/type.c_ushort.html) |
| 241 | + |
| 242 | +We've stabilized some helpers for use with `Poll`, the low-level implementation |
| 243 | +underneath futures: |
| 244 | + |
| 245 | +- [`future::poll_fn`](https://doc.rust-lang.org/stable/std/future/fn.poll_fn.html) |
| 246 | +- [`task::ready!`](https://doc.rust-lang.org/stable/std/task/macro.ready.html) |
| 247 | + |
| 248 | +In the future, we hope to provide simpler APIs that require less use of |
| 249 | +low-level details like `Poll` and `Pin`, but in the meantime, these helpers |
| 250 | +make it easier to write such code. |
| 251 | + |
| 252 | +These APIs are now usable in const contexts: |
| 253 | + |
| 254 | +- [`slice::from_raw_parts`](https://doc.rust-lang.org/stable/core/slice/fn.from_raw_parts.html) |
| 255 | + |
| 256 | +### Compatibility notes |
| 257 | + |
| 258 | +* As [previously |
| 259 | + announced](https://blog.rust-lang.org/2022/08/01/Increasing-glibc-kernel-requirements.html), |
| 260 | + `linux` targets now require at least Linux kernel 3.2 (except for targets which |
| 261 | + already required a newer kernel), and `linux-gnu` targets now require glibc |
| 262 | + 2.17 (except for targets which already required a newer glibc). |
| 263 | + |
| 264 | +* Rust 1.64.0 changes the memory layout of `Ipv4Addr`, `Ipv6Addr`, |
| 265 | + `SocketAddrV4` and `SocketAddrV6` to be more compact and memory efficient. |
| 266 | + This internal representation was never exposed, but some crates relied on |
| 267 | + it anyway by using `std::mem::transmute`, resulting in invalid memory |
| 268 | + accesses. Such internal implementation details of the standard library are |
| 269 | + *never* considered a stable interface. To limit the damage, we worked with |
| 270 | + the authors of all of the still-maintained crates doing so to release fixed |
| 271 | + versions, which have been out for more than a year. The vast majority of |
| 272 | + impacted users should be able to mitigate with a `cargo update`. |
| 273 | + |
| 274 | +* As part of the [RLS |
| 275 | + deprecation](https://blog.rust-lang.org/2022/07/01/RLS-deprecation.html), |
| 276 | + this is also the last release containing a copy of RLS. Starting from Rust |
| 277 | + 1.65.0, RLS will be replaced by a small LSP server showing the deprecation |
| 278 | + warning. |
| 279 | + |
| 280 | +### Other changes |
| 281 | + |
| 282 | +There are other changes in the Rust 1.64 release, including: |
| 283 | + |
| 284 | +* Windows builds of the Rust compiler now use profile-guided optimization, |
| 285 | + providing performance improvements of 10-20% for compiling Rust code on |
| 286 | + Windows. |
| 287 | + |
| 288 | +* If you define a struct containing fields that are never used, rustc will warn |
| 289 | + about the unused fields. Now, in Rust 1.64, you can enable the |
| 290 | + `unused_tuple_struct_fields` lint to get the same warnings about unused |
| 291 | + fields in a tuple struct. In future versions, we plan to make this lint |
| 292 | + warn by default. Fields of type unit (`()`) do not produce this warning, |
| 293 | + to make it easier to migrate existing code without having to change tuple |
| 294 | + indices. |
| 295 | + |
| 296 | +Check out everything that changed in |
| 297 | +[Rust](https://github.com/rust-lang/rust/blob/stable/RELEASES.md#version-1640-2022-09-22), |
| 298 | +[Cargo](https://github.com/rust-lang/cargo/blob/master/CHANGELOG.md#cargo-164-2022-09-22), |
| 299 | +and [Clippy](https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#rust-164). |
| 300 | + |
| 301 | +### Contributors to 1.64.0 |
| 302 | + |
| 303 | +Many people came together to create Rust 1.64.0. |
| 304 | +We couldn't have done it without all of you. |
| 305 | +[Thanks!](https://thanks.rust-lang.org/rust/1.64.0/) |
0 commit comments