Announcing Rust 1.21
The Rust team is happy to announce the latest version of Rust, 1.21.0. Rust is a systems programming language focused on safety, speed, and concurrency.
If you have a previous version of Rust installed, getting Rust 1.21 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.21.0 on GitHub.
What’s in 1.21.0 stable
This release contains some very minor, but nice-to-have features, as well as some new documentation.
First up, a small change to literals. Consider code like this:
let x = &5;
In Rust, this code is synonymous with:
let _x = 5;
let x = &_x;
That is, the 5
here will be stored on the stack, or possibly in registers.
x
will be a reference to it.
However, given that it’s a literal integer, there’s no reason that it has
to be local like this. Imagine we had a function that took a 'static
argument,
like std::thread::spawn
. You might use x
like this:
use std::thread;
fn main() {
let x = &5;
thread::spawn(move || {
println!("{}", x);
});
}
In previous versions of Rust, this would fail to compile:
error[E0597]: borrowed value does not live long enough
--> src/main.rs:4:14
|
4 | let x = &5;
| ^ does not live long enough
...
10 | }
| - temporary value only lives until here
|
= note: borrowed value must be valid for the static lifetime...
Because the 5
is local, so is its borrow, which doesn’t satisfy the
requirements for spawn
.
However, if you compile this on Rust 1.21, it will work. Why? Well,
if the thing being referred to is okay to put into a static
, we could
instead de-sugar let x = &5;
like this:
static FIVE: i32 = 5;
let x = &FIVE;
Here, since the FIVE
is static
, x
is a &'static i32
. And so this
is what Rust will now do in this kind of case. For full details, see RFC 1414,
which was accepted in January, but started in December of 2015!
We now run LLVM in parallel while generating code, which should reduce peak memory usage.
The RLS can now be installed
through rustup by invoking
rustup component add rls-preview
. In general, many useful Rust developer
tools such as the RLS, Clippy, and rustfmt
need nightly Rust; this is the
first steps toward having them work on stable Rust. Please check out the
preview, and you’ll hear more about these plans in the future.
Finally, a few documentation improvements. First up, if you visit the docs
for std::os
, which contains
operating-system specific functionality, you’ll now see more than just linux
,
the platform we build the documentation on. We’ve long regretted that the hosted
version of the documentation has been Linux-specific; this is a first step towards
rectifying that. This is specific to the standard
library and not for general use;
we hope to improve this further in the future.
Next, Cargo’s docs are moving! Historically, Cargo’s docs were hosted on doc.crates.io, which doesn’t follow the release train model, even though Cargo itself does. This led to situations where a feature would land in Cargo nightly, the docs would be updated, and then for up to twelve weeks, users would think that it should work, but it wouldn’t yet. https://doc.rust-lang.org/cargo will be the new home of Cargo’s docs, though for now, that URL is a redirect to doc.crates.io. Future releases will move Cargo’s docs over, and at that point, doc.crates.io will redirect to doc.rust-lang.org/cargo. Cargo’s docs have long needed a refreshing, so expect to hear more news about Cargo’s docs generally in the future!
Finally, until now, rustdoc
did not have any documentation. This is now
fixed, with a new “rustdoc
Book,” located at
https://doc.rust-lang.org/rustdoc. These
docs are fairly bare-bones at the moment, but we’ll be improving them over
time.
See the detailed release notes for more.
Library stabilizations
Not too many stabilizations this release, but there’s one really great
quality of life change: due to the lack of type-level integers, arrays only
supported various traits up to size 32. This has now been fixed for the
Clone
trait, which also
caused a lot of ICEs at times, when a type would be Copy
but not Clone
.
For other traits, an RFC for type-level integers was accepted
recently,
which may help with this situation. That change has yet to be implemented, however,
though pre-requisite work is ongoing at the moment.
Next, Iterator::for_each
has
been stabilized, letting you consume an iterator for side effects without needing
a for
loop:
// old
for i in 0..10 {
println!("{}", i);
}
// new
(0..10).for_each(|i| println!("{}", i));
The correct one to use depends on your situation; in the sample above, the for
loop
is pretty striaghtforward. But when you’re chaining a number of iterators together,
the for_each
version is sometimes clearer. Consider this:
// old
for i in (0..100).map(|x| x + 1).filter(|x| x % 2 == 0) {
println!("{}", i);
}
// new
(0..100)
.map(|x| x + 1)
.filter(|x| x % 2 == 0)
.for_each(|i| println!("{}", i));
The max
and min
functions on the Ord
trait are now stable.
The needs_drop
intrinsic
is now stable.
Finally, std::mem::discriminant
has been
stabilized, allowing
you to see what variant an enum
instance is without a match
statement.
See the detailed release notes for more.
Cargo features
Beyond the documentation features listed above, Cargo is gaining one major
feature in this release:
[patch]
. Designed in RFC
1969,
the [patch]
section of your Cargo.toml
can be used when you want to
override certain parts of your dependency graph. We also have a feature,
[replace]
that has similar functionality. In many ways, [patch]
is the new
[replace]
, and while we have no plans to deprecate or remove [replace]
,
at this point, you should use [patch]
instead of [replace]
.
So what’s it look like? Let’s say we have a Cargo.toml
that looks like this:
[dependencies]
foo = "1.2.3"
In addition, our foo
crate depends on a bar
crate, and we find a bug in
bar
. To test this out, we’d download the source code for bar
, and then
update our Cargo.toml
:
[dependencies]
foo = "1.2.3"
[patch.crates-io]
bar = { path = '/path/to/bar' }
Now, when you cargo build
, it will use the local version of bar
, rather
than the one from crates.io
that foo
depends on.
For more details, see the documentation.
Additionally:
- you can now
cargo install
multiple crates at once - If you’re in a virtual workspace,
--all
is now applied automatically. include
andexclude
fields in yourCargo.toml
accepts patterns similar to a.gitignore
.
See the detailed release notes for more.
Contributors to 1.21.0
Many people came together to create Rust 1.21. We couldn’t have done it without all of you. Thanks!