The Rust team is happy to announce a new version of Rust, 1.34.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.34.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.
What's in 1.34.0 stable
The largest feature in this release is the introduction of alternative cargo
registries.
The release also includes support for ?
in documentation tests,
some improvements for #[attribute(..)]
s, as well as the stabilization of TryFrom
.
Read on for a few highlights, or see the detailed release notes for additional information.
cargo
registries
Alternative Since before 1.0, Rust has had a public crate registry, crates.io.
People publish crates with cargo publish
and it's easy to include these crates
in the [dependencies]
section of your Cargo.toml
.
However, not everyone wants to publish their crates to crates.io.
People maintaining proprietary/closed-source code cannot use crates.io,
and instead are forced to use git
or path
dependencies.
This is usually fine for small projects, but if you have a lot of closed-source crates
within a large organization, you lose the benefit of the versioning support that crates.io has.
With this release, Cargo gains support for alternate registries. These registries coexist with crates.io, so you can write software that depends on crates from both crates.io and your custom registry. Crates on crates.io cannot however depend on external registries.
To use an alternate registry, you must add these lines to your .cargo/config
.
This file can be in your home directory (~/.cargo/config
) or relative to the package directory.
[registries]
my-registry = { index = "https://my-intranet:8080/git/index" }
Depending on a crate from an alternate registry is easy.
When specifying dependencies in your Cargo.toml
, use the registry
key to
let Cargo know that you wish to fetch the crate from the alternate registry:
[dependencies]
other-crate = { version = "1.0", registry = "my-registry" }
As a crate author, if you wish to publish your crate to an alternate registry,
you first need to save the authentication token into ~/.cargo/credentials
with the cargo login
command:
cargo login --registry=my-registry
You can then use the --registry
flag to indicate which registry to use when publishing:
cargo publish --registry=my-registry
There is documentation on how to run your own registry.
?
in documentation tests
RFC 1937 proposed adding support for using the ?
operator in fn main()
,
#[test]
functions, and doctests, allowing them to return Option<T>
or Result<T, E>
,
with error values causing a nonzero exit code in the case of fn main()
,
and a test failure in the case of the tests.
Support in fn main()
and #[test]
was implemented many releases ago.
However, the support within documentation tests was limited to doctests that have an explicit fn main()
.
In this release, full support for ?
in doctests has been added.
Now, you can write this in your documentation tests:
/// ```rust
/// use std::io;
/// let mut input = String::new();
/// io::stdin().read_line(&mut input)?;
/// # Ok::<(), io::Error>(())
/// ```
fn my_func() {}
You still have to specify the error type being used at the bottom of the documentation test.
Custom attributes accept arbitrary token streams
Procedural macros in Rust can define custom attributes that they consume. Until now, such attributes were restricted to being trees of paths and literals according to a specific syntax, like:
#[foo(bar)]
#[foo = "bar"]
#[foo = 0]
#[foo(bar = true)]
#[foo(bar, baz(quux, foo = "bar"))]
Unlike procedural macros, these helper attributes could not accept arbitrary token streams in delimiters,
so you could not write #[range(0..10)]
or #[bound(T: MyTrait)]
.
Procedural macro crates would instead use strings for specifying syntaxes like this, e.g. #[range("0..10")]
With this Rust release, custom attributes #[attr($tokens)]
now accept
arbitrary token streams in $tokens
, bringing them on par with macros.
If you're the author of a procedural macro crate, please check if your custom attributes
have unnecessary strings in their syntax and if they can be better expressed with token streams.
TryFrom
and TryInto
The TryFrom
and TryInto
traits were stabilized to allow fallible type conversions.
For example, the from_be_bytes
and related methods on integer types take arrays,
but data is often read in via slices. Converting between slices and arrays is tedious to do manually.
With the new traits, it can be done inline with .try_into()
.
let num = u32::from_be_bytes(slice.try_into()?);
For conversions that cannot fail, such as u8
to u32
, the Infallible
type was added.
This also permits a blanket implementation of TryFrom
for all existing From
implementations.
In the future, we hope to turn Infallible
into an alias for the !
(never) type.
fn before_exec
deprecated in favor of unsafe fn pre_exec
On Unix-like systems, the function CommandExt::before_exec
allows you to
schedule a closure to be run before exec
is invoked.
The closure provided will be run in the context of the child process after a fork.
This means that resources, such as file descriptors and memory-mapped regions, may get duplicated.
In other words, you can now copy a value of a non-Copy
type into a different process
while retaining the original in the parent. This makes it possible to cause
undefined behavior and break libraries assuming non-duplication.
The function before_exec
should therefore have been marked as unsafe
.
In this release of Rust, we have deprecated fn before_exec
in favor of the unsafe fn pre_exec
.
When calling CommandExt::pre_exec
, it is your responsibility to make sure that the closure
does not violate library invariants by making invalid use of these duplicates.
If you provide a library that is in a similar situation as before_exec
,
consider deprecating and providing an unsafe
alternative as well.
Library stabilizations
In 1.34.0, the set of stable atomic integer types was expanded,
with signed and unsigned variants from 8 (AtomicU8
) to 64 bits now available.
Previously, non-zero unsigned integer types, e.g. NonZeroU8
, were stabilized.
This gave Option<NonZeroU8>
the same size as u8
.
With this Rust release, signed versions, e.g. NonZeroI8
, have been stabilized.
The functions iter::from_fn
and iter::successors
have been stabilized.
The former allows you to construct an iterator from FnMut() -> Option<T>
.
To pop elements from a vector iteratively, you can now write from_fn(|| vec.pop())
.
Meanwhile, the latter creates a new iterator where each successive item
is computed based on the preceding one.
Additionally, these APIs have become stable:
- Any::type_id
- Error::type_id
- slice::sort_by_cached_key
- str::escape_debug
- str::escape_default
- str::escape_unicode
- str::split_ascii_whitespace
- Instant::checked_add
- Instant::checked_sub
- SystemTime::checked_add
- SystemTime::checked_sub
See the detailed release notes for more details.