Skip to content

Draft release notes for 1.64 #1027

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Sep 22, 2022
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
256 changes: 256 additions & 0 deletions posts/2022-09-22-Rust-1.64.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
---
layout: post
title: "Announcing Rust 1.64.0"
author: Josh Triplett
team: The Release Team <https://www.rust-lang.org/governance/teams/release>
release: true
---

The Rust team is happy to announce a new version of Rust, 1.64.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.64.0
with:

```console
rustup update stable
```

If you don't have it already, you can [get
`rustup`](https://www.rust-lang.org/install.html) from the appropriate page on
our website, and check out the [detailed release notes for
1.64.0](https://github.com/rust-lang/rust/blob/stable/RELEASES.md#version-1640-2022-09-22)
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](https://github.com/rust-lang/rust/issues/new/choose) any bugs you
might come across!

## What's in 1.64.0 stable

### C-compatible ffi types in core and alloc

When calling or being called by C ABIs, Rust code can use types like `c_uint`
or `c_ulong` to match the corresponding types from C on any target, without
requiring target-specific code or conditionals.

Previously, these types were only available in `std`, so code written for
embedded targets and other scenarios that could only use `core` or `alloc`
could not use these types.

Rust 1.64 now provides all of the `c_*` types in
[`core::ffi`](https://doc.rust-lang.org/core/ffi/index.html), as well as
[`core::ffi::CStr`](https://doc.rust-lang.org/core/ffi/struct.CStr.html) for
working with C strings. Rust 1.64 also provides
[`alloc::ffi::CString`](https://doc.rust-lang.org/alloc/ffi/struct.CString.html)
for working with owned C strings using only the `alloc` crate, rather than the
full `std` library.

### New internal layout for network structures

The standard library network data structures
[`Ipv4Addr`](https://doc.rust-lang.org/std/net/struct.Ipv4Addr.html),
[`Ipv6Addr`](https://doc.rust-lang.org/std/net/struct.Ipv6Addr.html),
[`SocketAddrV4`](https://doc.rust-lang.org/std/net/struct.SocketAddrV4.html),
and
[`SocketAddrV6`](https://doc.rust-lang.org/std/net/struct.SocketAddrV6.html)
now use a more compact, memory-efficient layout, rather than using the memory
layout of the underlying OS data structure.

Normally, such a change would be an entirely internal detail of the standard
library, with the only user-visible effect being less memory usage. However,
some crates relied on the internal implementation details of the standard
library, by using
[`std::mem::transmute`](https://doc.rust-lang.org/std/mem/fn.transmute.html) or
similar to access the internal representation and pass it directly to OS
functions.

Such internal implementation details of the standard library are *never*
considered a stable interface. Nonetheless, because multiple crates relied on
this, we first worked with the authors of all of the still-maintained crates
doing so to arrange for the release of new versions, and to yank the old ones,
before making this change.

See <https://github.com/rust-lang/rust/pull/78802> for more details.

### Warning about unused tuple-struct fields

If you define a struct containing fields that are never used, rustc will warn
about the unused fields. Now, in Rust 1.64, you can enable the
`unused_tuple_struct_fields` lint to get the same warnings about unused fields
in a tuple struct. In future versions, we plan to make this lint warn by
default.

Fields of type unit (`()`) do not produce a warning, to make it easier to
migrate existing code without having to change tuple indices.

### Enhancing `.await` with `IntoFuture`

Rust 1.64 stabilizes the
[`IntoFuture`](https://doc.rust-lang.org/std/future/trait.IntoFuture.html)
trait. `IntoFuture` is a trait similar to
[`IntoIterator`](https://doc.rust-lang.org/std/iter/trait.IntoIterator.html),
but rather than supporting `for ... in ...` loops, `IntoFuture` changes how
`.await` works. With `IntoFuture`, the `.await` keyword can await mor ethan
just futures; it can await _anything which can be converted into a `Future` via
`IntoFuture`_ - which can help make your APIs more user-friendly!

Take for example a builder which constructs requests to some storage provider
over the network:

```rust
pub struct Error { ... }
pub struct StorageResponse { ... }:
pub struct StorageRequest(bool);

impl StorageRequest {
/// Create a new instance of `StorageRequest`.
pub fn new() -> Self { ... }
/// Decide whether debug mode should be enabled.
pub fn set_debug(self, b: bool) -> Self { ... }
/// Send the request and receive a response.
pub async fn send(self) -> Result<StorageResponse, Error> { ... }
}
```

Typical usage would likely look something like this:

```rust
let response = StorageRequest::new() // 1. create a new instance
.set_debug(true) // 2. set some option
.send() // 3. construct the future
.await?; // 4. run the future + propagate errors
```

This is not bad, but we can do better here. Using `IntoFuture` we can combine
_"construct the future"_ (line 3) and _"run the future"_ (line 4) into a single
step:
```rust
let response = StorageRequest::new() // 1. create a new instance
.set_debug(true) // 2. set some option
.await?; // 3. construct + run the future + propagate errors
```

We can do this by implementing `IntoFuture` for `StorageRequest`. `IntoFuture`
requires us to have a named future we can return, which we can do by creating a
"boxed future" and defining a type alias for it:

```rust
// First we must import some new types into the scope.
use std::pin::Pin;
use std::future::{Future, IntoFuture};

pub struct Error { ... }
pub struct StorageResponse { ... }
pub struct StorageRequest(bool);

impl StorageRequest {
/// Create a new instance of `StorageRequest`.
pub fn new() -> Self { ... }
/// Decide whether debug mode should be enabled.
pub fn set_debug(self, b: bool) -> Self { ... }
/// Send the request and receive a response.
pub async fn send(self) -> Result<StorageResponse, Error> { ... }
}

// The new implementations:
// 1. create a new named future type
// 2. implement `IntoFuture` for `StorageRequest`
pub type StorageRequestFuture = Pin<Box<dyn Future<Output = Result<StorageResponse, Error> + Send + 'static>>
impl IntoFuture for StorageRequest {
type IntoFuture = StorageRequestFuture;
type Output = <StorageRequestFuture as Future>::Output;
fn into_future(self) -> Self::IntoFuture {
Box::pin(self.send())
}
}
```
This takes a bit more code to implement, but provides a simpler API for users.

In the future, the Rust Async WG hopes to simplify the creating new named
futures by supporting [`impl Trait` in `type` aliases (Type Alias Impl Trait or
TAIT)](https://rust-lang.github.io/impl-trait-initiative/explainer/tait.html).
This should make implementing `IntoFuture` easier by simplifying the type
alias' signature, and make it more performant by removing the `Box` from the
type alias.

### Stabilizing `ready!` and `poll_fn`

When working with the low-level details of futures, you'll currently often
encounter the [`Poll`](https://doc.rust-lang.org/std/task/enum.Poll.html) type.
We've stabilized a few helpers for working with this type:

- [`ready!`](https://doc.rust-lang.org/std/task/macro.ready.html) takes a
`Poll` and returns from the containing function for `Poll::Pending`, or
returns the contained value in a `Poll::Ready`. This can be useful when
implementing futures manually using `Poll`.
- [`poll_fn`](https://doc.rust-lang.org/std/future/fn.poll_fn.html) turns a
function returning `Poll` into a future.

In the future, we hope to provide simpler APIs that require less use of
low-level details like `Poll` and `Pin`, but in the meantime, these helpers
make it easier to write such code.

### Minimum required kernel and glibc versions increased

As [previously
announced](https://blog.rust-lang.org/2022/08/01/Increasing-glibc-kernel-requirements.html),
`linux` targets now require at least Linux kernel 3.2 (except for targets which
already required a newer kernel), and `linux-gnu` targets now require glibc
2.17 (except for targets which already required a newer glibc).

### Profile-guided optimization (PGO) for Windows targets

Windows builds of the Rust compiler now use profile-guided optimization,
providing performance improvements of 10-20% for compiling Rust code on
Windows.

### `rust-analyzer` now available via `rustup`, no longer in preview

Users of `rust-analyzer` can now obtain it via `rustup` on the stable and beta
channels, not just on nightly.

### Cargo workspace inheritance

When working with collections of related libraries or binary crates in one
Cargo workspace, you can now avoid duplication of common field values between
crates, such as common version numbers, repository URLs, or `rust-version`.
This also helps keep these values in sync between crates when updating them.
For more details, see
[`workspace.package`](https://doc.rust-lang.org/cargo/reference/workspaces.html#the-workspacepackage-table),
[`workspace.dependencies`](https://doc.rust-lang.org/cargo/reference/workspaces.html#the-workspacedependencies-table),
and ["inheriting a dependency from a
workspace"](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#inheriting-a-dependency-from-a-workspace).

### Cargo multi-target builds

When building for multiple targets, you can now pass multiple `--target`
options to `cargo build`, to build all of those targets at once. You can also
set [`build.target`](https://doc.rust-lang.org/cargo/reference/config.html#buildtarget) to an array of multiple targets in `.cargo/config.toml` to
build for multiple targets by default.

### Stabilized APIs

The following methods and trait implementations are now stabilized:

- ...

These APIs are now usable in const contexts:

- ...

### Other changes

There are other changes in the Rust 1.64.0 release. Check out what changed in
[Rust](https://github.com/rust-lang/rust/blob/stable/RELEASES.md#version-1640-2022-09-22),
[Cargo](https://github.com/rust-lang/cargo/blob/master/CHANGELOG.md#cargo-164-2022-09-22),
and [Clippy](https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#rust-164).

### Contributors to 1.64.0

Many people came together to create Rust 1.64.0.
We couldn't have done it without all of you.
[Thanks!](https://thanks.rust-lang.org/rust/1.64.0/)