Announcing Rust 1.36.0

July 4, 2019 · The Rust Release Team

The Rust team is happy to announce a new version of Rust, 1.36.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.36.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.36.0 on GitHub.

What's in 1.36.0 stable

This release brings many changes, including the stabilization of the Future trait, the alloc crate, the MaybeUninit<T> type, NLL for Rust 2015, a new HashMap<K, V> implementation, and --offline support in Cargo. Read on for a few highlights, or see the detailed release notes for additional information.

The Future is here!

In Rust 1.36.0 the long awaited Future trait has been stabilized!

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.

The alloc crate is stable

Before 1.36.0, the standard library consisted of the crates std, core, and proc_macro. The core crate provided core functionality such as Iterator and Copy and could be used in #![no_std] environments since it did not impose any requirements. Meanwhile, the std crate provided types like Box<T> and OS functionality but required a global allocator and other OS capabilities in return.

Starting with Rust 1.36.0, the parts of std that depend on a global allocator, e.g. Vec<T>, are now available in the alloc crate. The std crate then re-exports these parts. While #![no_std] binaries using alloc still require nightly Rust, #![no_std] library crates can use the alloc crate in stable Rust. Meanwhile, normal binaries, without #![no_std], can depend on such library crates. We hope this will facilitate the development of a #![no_std] compatible ecosystem of libraries prior to stabilizing support for #![no_std] binaries using alloc.

If you are the maintainer of a library that only relies on some allocation primitives to function, consider making your library #[no_std] compatible by using the following at the top of your lib.rs file:

#![no_std]

extern crate alloc;

use alloc::vec::Vec;

MaybeUninit<T> instead of mem::uninitialized

In previous releases of Rust, the mem::uninitialized function has allowed you to bypass Rust's initialization checks by pretending that you've initialized a value at type T without doing anything. One of the main uses of this function has been to lazily allocate arrays.

However, mem::uninitialized is an incredibly dangerous operation that essentially cannot be used correctly as the Rust compiler assumes that values are properly initialized. For example, calling mem::uninitialized::<bool>() causes instantaneous undefined behavior as, from Rust's point of view, the uninitialized bits are neither 0 (for false) nor 1 (for true) - the only two allowed bit patterns for bool.

To remedy this situation, in Rust 1.36.0, the type MaybeUninit<T> has been stabilized. The Rust compiler will understand that it should not assume that a MaybeUninit<T> is a properly initialized T. Therefore, you can do gradual initialization more safely and eventually use .assume_init() once you are certain that maybe_t: MaybeUninit<T> contains an initialized T.

As MaybeUninit<T> is the safer alternative, starting with Rust 1.39, the function mem::uninitialized will be deprecated.

To find out more about uninitialized memory, mem::uninitialized, and MaybeUninit<T>, read Alexis Beingessner's blog post. The standard library also contains extensive documentation about MaybeUninit<T>.

NLL for Rust 2015

In the announcement for Rust 1.31.0, we told you about NLL (Non-Lexical Lifetimes), an improvement to the language that makes the borrow checker smarter and more user friendly. For example, you may now write:

fn main() {
    let mut x = 5;
    let y = &x;
    let z = &mut x; // This was not allowed before 1.31.0.
}

In 1.31.0 NLL was stabilized only for Rust 2018, with a promise that we would backport it to Rust 2015 as well. With Rust 1.36.0, we are happy to announce that we have done so! NLL is now available for Rust 2015.

With NLL on both editions, we are closer to removing the old borrow checker. However, the old borrow checker unfortunately accepted some unsound code it should not have. As a result, NLL is currently in a "migration mode" wherein we will emit warnings instead of errors if the NLL borrow checker rejects code the old AST borrow checker would accept. Please see this list of public crates that are affected.

To find out more about NLL, MIR, the story around fixing soundness holes, and what you can do about the warnings if you have them, read Felix Klock's blog post.

A new HashMap<K, V> implementation

In Rust 1.36.0, the HashMap<K, V> implementation has been replaced with the one in the hashbrown crate which is based on the SwissTable design. While the interface is the same, the HashMap<K, V> implementation is now faster on average and has lower memory overhead. Note that unlike the hashbrown crate, the implementation in std still defaults to the SipHash 1-3 hashing algorithm.

--offline support in Cargo

During most builds, Cargo doesn't interact with the network. Sometimes, however, Cargo has to. Such is the case when a dependency is added and the latest compatible version needs to be downloaded. At times, network access is not an option though, for example on an airplane or in isolated build environments.

In Rust 1.36, a new Cargo flag has been stabilized: --offline. The flag alters Cargo's dependency resolution algorithm to only use locally cached dependencies. When the required crates are not available offline, and a network access would be required, Cargo will exit with an error. To prepopulate the local cache in preparation for going offline, use the cargo fetch command, which downloads all the required dependencies for a project.

To find out more about --offline and cargo fetch, read Nick Cameron's blog post.

For information on other changes to Cargo, see the detailed release notes.

Library changes

The dbg! macro now supports multiple arguments.

Additionally, a number of APIs have been made const:

New APIs have become stable, including:

Other library changes are available in the detailed release notes.

Other changes

Detailed 1.36.0 release notes are available for Rust, Cargo, and Clippy.

Contributors to 1.36.0

Many people came together to create Rust 1.36.0. We couldn't have done it without all of you. Thanks!