|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "Announcing Rust 1.39.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.39.0. Rust is a programming language that is empowering everyone to build reliable and efficient software. |
| 9 | + |
| 10 | +If you have a previous version of Rust installed via rustup, getting Rust 1.39.0 is as easy as: |
| 11 | + |
| 12 | +```console |
| 13 | +$ rustup update stable |
| 14 | +``` |
| 15 | + |
| 16 | +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.39.0][notes] on GitHub. |
| 17 | + |
| 18 | +[install]: https://www.rust-lang.org/install.html |
| 19 | +[notes]: https://github.com/rust-lang/rust/blob/stable/RELEASES.md#version-1390-2019-11-07 |
| 20 | + |
| 21 | +## What's in 1.39.0 stable |
| 22 | + |
| 23 | +The highlights of Rust 1.39.0 include `async`/`.await`, shared references to by-move bindings in `match` guards, and attributes on function parameters. Also, see the [detailed release notes][notes] for additional information. |
| 24 | + |
| 25 | +### The `.await` is over, `async fn`s are here |
| 26 | + |
| 27 | +[rel-1360]: https://blog.rust-lang.org/2019/07/04/Rust-1.36.0.html#the-future-is-here |
| 28 | +[`Future`]: https://doc.rust-lang.org/nightly/std/future/trait.Future.html |
| 29 | +[niko-post-async]: https://blog.rust-lang.org/2019/11/07/Async-await-stable.html |
| 30 | + |
| 31 | +Previously in Rust 1.36.0, [we announced][rel-1360] that the [`Future`] trait is here. Back then, we noted that: |
| 32 | + |
| 33 | +> With this stabilization, we hope to give important crates, libraries, and the ecosystem time to prepare for `async` / `.await`, which we'll tell you more about in the future. |
| 34 | +
|
| 35 | +A promise made is a promise kept. So in Rust 1.39.0, we are pleased to announce that `async` / `.await` is stabilized! Concretely, this means that you can define `async` functions and blocks and `.await` them. |
| 36 | + |
| 37 | +An `async` function, which you can introduce by writing `async fn` instead of `fn`, does nothing other than to return a `Future` when called. This `Future` is a suspended computation which you can drive to completion by `.await`ing it. Besides `async fn`, `async { ... }` and `async move { ... }` blocks, which act like closures, can be used to define "async literals". |
| 38 | + |
| 39 | +For more on the release of `async` / `.await`, read [Niko Matsakis's blog post][niko-post-async]. |
| 40 | + |
| 41 | +### References to by-move bindings in `match` guards |
| 42 | + |
| 43 | +[pr-bind-by-move]: https://github.com/rust-lang/rust/pull/63118/#issuecomment-522823925 |
| 44 | + |
| 45 | +When pattern matching in Rust, a variable, also known as a "binding", can be bound in the following ways: |
| 46 | + |
| 47 | +- by-reference, either immutably or mutably. This can be achieved explicitly e.g. through `ref my_var` or `ref mut my_var` respectively. Most of the time though, the binding mode will be inferred automatically. |
| 48 | + |
| 49 | +- by-value -- either by-copy, when the bound variable's type implements `Copy`, or otherwise **_by-move_**. |
| 50 | + |
| 51 | +Previously, Rust would forbid taking shared references to **_by-move_** bindings in the `if` guards of `match` expressions. This meant that the following code would be rejected: |
| 52 | + |
| 53 | +```rust |
| 54 | +fn main() { |
| 55 | + let array: Box<[u8; 4]> = Box::new([1, 2, 3, 4]); |
| 56 | + |
| 57 | + match array { |
| 58 | + nums |
| 59 | +// ---- `nums` is bound by move. |
| 60 | + if nums.iter().sum::<u8>() == 10 |
| 61 | +// ^------ `.iter()` implicitly takes a reference to `nums`. |
| 62 | + => { |
| 63 | + drop(nums); |
| 64 | +// ----------- `nums` was bound by move and so we have ownership. |
| 65 | + } |
| 66 | + _ => unreachable!(), |
| 67 | + } |
| 68 | +} |
| 69 | +``` |
| 70 | + |
| 71 | +[With Rust 1.39.0][pr-bind-by-move], the snippet above is now accepted by the compiler. We hope that this will give a smoother and more consistent experience with `match` expressions overall. |
| 72 | + |
| 73 | +### Attributes on function parameters |
| 74 | + |
| 75 | +[pr-attr]: https://github.com/rust-lang/rust/pull/64010/ |
| 76 | + |
| 77 | +With Rust 1.39.0, attributes are now allowed on parameters of functions, closures, and function pointers. Whereas before, you might have written: |
| 78 | + |
| 79 | +```rust |
| 80 | +#[cfg(windows)] |
| 81 | +fn len(slice: &[u16]) -> usize { |
| 82 | + slice.len() |
| 83 | +} |
| 84 | +#[cfg(not(windows))] |
| 85 | +fn len(slice: &[u8]) -> usize { |
| 86 | + slice.len() |
| 87 | +} |
| 88 | +``` |
| 89 | + |
| 90 | +...[you can now][pr-attr], more succinctly, write: |
| 91 | + |
| 92 | +```rust |
| 93 | +fn len( |
| 94 | + #[cfg(windows)] slice: &[u16], // This parameter is used on Windows. |
| 95 | + #[cfg(not(windows))] slice: &[u8], // Elsewhere, this one is used. |
| 96 | +) -> usize { |
| 97 | + slice.len() |
| 98 | +} |
| 99 | +``` |
| 100 | + |
| 101 | +The attributes you can use in this position include: |
| 102 | + |
| 103 | +1. Conditional compilation: `cfg` and `cfg_attr` |
| 104 | + |
| 105 | +2. Controlling lints: `allow`, `warn`, `deny`, and `forbid` |
| 106 | + |
| 107 | +3. Helper attributes used by procedural macro attributes applied to items. |
| 108 | + |
| 109 | + Our hope is that this will be used to provide more readable and ergonomic macro-based DSLs throughout the ecosystem. |
| 110 | + |
| 111 | +### Borrow check migration warnings are hard errors in Rust 2018 |
| 112 | + |
| 113 | +[rel-1350]: https://blog.rust-lang.org/2019/07/04/Rust-1.36.0.html#nll-for-rust-2015 |
| 114 | +[rel-1310]: https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.html#non-lexical-lifetimes |
| 115 | +[err-2018]: https://github.com/rust-lang/rust/pull/63565 |
| 116 | +[err-2015]: https://github.com/rust-lang/rust/pull/64221 |
| 117 | +[rip-ast-borrowck]: https://github.com/rust-lang/rust/pull/64790 |
| 118 | +[niko-blog-nll]: https://blog.rust-lang.org/2019/11/01/nll-hard-errors.html |
| 119 | + |
| 120 | +In the 1.35.0 release, [we announced][rel-1350] that NLL had come to Rust 2015 after first being released for Rust 2018 in [1.31][rel-1310]. |
| 121 | + |
| 122 | +As noted in the 1.35.0 release, the old borrow checker had some bugs which would allow memory unsafety. These bugs were fixed by the NLL borrow checker. As these fixes broke some stable code, we decided to gradually phase in the errors by checking if the old borrow checker would accept the program and the NLL checker would reject it. If so, the errors would instead become warnings. |
| 123 | + |
| 124 | +With Rust 1.39.0, these warnings are now [errors in Rust 2018][err-2018]. |
| 125 | +In the next release, Rust 1.40.0, [this will also apply to Rust 2015][err-2015], which will finally allow us to [remove the old borrow checker][rip-ast-borrowck], and keep the compiler clean. |
| 126 | + |
| 127 | +If you are affected, or want to hear more, read [Niko Matsakis's blog post][niko-blog-nll]. |
| 128 | + |
| 129 | +### More `const fn`s in the standard library |
| 130 | + |
| 131 | +[`Vec::new`]: https://doc.rust-lang.org/std/vec/struct.Vec.html#method.new |
| 132 | +[`String::new`]: https://doc.rust-lang.org/std/string/struct.String.html#method.new |
| 133 | +[`LinkedList::new`]: https://doc.rust-lang.org/std/collections/linked_list/struct.LinkedList.html#method.new |
| 134 | +[`str::len`]: https://doc.rust-lang.org/std/primitive.str.html#method.len |
| 135 | +[`slice::len`]: https://doc.rust-lang.org/std/primitive.slice.html#method.len |
| 136 | +[`str::as_bytes`]: https://doc.rust-lang.org/std/primitive.str.html#method.as_bytes |
| 137 | +[`abs`]: https://doc.rust-lang.org/std/primitive.i8.html#method.abs |
| 138 | +[`wrapping_abs`]: https://doc.rust-lang.org/std/primitive.i8.html#method.wrapping_abs |
| 139 | +[`overflowing_abs`]: https://doc.rust-lang.org/std/primitive.i8.html#method.overflowing_abs |
| 140 | + |
| 141 | +With Rust 1.39.0, the following functions became `const fn`: |
| 142 | + |
| 143 | +- [`Vec::new`], [`String::new`], and [`LinkedList::new`] |
| 144 | +- [`str::len`], [`[T]::len`][`slice::len`], and [`str::as_bytes`] |
| 145 | +- [`abs`], [`wrapping_abs`], and [`overflowing_abs`] |
| 146 | + |
| 147 | +### Additions to the standard library |
| 148 | + |
| 149 | +[`Pin::into_inner`]: https://doc.rust-lang.org/std/pin/struct.Pin.html#method.into_inner |
| 150 | +[`Instant::checked_duration_since`]: https://doc.rust-lang.org/std/time/struct.Instant.html#method.checked_duration_since |
| 151 | +[`Instant::saturating_duration_since`]: https://doc.rust-lang.org/std/time/struct.Instant.html#method.saturating_duration_since |
| 152 | + |
| 153 | +In Rust 1.39.0 the following functions were stabilized: |
| 154 | + |
| 155 | +- [`Pin::into_inner`] |
| 156 | +- [`Instant::checked_duration_since`] and [`Instant::saturating_duration_since`] |
| 157 | + |
| 158 | +### Other changes |
| 159 | + |
| 160 | +[relnotes-cargo]: https://github.com/rust-lang/cargo/blob/master/CHANGELOG.md#cargo-139-2019-11-07 |
| 161 | +[relnotes-clippy]: https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#rust-139 |
| 162 | +[compat-notes]: https://github.com/rust-lang/rust/blob/stable/RELEASES.md#compatibility-notes |
| 163 | + |
| 164 | +There are other changes in the Rust 1.39.0 release: check out what changed in [Rust][notes], [Cargo][relnotes-cargo], and [Clippy][relnotes-clippy]. |
| 165 | + |
| 166 | +Please also see the [compatibility notes][compat-notes] to check if you're affected by those changes. |
| 167 | + |
| 168 | +## Contributors to 1.39.0 |
| 169 | + |
| 170 | +Many people came together to create Rust 1.39.0. We couldn't have done it |
| 171 | +without all of you. [Thanks!](https://thanks.rust-lang.org/rust/1.39.0/) |
0 commit comments