|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "Announcing Rust 1.56.0 and Rust 2021" |
| 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.56.0. This stabilizes the 2021 edition as well. |
| 9 | +Rust is a programming language empowering everyone to build reliable and efficient software. |
| 10 | + |
| 11 | +If you have a previous version of Rust installed via rustup, getting Rust 1.56.0 is as easy as: |
| 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.56.0][notes] on GitHub. |
| 20 | + |
| 21 | +[install]: https://www.rust-lang.org/install.html |
| 22 | +[notes]: https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1560-2021-10-21 |
| 23 | + |
| 24 | +## What's in 1.56.0 stable |
| 25 | + |
| 26 | +### Rust 2021 |
| 27 | + |
| 28 | +We wrote about plans for the Rust 2021 Edition [in May](https://blog.rust-lang.org/2021/05/11/edition-2021.html). |
| 29 | +Editions are a mechanism for opt-in changes that may otherwise pose backwards compatibility risk. See [the edition guide](https://doc.rust-lang.org/stable/edition-guide/editions/index.html) for details on how this is achieved. |
| 30 | +This a smaller edition, especially compared to 2018, but there |
| 31 | +are still some nice quality-of-life changes that require an edition opt-in to |
| 32 | +avoid breaking some corner cases in existing code. See the new chapters of the |
| 33 | +edition guide below for more details on each new feature and guidance for |
| 34 | +migration. |
| 35 | + |
| 36 | +* [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. |
| 37 | +* [`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. |
| 38 | +* [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`. |
| 39 | +* [Default Cargo feature resolver](https://doc.rust-lang.org/edition-guide/rust-2021/default-cargo-resolver.html) is now version 2. |
| 40 | +* [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. |
| 41 | +* [Panic macros](https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html) now always expect format strings, just like `println!()`. |
| 42 | +* [Reserving syntax](https://doc.rust-lang.org/edition-guide/rust-2021/reserving-syntax.html) for `ident#`, `ident"..."`, and `ident'...'`. |
| 43 | +* [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`. |
| 44 | + |
| 45 | +#### Disjoint capture in closures |
| 46 | + |
| 47 | +Closures automatically capture values or references to identifiers that are |
| 48 | +used in the body, but before 2021, they were always captured as a whole. The new |
| 49 | +disjoint-capture feature will likely simplify the way you write closures, so |
| 50 | +let's look at a quick example: |
| 51 | + |
| 52 | +```rust |
| 53 | +// 2015 or 2018 edition code |
| 54 | +let a = SomeStruct::new(); |
| 55 | + |
| 56 | +// Move out of one field of the struct |
| 57 | +drop(a.x); |
| 58 | + |
| 59 | +// Ok: Still use another field of the struct |
| 60 | +println!("{}", a.y); |
| 61 | + |
| 62 | +// Error: Before 2021 edition, tries to capture all of `a` |
| 63 | +let c = || println!("{}", a.y); |
| 64 | +c(); |
| 65 | +``` |
| 66 | + |
| 67 | +To fix this, you would have had to extract something like `let y = &a.y;` |
| 68 | +manually before the closure to limit its capture. Starting in Rust 2021, |
| 69 | +closures will automatically capture only the fields that they use, so the |
| 70 | +above example will compile fine! |
| 71 | + |
| 72 | +This new behavior is only activated in the new edition, since it can change |
| 73 | +the order in which fields are dropped. As for all edition changes, an |
| 74 | +automatic migration is available, which will update your closures for which |
| 75 | +this matters by inserting `let _ = &a;` inside the closure to force the |
| 76 | +entire struct to be captured as before. |
| 77 | + |
| 78 | +#### Migrating to 2021 |
| 79 | + |
| 80 | +The guide includes migration instructions for all new features, and in general |
| 81 | +[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). |
| 82 | +In many cases `cargo fix` can automate the necessary changes. You may even |
| 83 | +find that no changes in your code are needed at all for 2021! |
| 84 | + |
| 85 | +However small this edition appears on the surface, it's still the product |
| 86 | +of a lot of hard work from many contributors: see our dedicated |
| 87 | +[celebration and thanks](https://github.com/rust-lang/rust/issues/88623) tracker! |
| 88 | + |
| 89 | +### Cargo `rust-version` |
| 90 | + |
| 91 | +`Cargo.toml` now supports a `[package]` [`rust-version`] field to specify |
| 92 | +the minimum supported Rust version for a crate, and Cargo will exit with an |
| 93 | +early error if that is not satisfied. This doesn't currently influence the |
| 94 | +dependency resolver, but the idea is to catch compatibility problems before |
| 95 | +they turn into cryptic compiler errors. |
| 96 | + |
| 97 | +[`rust-version`]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-rust-version-field |
| 98 | + |
| 99 | +### New bindings in `binding @ pattern` |
| 100 | + |
| 101 | +Rust pattern matching can be written with a single identifier that binds |
| 102 | +the entire value, followed by `@` and a more refined structural pattern, |
| 103 | +but this has not allowed additional bindings in that pattern -- until now! |
| 104 | + |
| 105 | +```rust |
| 106 | +struct Matrix { |
| 107 | + data: Vec<f64>, |
| 108 | + row_len: usize, |
| 109 | +} |
| 110 | + |
| 111 | +// Before, we need separate statements to bind |
| 112 | +// the whole struct and also read its parts. |
| 113 | +let matrix = get_matrix(); |
| 114 | +let row_len = matrix.row_len; |
| 115 | +// or with a destructuring pattern: |
| 116 | +let Matrix { row_len, .. } = matrix; |
| 117 | + |
| 118 | +// Rust 1.56 now lets you bind both at once! |
| 119 | +let matrix @ Matrix { row_len, .. } = get_matrix(); |
| 120 | +``` |
| 121 | + |
| 122 | +This actually was allowed in the days before Rust 1.0, but that was removed |
| 123 | +due to known [unsoundness](https://github.com/rust-lang/rust/pull/16053) at |
| 124 | +the time. With the evolution of the borrow checker since that time, and with |
| 125 | +heavy testing, the compiler team determined that this was safe to finally |
| 126 | +allow in stable Rust! |
| 127 | + |
| 128 | +### Stabilized APIs |
| 129 | + |
| 130 | +The following methods and trait implementations were stabilized. |
| 131 | + |
| 132 | +- [`std::os::unix::fs::chroot`] |
| 133 | +- [`UnsafeCell::raw_get`] |
| 134 | +- [`BufWriter::into_parts`] |
| 135 | +- [`core::panic::{UnwindSafe, RefUnwindSafe, AssertUnwindSafe}`]\ |
| 136 | + \(previously only in `std`) |
| 137 | +- [`Vec::shrink_to`] |
| 138 | +- [`String::shrink_to`] |
| 139 | +- [`OsString::shrink_to`] |
| 140 | +- [`PathBuf::shrink_to`] |
| 141 | +- [`BinaryHeap::shrink_to`] |
| 142 | +- [`VecDeque::shrink_to`] |
| 143 | +- [`HashMap::shrink_to`] |
| 144 | +- [`HashSet::shrink_to`] |
| 145 | + |
| 146 | +The following previously stable functions are now `const`. |
| 147 | + |
| 148 | +- [`std::mem::transmute`] |
| 149 | +- [`[T]::first`][`slice::first`] |
| 150 | +- [`[T]::split_first`][`slice::split_first`] |
| 151 | +- [`[T]::last`][`slice::last`] |
| 152 | +- [`[T]::split_last`][`slice::split_last`] |
| 153 | + |
| 154 | +[`std::os::unix::fs::chroot`]: https://doc.rust-lang.org/stable/std/os/unix/fs/fn.chroot.html |
| 155 | +[`UnsafeCell::raw_get`]: https://doc.rust-lang.org/stable/std/cell/struct.UnsafeCell.html#method.raw_get |
| 156 | +[`BufWriter::into_parts`]: https://doc.rust-lang.org/stable/std/io/struct.BufWriter.html#method.into_parts |
| 157 | +[`core::panic::{UnwindSafe, RefUnwindSafe, AssertUnwindSafe}`]: https://github.com/rust-lang/rust/pull/84662 |
| 158 | +[`Vec::shrink_to`]: https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.shrink_to |
| 159 | +[`String::shrink_to`]: https://doc.rust-lang.org/stable/std/string/struct.String.html#method.shrink_to |
| 160 | +[`OsString::shrink_to`]: https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html#method.shrink_to |
| 161 | +[`PathBuf::shrink_to`]: https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#method.shrink_to |
| 162 | +[`BinaryHeap::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/struct.BinaryHeap.html#method.shrink_to |
| 163 | +[`VecDeque::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/struct.VecDeque.html#method.shrink_to |
| 164 | +[`HashMap::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/hash_map/struct.HashMap.html#method.shrink_to |
| 165 | +[`HashSet::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/hash_set/struct.HashSet.html#method.shrink_to |
| 166 | +[`std::mem::transmute`]: https://doc.rust-lang.org/stable/std/mem/fn.transmute.html |
| 167 | +[`slice::first`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.first |
| 168 | +[`slice::split_first`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_first |
| 169 | +[`slice::last`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.last |
| 170 | +[`slice::split_last`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_last |
| 171 | + |
| 172 | +### Other changes |
| 173 | + |
| 174 | +There are other changes in the Rust 1.56.0 release: check out what changed in |
| 175 | +[Rust](https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1560-2021-10-21), |
| 176 | +[Cargo](https://github.com/rust-lang/cargo/blob/master/CHANGELOG.md#cargo-156-2021-10-21), |
| 177 | +and [Clippy](https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#rust-156). |
| 178 | + |
| 179 | +### Contributors to 1.56.0 |
| 180 | + |
| 181 | +Many people came together to create Rust 1.56.0 and the 2021 edition. |
| 182 | +We couldn't have done it without all of you. |
| 183 | +[Thanks!](https://thanks.rust-lang.org/rust/1.56.0/) |
0 commit comments