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.
If you have a previous version of Rust installed via rustup, getting Rust 1.39.0 is as easy as:
$ rustup update stable
If you don't have it already, you can get rustup
from the appropriate page on our website, and check out the detailed release notes for 1.39.0 on GitHub.
What's in 1.39.0 stable
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 for additional information.
.await
is over, async fn
s are here
The Previously in Rust 1.36.0, we announced that the Future
trait is here. Back then, we noted that:
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.
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.
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".
For more on the release of async
/ .await
, read Niko Matsakis's blog post.
match
guards
References to by-move bindings in When pattern matching in Rust, a variable, also known as a "binding", can be bound in the following ways:
-
by-reference, either immutably or mutably. This can be achieved explicitly e.g. through
ref my_var
orref mut my_var
respectively. Most of the time though, the binding mode will be inferred automatically. -
by-value -- either by-copy, when the bound variable's type implements
Copy
, or otherwise by-move.
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:
fn main() {
let array: Box<[u8; 4]> = Box::new([1, 2, 3, 4]);
match array {
nums
// ---- `nums` is bound by move.
if nums.iter().sum::<u8>() == 10
// ^------ `.iter()` implicitly takes a reference to `nums`.
=> {
drop(nums);
// ----------- `nums` was bound by move and so we have ownership.
}
_ => unreachable!(),
}
}
With Rust 1.39.0, 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.
Attributes on function parameters
With Rust 1.39.0, attributes are now allowed on parameters of functions, closures, and function pointers. Whereas before, you might have written:
#[cfg(windows)]
fn len(slice: &[u16]) -> usize {
slice.len()
}
#[cfg(not(windows))]
fn len(slice: &[u8]) -> usize {
slice.len()
}
...you can now, more succinctly, write:
fn len(
#[cfg(windows)] slice: &[u16], // This parameter is used on Windows.
#[cfg(not(windows))] slice: &[u8], // Elsewhere, this one is used.
) -> usize {
slice.len()
}
The attributes you can use in this position include:
-
Conditional compilation:
cfg
andcfg_attr
-
Controlling lints:
allow
,warn
,deny
, andforbid
-
Helper attributes used by procedural macro attributes applied to items.
Our hope is that this will be used to provide more readable and ergonomic macro-based DSLs throughout the ecosystem.
Borrow check migration warnings are hard errors in Rust 2018
In the 1.36.0 release, we announced that NLL had come to Rust 2015 after first being released for Rust 2018 in 1.31.
As noted in the 1.36.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.
With Rust 1.39.0, these warnings are now errors in Rust 2018. In the next release, Rust 1.40.0, this will also apply to Rust 2015, which will finally allow us to remove the old borrow checker, and keep the compiler clean.
If you are affected, or want to hear more, read Niko Matsakis's blog post.
const fn
s in the standard library
More With Rust 1.39.0, the following functions became const fn
:
Vec::new
,String::new
, andLinkedList::new
str::len
,[T]::len
, andstr::as_bytes
abs
,wrapping_abs
, andoverflowing_abs
Additions to the standard library
In Rust 1.39.0 the following functions were stabilized:
Other changes
There are other changes in the Rust 1.39.0 release: check out what changed in Rust, Cargo, and Clippy.
Please also see the compatibility notes to check if you're affected by those changes.
Contributors to 1.39.0
Many people came together to create Rust 1.39.0. We couldn't have done it without all of you. Thanks!