Skip to content
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

Announcing Rust 1.56.0 and Rust 2021 #897

Merged
merged 4 commits into from
Oct 21, 2021
Merged
Changes from 3 commits
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
182 changes: 182 additions & 0 deletions posts/2021-10-21-Rust-1.56.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
---
layout: post
title: "Announcing Rust 1.56.0 and Rust 2021"
author: The Rust Release Team
release: true
---

The Rust team is happy to announce a new version of Rust, 1.56.0. This stabilizes the 2021 edition as well.
Rust is a programming language empowering everyone to build reliable and efficient software.

If you have a previous version of Rust installed via rustup, getting Rust 1.56.0 is as easy as:

```console
rustup update stable
```

If you don't have it already, you can [get `rustup`][install]
from the appropriate page on our website, and check out the
[detailed release notes for 1.56.0][notes] on GitHub.

[install]: https://www.rust-lang.org/install.html
[notes]: https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1560-2021-10-21

## What's in 1.56.0 stable

### Rust 2021

We wrote about plans for Rust 2021 [in May](https://blog.rust-lang.org/2021/05/11/edition-2021.html).
pietroalbini marked this conversation as resolved.
Show resolved Hide resolved
This a smaller edition, especially compared to 2018, but there
are still some nice quality-of-life changes that require an edition opt-in to
avoid breaking some corner cases in existing code. See the new chapters of the
edition guide below for more details on each new feature and guidance for
migration.

cuviper marked this conversation as resolved.
Show resolved Hide resolved
* [Disjoint capture](https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html): closures now capture individual named fields rather than always capturing whole identifiers.
* [`IntoIterator` for arrays](https://doc.rust-lang.org/edition-guide/rust-2021/IntoIterator-for-arrays.html): `array.into_iter()` now iterates over items by value instead of by reference.
* [Or patterns in macro-rules](https://doc.rust-lang.org/edition-guide/rust-2021/or-patterns-macro-rules.html) now match top-level `A|B` in `:pat`.
* [Default Cargo feature resolver](https://doc.rust-lang.org/edition-guide/rust-2021/default-cargo-resolver.html) is now version 2.
* [Additions to the prelude](https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html): `TryInto`, `TryFrom`, and `FromIterator` are now in scope by default.
* [Panic macros](https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html) now always expect format strings, just like `println!()`.
* [Reserving syntax](https://doc.rust-lang.org/edition-guide/rust-2021/reserving-syntax.html) for `ident#`, `ident"..."`, and `ident'...'`.
* [Warnings promoted to errors](https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html): `bare_trait_objects` and `ellipsis_inclusive_range_patterns`.

#### Disjoint capture in closures

Closures automatically capture values or references to identifiers that are
used in the body, but before 2021, they were always captured as a whole. The new
disjoint-capture feature will likely simplify the way you write closures, so
let's look at a quick example:

```rust
cuviper marked this conversation as resolved.
Show resolved Hide resolved
// 2015 or 2018 edition code
let a = SomeStruct::new();
cuviper marked this conversation as resolved.
Show resolved Hide resolved

// Move out of one field of the struct
drop(a.x);

// Ok: Still use another field of the struct
println!("{}", a.y);

// Error: Before 2021 edition, tries to capture all of `a`
let c = || println!("{}", a.y);
c();
```

To fix this, you would have had to extract something like `let y = &a.y;`
manually before the closure to limit its capture. Starting in Rust 2021,
closures will automatically capture only the fields that they use, so the
above example will compile fine!

This new behavior is only activated in the new edition, since it can change
the order in which fields are dropped. As for all edition changes, an
automatic migration is available, which will update your closures for which
this matters by inserting `let _ = &a;` inside the closure to force the
entire struct to be captured as before.

#### Migrating to 2021

The guide includes migration instructions for all new features, and in general
[transitioning an existing project to a new edition](https://doc.rust-lang.org/edition-guide/editions/transitioning-an-existing-project-to-a-new-edition.html).
In many cases `cargo fix` can automate the necessary changes. You may even
find that no changes in your code are needed at all for 2021!

However small this edition appears on the surface, it's still the product
of a lot of hard work from many contributors: see our dedicated
[celebration and thanks](https://github.com/rust-lang/rust/issues/88623) tracker!

### Cargo `rust-version`

`Cargo.toml` now supports a `[package]` [`rust-version`] field to specify
the minimum supported Rust version for a crate, and Cargo will exit with an
early error if that is not satisfied. This doesn't currently influence the
dependency resolver, but the idea is to catch compatibility problems before
they turn into cryptic compiler errors.

[`rust-version`]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-rust-version-field

### New bindings in `binding @ pattern`

Rust pattern matching can be written with a single identifier that binds
the entire value, followed by `@` and a more refined structural pattern,
but this has not allowed additional bindings in that pattern -- until now!

```rust
struct Matrix {
data: Vec<f64>,
row_len: usize,
}

// Before, we need separate statements to bind
// the whole struct and also read its parts.
let matrix = get_matrix();
let row_len = matrix.row_len;
// or with a destructuring pattern:
let Matrix { row_len, .. } = matrix;

// Rust 1.56 now lets you bind both at once!
let matrix @ Matrix { row_len, .. } = get_matrix();
```

This actually was allowed in the days before Rust 1.0, but that was removed
due to known [unsoundness](https://github.com/rust-lang/rust/pull/16053) at
the time. With the evolution of the borrow checker since that time, and with
heavy testing, the compiler team determined that this was safe to finally
allow in stable Rust!

### Stabilized APIs

The following methods and trait implementations were stabilized.

- [`std::os::unix::fs::chroot`]
- [`UnsafeCell::raw_get`]
- [`BufWriter::into_parts`]
- [`core::panic::{UnwindSafe, RefUnwindSafe, AssertUnwindSafe}`]\
\(previously only in `std`)
- [`Vec::shrink_to`]
- [`String::shrink_to`]
- [`OsString::shrink_to`]
- [`PathBuf::shrink_to`]
- [`BinaryHeap::shrink_to`]
- [`VecDeque::shrink_to`]
- [`HashMap::shrink_to`]
- [`HashSet::shrink_to`]

The following previously stable functions are now `const`.

- [`std::mem::transmute`]
- [`[T]::first`][`slice::first`]
- [`[T]::split_first`][`slice::split_first`]
- [`[T]::last`][`slice::last`]
- [`[T]::split_last`][`slice::split_last`]

[`std::os::unix::fs::chroot`]: https://doc.rust-lang.org/stable/std/os/unix/fs/fn.chroot.html
[`UnsafeCell::raw_get`]: https://doc.rust-lang.org/stable/std/cell/struct.UnsafeCell.html#method.raw_get
[`BufWriter::into_parts`]: https://doc.rust-lang.org/stable/std/io/struct.BufWriter.html#method.into_parts
[`core::panic::{UnwindSafe, RefUnwindSafe, AssertUnwindSafe}`]: https://github.com/rust-lang/rust/pull/84662
[`Vec::shrink_to`]: https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.shrink_to
[`String::shrink_to`]: https://doc.rust-lang.org/stable/std/string/struct.String.html#method.shrink_to
[`OsString::shrink_to`]: https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html#method.shrink_to
[`PathBuf::shrink_to`]: https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#method.shrink_to
[`BinaryHeap::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/struct.BinaryHeap.html#method.shrink_to
[`VecDeque::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/struct.VecDeque.html#method.shrink_to
[`HashMap::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/hash_map/struct.HashMap.html#method.shrink_to
[`HashSet::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/hash_set/struct.HashSet.html#method.shrink_to
[`std::mem::transmute`]: https://doc.rust-lang.org/stable/std/mem/fn.transmute.html
[`slice::first`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.first
[`slice::split_first`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_first
[`slice::last`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.last
[`slice::split_last`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_last

### Other changes

There are other changes in the Rust 1.56.0 release: check out what changed in
[Rust](https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1560-2021-10-21),
[Cargo](https://github.com/rust-lang/cargo/blob/master/CHANGELOG.md#cargo-156-2021-10-21),
and [Clippy](https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#rust-156).

### Contributors to 1.56.0
Mark-Simulacrum marked this conversation as resolved.
Show resolved Hide resolved

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